trackpro
v1.0.1
Published
Lightweight monitoring agent for the Centralized Server Monitoring Platform. Collects system metrics, application health, and sends heartbeats to the Monitoring API.
Maintainers
Readme
trackpro
Lightweight monitoring agent for the Centralized Server Monitoring Platform. Collects system metrics, application health, and heartbeats — then ships them to your Monitoring API every 30 seconds.
Features
| Category | What's collected | |---|---| | CPU | Usage %, load average (1m/5m/15m), core count, model, speed | | Memory | Total / used / free bytes, usage %, swap | | Disk | Per-filesystem: total / used / free, usage % | | Network | Per-interface: RX/TX bytes, RX/TX speed (bytes/s) | | Node.js process | Version, heap / RSS, event-loop delay, PID, uptime | | Health checks | HTTP endpoints, PostgreSQL (TCP), Redis (TCP) | | Heartbeat | Sent every 30 s regardless of metrics interval |
Installation
npm install trackpro
# or
yarn add trackproRequires Node.js ≥ 16.
Quick Start
import { MonitorAgent } from 'trackpro';
const agent = new MonitorAgent({
apiKey: 'proj_xxxxxxxxxxxxxxxx', // x-api-key from your project settings
apiUrl: 'https://monitor.example.com',
serverName: 'api-server-1', // optional – defaults to os.hostname()
environment: 'production', // optional – defaults to NODE_ENV
});
await agent.start(); // starts collecting & sending every 30 sConfiguration
interface AgentConfig {
/** Required: project API key (sent as x-api-key header) */
apiKey: string;
/** Required: base URL of the Monitoring API */
apiUrl: string;
/** Collection + send interval in ms (default: 30_000) */
interval?: number;
/** Display name on the dashboard (default: os.hostname()) */
serverName?: string;
/** Environment tag e.g. "production" | "staging" (default: NODE_ENV) */
environment?: string;
/** Health-check endpoints to probe on each cycle */
healthChecks?: HealthCheckConfig[];
/** Set false to silence all log output (default: true) */
verbose?: boolean;
}Health Checks
Add health checks to probe all of your dependencies on every metrics cycle:
const agent = new MonitorAgent({
apiKey: 'proj_xxx',
apiUrl: 'https://monitor.example.com',
healthChecks: [
// ── HTTP / HTTPS APIs ──────────────────────────────────────────────────
{ name: 'REST API', type: 'http', url: 'http://api.internal/health' },
{ name: 'Payments API', type: 'https', url: 'https://pay.example.com/health' },
{ name: 'Auth Service', type: 'https', url: 'https://auth.internal/ping',
method: 'HEAD', authToken: 'secret-token', expectedStatus: 200 },
// ── Relational databases ───────────────────────────────────────────────
{ name: 'Primary Postgres', type: 'postgresql', url: 'postgresql://db.internal:5432' },
{ name: 'MySQL DB', type: 'mysql', url: 'mysql://mysql.internal:3306' },
// ── NoSQL / document stores ────────────────────────────────────────────
{ name: 'MongoDB', type: 'mongodb', url: 'mongodb://mongo.internal:27017' },
{ name: 'Elasticsearch', type: 'elasticsearch',url: 'http://es.internal:9200' },
// ── In-memory / caching ────────────────────────────────────────────────
{ name: 'Redis Cache', type: 'redis', url: 'redis://cache.internal:6379' },
// ── Message brokers ────────────────────────────────────────────────────
{ name: 'RabbitMQ', type: 'rabbitmq', url: 'amqp://mq.internal:5672' },
{ name: 'Kafka', type: 'kafka', url: 'kafka.internal:9092' },
// ── RPC / generic TCP ──────────────────────────────────────────────────
{ name: 'gRPC Service', type: 'grpc', url: 'grpc.internal:50051' },
{ name: 'Custom TCP', type: 'tcp', url: 'service.internal:8080' },
// ── Mail ───────────────────────────────────────────────────────────────
{ name: 'SMTP Relay', type: 'smtp', url: 'smtp.example.com:25' },
// ── DNS ────────────────────────────────────────────────────────────────
{ name: 'API DNS', type: 'dns', url: 'api.example.com' },
{ name: 'API DNS (custom)', type: 'dns', url: 'api.example.com', dnsServer: '8.8.8.8' },
],
});Supported types
| type | Default port | How it probes |
|---|---|---|
| "http" | 80 | HTTP GET (or HEAD/POST) — healthy if status < 500 (or matches expectedStatus) |
| "https" | 443 | Same as http over TLS |
| "postgresql" | 5432 | TCP socket connect |
| "mysql" | 3306 | TCP socket connect |
| "mongodb" | 27017 | TCP socket connect |
| "elasticsearch" | 9200 | GET /_cluster/health — healthy if cluster status is green or yellow |
| "redis" | 6379 | Sends PING, expects +PONG reply |
| "rabbitmq" | 5672 | TCP socket connect |
| "kafka" | 9092 | TCP socket connect |
| "grpc" | 50051 | TCP socket connect |
| "tcp" | — | Generic TCP socket connect (port required in URL) |
| "smtp" | 25 | TCP connect + waits for 220 greeting banner |
| "dns" | — | Resolves A records via system resolver (or custom dnsServer) |
HTTP-specific options
| Option | Type | Description |
|---|---|---|
| method | "GET" \| "HEAD" \| "POST" | HTTP verb (default: "GET") |
| expectedStatus | number | Exact status code required (default: any < 500) |
| authToken | string | Sent as Authorization: Bearer <token> |
DNS-specific options
| Option | Type | Description |
|---|---|---|
| dnsServer | string | Custom DNS server IP to query (default: system resolver) |
Tracking Active Connections
If you want the agent to report your HTTP server's active connection count:
import http from 'http';
import { MonitorAgent } from '@company/monitor-agent';
const server = http.createServer(app);
const agent = new MonitorAgent({ apiKey: 'proj_xxx', apiUrl: '...' });
// Update every 5 s (or on connection events)
setInterval(() => {
agent.setActiveConnections(server.connections);
}, 5_000);
server.listen(3000);
await agent.start();One-Shot / CLI Usage
Collect metrics without starting the polling loop:
const agent = new MonitorAgent({ apiKey: 'proj_xxx', apiUrl: '...' });
const metrics = await agent.collectMetrics();
console.log(JSON.stringify(metrics, null, 2));Stopping the Agent
agent.stop();SIGINT and SIGTERM are handled automatically — the agent stops cleanly on process exit.
TypeScript Types
All types are exported from the package root:
import type {
AgentConfig,
MetricsPayload,
CpuMetrics,
MemoryMetrics,
DiskMetrics,
NetworkMetrics,
AppMetrics,
HealthCheckConfig,
HealthCheckResult,
HeartbeatPayload,
} from '@company/monitor-agent';API Endpoints Used
| Method | Endpoint | Description |
|---|---|---|
| POST | /metrics | Full metrics payload every interval ms |
| POST | /agent/heartbeat | Lightweight ping every 30 s |
Both requests include the x-api-key header from your config.
Payload Shape
{
"serverName": "api-server-1",
"environment": "production",
"timestamp": "2026-06-07T10:00:00.000Z",
"serverUptime": 864000,
"cpu": {
"usage": 23.5,
"loadAverage": [1.2, 0.9, 0.8],
"cores": 8,
"model": "Intel Core i7-12700",
"speed": 3600
},
"memory": {
"total": 17179869184,
"used": 8589934592,
"free": 8589934592,
"usagePercent": 50.0,
"swapTotal": 2147483648,
"swapUsed": 0
},
"disks": [
{
"filesystem": "/dev/sda1",
"mountpoint": "/",
"total": 107374182400,
"used": 53687091200,
"free": 53687091200,
"usagePercent": 50.0
}
],
"network": [
{
"interface": "eth0",
"rxBytes": 123456789,
"txBytes": 98765432,
"rxSpeed": 15000,
"txSpeed": 8000
}
],
"app": {
"nodeVersion": "v20.11.0",
"processMemory": {
"rss": 52428800,
"heapTotal": 31457280,
"heapUsed": 24117248,
"external": 1048576
},
"eventLoopDelay": 1.234,
"activeConnections": 42,
"uptime": 3600,
"pid": 12345
},
"healthChecks": [
{ "name": "Primary DB", "type": "database", "status": "healthy", "responseTime": 3 },
{ "name": "Cache", "type": "redis", "status": "healthy", "responseTime": 1 },
{ "name": "Payments API", "type": "http", "status": "unhealthy", "responseTime": 5001, "error": "timeout" }
]
}License
MIT — Architecture Team, June 2026
