npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

Iโ€™ve always been into building performant and accessible sites, but lately Iโ€™ve been taking it extremely seriously. So much so that Iโ€™ve been building a tool to help me optimize and monitor the sites that I build to make sure that Iโ€™m making an attempt to offer the best experience to those who visit them. If youโ€™re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, ๐Ÿ‘‹, Iโ€™m Ryan Hefnerย  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If youโ€™re interested in other things Iโ€™m working on, follow me on Twitter or check out the open source projects Iโ€™ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soonโ€“ish.

Open Software & Tools

This site wouldnโ€™t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you ๐Ÿ™

ยฉ 2025 โ€“ย Pkg Stats / Ryan Hefner

@watchlog/apm

v1.0.6

Published

๐Ÿ”— **Website**: [https://watchlog.io](https://watchlog.io)

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/apm

Quick 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:

  1. Auto-instrumentation hooks supported libraries (HTTP, MongoDB, etc.)
  2. Exports OTLP spans and metrics to your Watchlog endpoint
  3. Detects runtime and targets localhost or 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:

  1. url option in instrument() function (if provided)
  2. 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:

  1. Check for Kubernetes serviceaccount token file
  2. Inspect /proc/1/cgroup for kubepods
  3. 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: bridge

Docker 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-app

Important 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 url option in your code to point to the agent container

License

MIT ยฉ Watchlog