Skip to main content
Send Node.js logs to Rootprint over OTLP HTTP with the OpenTelemetry SDK, Pino, or Winston.

Prerequisites

  • A running Rootprint instance. Substitute its host for <your-rootprint>.
  • Node.js 22+ with npm. The examples are ES modules with top-level await: save them as .mjs, or set "type": "module" in package.json.
  • An ingest API key scoped to an OpenTelemetry logs index such as otel-logs-v0_9. In Settings → API keys, click Create ingest key and pick the index. See API keys.

Setup

1

Install

2

Set environment variables

The %20 after Bearer is required: OpenTelemetry SDKs expect URL-encoded values in OTEL_EXPORTER_OTLP_LOGS_HEADERS.
3

Minimal working example

4

Verify in Rootprint

Open Logs, filter on service_name:my-node-service, and your record should appear within a few seconds.

Structured logging

Pass attributes with the record. You can search and filter on them in Rootprint.
With Pino, pass an object as the first argument:

Framework recipe: Express

Initialize the SDK once at process start. Move the provider setup from the OpenTelemetry SDK example, from the imports through logs.setGlobalLoggerProvider(provider), into otel.js, and export a logger from it:
Import it before your Express app:

Troubleshooting

  • 401 or 403: the ingest API key is missing or wrong, or the space after Bearer isn’t written as %20. Check OTEL_EXPORTER_OTLP_LOGS_HEADERS. See Response codes.
  • 200 but no records in Logs: the ingest API key is scoped to an index without the OpenTelemetry logs schema, so the records are discarded. See Index target.
  • Nothing in Logs from a short-lived script: the batch processor buffers records. Shut down the logger provider before exit, as the minimal example does.
  • Every Winston line stored twice: the app also runs under the auto-instrumentation register hook from Send traces, which adds its own Winston transport. Set OTEL_NODE_DISABLED_INSTRUMENTATIONS=winston for that process.
  • Pino transport not emitting: pino-opentelemetry-transport reads the OTEL_* env vars itself. Set them in the process that spawns the transport worker.
  • TLS errors against a self-signed endpoint: set NODE_EXTRA_CA_CERTS=/path/to/ca.pem.