Node.js
The @opentelemetry/auto-instrumentations-node
package starts the OpenTelemetry SDK before your code loads. It instruments Express,
Fastify, Koa, NestJS, http, fetch, database drivers, Redis, Kafka and
more
without code changes.
Use this page when you run a Node.js service (JavaScript or TypeScript) and want it in FuseScope. For browser apps, see Real User Monitoring.
| Signal | Status | What is sent |
|---|---|---|
| Traces | Stable | Spans for requests, HTTP calls, database and messaging. |
| Metrics | Stable | HTTP server/client metrics, plus what your code records. |
| Logs | Development | pino, winston and bunyan records with trace IDs. |
Prerequisites
Section titled “Prerequisites”- Node.js on an active or maintenance LTS release. Current package versions require Node.js 22.15 or later.
- A FuseScope collector you can reach on port 4317 or 4318. See OTLP.
Install and run
Section titled “Install and run”-
Install the packages:
Terminal window npm install --save @opentelemetry/api @opentelemetry/auto-instrumentations-node -
Configure the SDK:
Terminal window export OTEL_SERVICE_NAME=checkoutexport OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production,service.version=1.4.2export OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufexport OTEL_TRACES_EXPORTER=otlpexport OTEL_METRICS_EXPORTER=otlpexport OTEL_LOGS_EXPORTER=otlp -
Load the instrumentation before your app:
Terminal window export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"node app.js
Useful settings:
| Variable | Example | Purpose |
|---|---|---|
OTEL_NODE_ENABLED_INSTRUMENTATIONS |
http,express,pg |
Only load these (names without @opentelemetry/instrumentation-). |
OTEL_NODE_DISABLED_INSTRUMENTATIONS |
fs,dns |
Skip these. fs is off by default. |
OTEL_NODE_RESOURCE_DETECTORS |
env,host,os |
Resource detectors to run. All run by default. |
OTEL_LOG_LEVEL |
debug |
The SDK’s own diagnostic output, printed to the console. |
Send to FuseScope
Section titled “Send to FuseScope”OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4317OTEL_EXPORTER_OTLP_PROTOCOL=grpcOTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufBehind the chart ingress, use https://otlp.example.com. See
from outside the cluster.
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufRun the collector with Docker, on a VM or in Kubernetes.
Docker
Section titled “Docker”The packages are regular dependencies, so they are in node_modules after npm ci:
FROM node:22-slimWORKDIR /appCOPY package*.json ./RUN npm ci --omit=devCOPY . .ENV NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"CMD ["node", "app.js"]docker run \ -e OTEL_SERVICE_NAME=checkout \ -e OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production \ -e OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318 \ -e OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \ -e OTEL_LOGS_EXPORTER=otlp \ checkout:latestKubernetes
Section titled “Kubernetes”Set the variables in the pod spec. The downward API adds the pod name and namespace:
env: - name: NODE_OPTIONS value: --require @opentelemetry/auto-instrumentations-node/register - name: OTEL_SERVICE_NAME value: checkout - name: OTEL_EXPORTER_OTLP_ENDPOINT value: http://fusescope-otel-collector.fusescope.svc.cluster.local:4318 - name: OTEL_EXPORTER_OTLP_PROTOCOL value: http/protobuf - name: K8S_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: K8S_NAMESPACE_NAME valueFrom: fieldRef: fieldPath: metadata.namespace - name: OTEL_RESOURCE_ATTRIBUTES value: deployment.environment.name=production,k8s.pod.name=$(K8S_POD_NAME),k8s.namespace.name=$(K8S_NAMESPACE_NAME)$(VAR) only expands variables defined earlier in the list, so keep
OTEL_RESOURCE_ATTRIBUTES last.
The pino, winston and bunyan instrumentations are included. Each does two things, both on by default:
- Correlation: adds
trace_idandspan_idto records written inside a span, so they also appear in stdout. - Sending: forwards each record to the OpenTelemetry Logs SDK, which exports it over
OTLP when
OTEL_LOGS_EXPORTER=otlp.
| Library | Sending needs |
|---|---|
| pino | pino 7 or later. |
| winston | winston 3, and npm install @opentelemetry/winston-transport. |
| bunyan | Nothing extra. |
console.log is not captured. If a collector already reads your stdout, set
OTEL_LOGS_EXPORTER=none so each line is stored once.
Check that data arrives
Section titled “Check that data arrives”- Send a few requests to the service.
- Open Services. The service appears under its
OTEL_SERVICE_NAMEwithin a minute. - Open the Traces explorer and filter by
service.name.
Nothing arrives? Run with OTEL_LOG_LEVEL=debug to see export errors, and check the
endpoint and protocol match (4318 with http/protobuf, 4317 with grpc).