OpenTelemetry
Node.js
Metrics

Metrics

Export custom application metrics from your Node.js app to TracePath using the OpenTelemetry Metrics API.

Setup

Metrics export is configured in your instrumentation.ts via the PeriodicExportingMetricReader. If you followed the Quick Start, metrics are already enabled.

import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
 
// In your NodeSDK config:
metricReaders: [
  new PeriodicExportingMetricReader({
    exporter: new OTLPMetricExporter({
      url: "https://ingest.tracepath.dev/api/otel/v1/metrics",
      headers: { Authorization: "Bearer your-project-token" },
    }),
    exportIntervalMillis: 30_000,
  }),
],

The option is metricReaders and it takes an array. The singular metricReader still works but is deprecated. Keep exportIntervalMillis at or above the export timeout (30 seconds by default), otherwise the SDK clamps the timeout and warns about it on startup.

Values are pushed on that interval, so a fresh counter takes up to 30 seconds to appear in the dashboard. Stopping the app flushes early if you added the SIGTERM handler from the Quick Start.

Creating Custom Metrics

Use @opentelemetry/api to create meters and instruments. Install it as a direct dependency (npm install @opentelemetry/api) rather than relying on it being hoisted from the SDK:

import { metrics } from "@opentelemetry/api";
 
const meter = metrics.getMeter("my-service");

Create the meter and its instruments once at module scope, not per request.

Metric Types

Counter

Monotonically increasing value. Use for counts of events:

const requestCounter = meter.createCounter("app.requests.total", {
  description: "Total number of requests",
});
 
// Increment
requestCounter.add(1, { endpoint: "/api/users", method: "GET" });

UpDownCounter

Value that can increase or decrease. Use for gauges like active connections:

const activeConnections = meter.createUpDownCounter("app.connections.active", {
  description: "Number of active connections",
});
 
activeConnections.add(1);   // connection opened
activeConnections.add(-1);  // connection closed

Histogram

Distribution of values. Use for durations and sizes:

const requestDuration = meter.createHistogram("app.request.duration", {
  description: "Request duration in milliseconds",
  unit: "ms",
});
 
const start = performance.now();
await handleRequest();
requestDuration.record(performance.now() - start, {
  endpoint: "/api/users",
});

Observable Gauge

Asynchronously observed value. Use for system metrics:

meter.createObservableGauge("app.memory.heap_used", {
  description: "Heap memory usage in bytes",
  unit: "bytes",
}).addCallback((result) => {
  result.observe(process.memoryUsage().heapUsed);
});

How Metrics Appear in TracePath

OTel TypeTracePath Handling
GaugeStored as-is
Sum (Counter)Stored as-is
HistogramConverted to {name}.avg and {name}.count

A histogram named app.request.duration therefore shows up in the dashboard as two metrics, app.request.duration.avg (carrying your unit) and app.request.duration.count. Search for the base name and you will find neither.

See OTel Metrics for full details on histogram handling and supported types.

Metrics You Get for Free

@opentelemetry/auto-instrumentations-node enables @opentelemetry/instrumentation-runtime-node by default, so these arrive without any code once a metric reader is configured:

MetricWhat it measures
nodejs.eventloop.delay.p50 / .p90 / .p99 / .mean / .maxEvent loop lag
nodejs.eventloop.utilizationFraction of time the loop was busy
http.server.request.duration.avg / .countServer request duration, from the HTTP instrumentation
v8js.memory.heap.usedHeap bytes in use, from the V8 runtime metrics
v8js.gc.duration.avg / .countGarbage collection pauses

Host-level metrics (CPU, memory, disk) are not included. @opentelemetry/instrumentation-host-metrics ships disabled, and the TracePath OTel Agent is the usual way to collect them.

Next Steps

  • Traces: manual spans, background jobs, exception recording
  • Logs: ship application logs and link them to traces
  • Quick Start: setup and installation