Spitfirev0.71.0 · What's new

Version: 0.71.0This documentation is for Spitfire 0.71.0.

Connecting a Node.js service with OTel

@opentelemetry/auto-instrumentations-node collects traces, metrics and logs without touching the code. Values and general rules: Connecting services with OTel: overview.

Version table

Node.js @opentelemetry/auto-instrumentations-node Note
22.15 and later (22, 24, 26) 0.82.0 The LTS versions OTel supports
18.19+, 20.6+, 22.0 – 22.14 0.81.2, @opentelemetry/api 1.9.1 0.82.0 does not install on these versions; 0.81.2 does not install with api 1.10.0
18.18 and earlier (16 included) not supported Upgrade to Node.js 22 or take server metrics only: Collector

Find your version: node --version with the Node.js the service uses.

The commands below say 0.82.0 and api@1.10.0; if your band is 18/20/22.0–22.14, write 0.81.2 and api@1.9.1.

Verified: 2026-11-02. Source: supported runtimes, npm page (engines), package documentation.

What you need

  • Spitfire address https://<spitfire> and OTLP receiver token sfotlp_…
  • Tower address http://<tower>:4318 and Collector token sfcol_…
  • Protocol http/protobuf
  • Service name <service-name>, version <service-version>, environment <environment>
  • With a private CA, the CA file /etc/spitfire-otel/ca.pem
  • With a proxy, the Tower and Spitfire in NO_PROXY
  • Sampling parentbased_traceidratio, 0.1

Linux (systemd)

  1. In the application's folder (where package.json is), install the packages:
bash
npm install --save @opentelemetry/auto-instrumentations-node@0.82.0 @opentelemetry/api@1.10.0
sudo mkdir -p /opt/spitfire-otel /etc/spitfire-otel
  1. Create the file /etc/spitfire-otel/<service-name>.env and paste this:
bash
IS_OTEL_ENABLED=true
OTEL_SERVICE_NAME=<service-name>
OTEL_RESOURCE_ATTRIBUTES=service.version=<service-version>,deployment.environment=<environment>
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://<spitfire>/otlp/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=authorization=sfotlp_…
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://<spitfire>/otlp/v1/logs
OTEL_EXPORTER_OTLP_LOGS_HEADERS=authorization=sfotlp_…
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<tower>:4318/v1/metrics
OTEL_EXPORTER_OTLP_METRICS_HEADERS=authorization=sfcol_…
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
NO_PROXY=<tower>,<spitfire>
#OTEL_EXPORTER_OTLP_CERTIFICATE=/etc/spitfire-otel/ca.pem
  1. Restrict its permission: sudo chmod 600 /etc/spitfire-otel/<service-name>.env
  2. Create the file /opt/spitfire-otel/otel-run and paste this:
bash
#!/bin/sh
# IS_OTEL_ENABLED=true: OTel is loaded with --require; any other value: not loaded, SDK off.
if [ "$IS_OTEL_ENABLED" = "true" ]; then
  export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register ${NODE_OPTIONS:-}"
else
  export OTEL_SDK_DISABLED=true
fi
exec "$@"
  1. Make it executable: sudo chmod 755 /opt/spitfire-otel/otel-run
  2. Find the service's current start command: systemctl cat <unit> | grep ^ExecStart
  3. Open sudo systemctl edit <unit> and paste this (on the last line, replace the command after ExecStart= with the command from step 6; WorkingDirectory must be the application's folder):
ini
[Service]
EnvironmentFile=/etc/spitfire-otel/<service-name>.env
WorkingDirectory=/srv/app
ExecStart=
ExecStart=/opt/spitfire-otel/otel-run /usr/bin/node /srv/app/server.js
  1. Restart: sudo systemctl daemon-reload && sudo systemctl restart <unit>
  2. See that it is loaded: the journalctl -u <unit> -n 50 output must not show the error Cannot find module '@opentelemetry/auto-instrumentations-node/register'.
Note

If it runs under pm2, do not use otel-run: write the values from the environment file under env in pm2's ecosystem.config.js and add node_args: "--require @opentelemetry/auto-instrumentations-node/register"; to turn it off, delete the node_args line and write OTEL_SDK_DISABLED=true.

Docker

  1. Put the otel-run file (Linux step 4) next to the Dockerfile.
  2. Add this to the Dockerfile (after npm install, with WORKDIR the application's folder); /opt/spitfire-otel/otel-run goes at the start of ENTRYPOINT, the rest is your command:
dockerfile
RUN npm install --save @opentelemetry/auto-instrumentations-node@0.82.0 @opentelemetry/api@1.10.0
COPY --chmod=755 otel-run /opt/spitfire-otel/otel-run
ENTRYPOINT ["/opt/spitfire-otel/otel-run", "node", "server.js"]
  1. Save the environment file (Linux step 2) on the Docker machine as /etc/spitfire-otel/<service-name>.env.
  2. Run: docker run --env-file /etc/spitfire-otel/<service-name>.env … or, in compose, under the service env_file: /etc/spitfire-otel/<service-name>.env.
  3. When the environment file changes, recreate the container (restart is not enough): docker compose up -d --force-recreate <service>

Kubernetes

  1. Prepare the image as in the Docker section.
  2. Save the environment file (Linux step 2) as <service-name>.env and make it a Secret:
bash
kubectl create secret generic <service-name>-otel --from-env-file=<service-name>.env \
  --dry-run=client -o yaml | kubectl apply -f -
  1. In the Deployment, add this under the container:
yaml
envFrom:
  - secretRef:
      name: <service-name>-otel
  1. Restart: kubectl rollout restart deployment/<deployment>

Windows (service)

  1. In the application's folder (where package.json is), install the packages:
powershell
npm install --save @opentelemetry/auto-instrumentations-node@0.82.0 @opentelemetry/api@1.10.0
  1. The service must start in the application's folder (with NSSM: nssm set <windows-service> AppDirectory C:\app; with another wrapper, its working directory setting).
  2. In an administrator PowerShell, write the service's name (Name in the Get-Service list) in place of <windows-service> and run:
powershell
$Service = "<windows-service>"
$IS_OTEL_ENABLED = "true"
$Otel = @(
  "IS_OTEL_ENABLED=$IS_OTEL_ENABLED",
  "OTEL_SERVICE_NAME=<service-name>",
  "OTEL_RESOURCE_ATTRIBUTES=service.version=<service-version>,deployment.environment=<environment>",
  "OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf",
  "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://<spitfire>/otlp/v1/traces",
  "OTEL_EXPORTER_OTLP_TRACES_HEADERS=authorization=sfotlp_…",
  "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://<spitfire>/otlp/v1/logs",
  "OTEL_EXPORTER_OTLP_LOGS_HEADERS=authorization=sfotlp_…",
  "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<tower>:4318/v1/metrics",
  "OTEL_EXPORTER_OTLP_METRICS_HEADERS=authorization=sfcol_…",
  "OTEL_TRACES_EXPORTER=otlp",
  "OTEL_METRICS_EXPORTER=otlp",
  "OTEL_LOGS_EXPORTER=otlp",
  "OTEL_TRACES_SAMPLER=parentbased_traceidratio",
  "OTEL_TRACES_SAMPLER_ARG=0.1",
  "NO_PROXY=<tower>,<spitfire>"
)
# Private CA: $Otel += "OTEL_EXPORTER_OTLP_CERTIFICATE=C:\spitfire-otel\ca.pem"
if ($IS_OTEL_ENABLED -eq "true") {
  $Otel += "NODE_OPTIONS=--require @opentelemetry/auto-instrumentations-node/register"
} else {
  $Otel += "OTEL_SDK_DISABLED=true"
}
$Key = "HKLM:\SYSTEM\CurrentControlSet\Services\$Service"
$Keep = @((Get-ItemProperty $Key).Environment | Where-Object { $_ -and $_ -notmatch '^(IS_OTEL_ENABLED|OTEL_|NODE_OPTIONS|NO_PROXY)=' })
Set-ItemProperty $Key -Name Environment -Type MultiString -Value ($Keep + $Otel)
Restart-Service -Name $Service -Force
  1. See that it is loaded: the service's log must not show the error Cannot find module '@opentelemetry/auto-instrumentations-node/register'.
Note

--require looks for the package from the working directory (Node.js documentation); that is why step 2 is needed.

Turning off and removing

  1. Turning off: set IS_OTEL_ENABLED=false in the environment file (in the script on Windows) and restart the service (Linux step 8, Docker step 5, Kubernetes step 4, or run the Windows script again).
  2. Removing: sudo systemctl revert <unit>, sudo rm -r /opt/spitfire-otel /etc/spitfire-otel and npm uninstall @opentelemetry/auto-instrumentations-node @opentelemetry/api; in Docker, delete the lines added to the Dockerfile; on Windows, delete the OTel lines from the service's Environment value.

Common problems

Symptom Cause Fix
Cannot find module '@opentelemetry/auto-instrumentations-node/register' The service does not start in the application's folder Make WorkingDirectory (WORKDIR in Docker) the folder with node_modules
npm EBADENGINE warning or install error The Node.js version is outside the band Write your band's versions (0.81.2, api@1.9.1)
No spans in an ES module ("type": "module") application Some libraries are not caught with --require in ESM In otel-run, add --experimental-loader=@opentelemetry/instrumentation/hook.mjs at the start of NODE_OPTIONS (ESM support)
No traces or metrics arrive Address, token or network Follow the Verifying steps