@watchlog/apm
v1.0.6
Published
๐ **Website**: [https://watchlog.io](https://watchlog.io)
Keywords
Readme
@watchlog/apm
๐ Website: https://watchlog.io
Lightweight APM (Application Performance Monitoring) library for Node.js, built on OpenTelemetry. Provides out-of-the-box auto-instrumentation and flexible controls over which spans are sent.
Features
- Auto-instrumentation for HTTP, Express, MongoDB, gRPC, and more
- Manual custom spans via OpenTelemetry API
- OTLP exporter over HTTP (protobuf) for compact transport
- Environment detection (local vs Kubernetes in-cluster)
- Configurable sampling, error-only and slow-only span export
- Adjustable batching and metric export intervals
Installation
npm install @watchlog/apm
# or
yarn add @watchlog/apmQuick Start
Load before any other modules to ensure full auto-instrumentation:
// index.js โ must be first
const { instrument } = require('@watchlog/apm');
// Initialize with your service name and options
const sdk = instrument({
app: 'my-service', // your application name
errorTPS: 5, // max 5 error spans/sec
sendErrorTraces: true, // always send error spans
slowThresholdMs: 300, // always send spans slower than 300ms
sampleRate: 1 // random sample rate (0.0โ1.0, capped at 0.3)
});
// Continue loading your application
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Listening on 3000'));Under the hood:
- Auto-instrumentation hooks supported libraries (HTTP, MongoDB, etc.)
- Exports OTLP spans and metrics to your Watchlog endpoint
- Detects runtime and targets
localhostor in-cluster Watchlog agent
Custom Spans
Use the OpenTelemetry API directly for manual instrumentation:
const { trace } = require('@opentelemetry/api');
app.get('/db', async (req, res) => {
const tracer = trace.getTracer('watchlog-apm', '1.0.0');
const span = tracer.startSpan('fetch-user', {
attributes: { 'db.system': 'mongodb', 'db.operation': 'find' }
});
try {
const result = await tracer.withSpan(span, () => User.find());
res.json(result);
} catch (err) {
span.recordException(err);
res.status(500).send('Error');
} finally {
span.end();
}
});Configuration Options
| Option | Type | Default | Description |
| ---------------------- | --------- | ------------------------------------------------- | ----------------------------------------------------------------------- |
| app | string | node-app | Name of your application/service |
| url | string | auto-detected | Base OTLP endpoint (overrides auto-detection if provided) |
| headers | object | {} | Additional HTTP headers for the exporters |
| batchOptions | object | { maxBatchSize:200, scheduledDelayMillis:5000 } | Settings for the OTLP batch processor |
| metricIntervalMillis | number | 5000 | Interval (ms) for exporting metrics |
| sampleRate | number | 1.0 | Random sampling rate 0.0โ1.0 (capped at 0.3) for non-filtered spans |
| sendErrorTraces | boolean | false | If true, always export spans with non-UNSET status |
| errorTPS | number | Infinity | Maximum number of error spans to export per second |
| slowThresholdMs | number | 0 | If >0, always export spans whose duration exceeds this threshold |
Note: Priority order for endpoint selection:
urloption ininstrument()function (if provided)- Auto-detection (local or Kubernetes)
Environment Detection
The package automatically detects the runtime environment:
- Local / non-K8s:
http://localhost:3774/apm - Kubernetes:
http://watchlog-node-agent.monitoring.svc.cluster.local:3774/apm
Detection steps:
- Check for Kubernetes serviceaccount token file
- Inspect
/proc/1/cgroupforkubepods - DNS lookup for
kubernetes.default.svc.cluster.local
Manual Override: You can override the endpoint by passing url option in instrument() function
Docker Setup
When running your Node.js app in Docker, you need to configure the correct agent endpoint.
Using URL Option (Recommended for Docker)
// index.js
const { instrument } = require('@watchlog/apm');
const sdk = instrument({
app: 'my-service',
url: 'http://watchlog-agent:3774/apm', // Explicit agent URL for Docker
errorTPS: 5,
sendErrorTraces: true,
slowThresholdMs: 300,
sampleRate: 1
});
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000);Docker Compose Example:
version: '3.8'
services:
watchlog-agent:
image: watchlog/agent:latest
container_name: watchlog-agent
ports:
- "3774:3774"
environment:
- WATCHLOG_APIKEY=your-api-key
- WATCHLOG_SERVER=https://log.watchlog.ir
networks:
- app-network
node-app:
build: .
container_name: node-app
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- watchlog-agent
networks:
- app-network
networks:
app-network:
driver: bridgeDocker Run Example:
# 1. Create network
docker network create app-network
# 2. Run Watchlog Agent
docker run -d \
--name watchlog-agent \
--network app-network \
-p 3774:3774 \
-e WATCHLOG_APIKEY="your-api-key" \
-e WATCHLOG_SERVER="https://log.watchlog.ir" \
watchlog/agent:latest
# 3. Run Node.js app (make sure your code sets url: 'http://watchlog-agent:3774/apm')
docker run -d \
--name node-app \
--network app-network \
-p 3000:3000 \
my-node-appImportant Notes:
- When using Docker, use the container name as the hostname (e.g.,
watchlog-agent) - Both containers must be on the same Docker network
- The agent must be running before your app starts
- Set the
urloption in your code to point to the agent container
License
MIT ยฉ Watchlog
