Skip to main content
This page takes a Node.js service with no telemetry to first data in Sherlock. The full path, with the from-code start, deployment, and verification, is in End-to-end steps.

What you’ll learn

  • Where to find your collector credentials
  • How to install and register the SDK
  • The environment variables that start telemetry
  • What first data looks like in Sherlock

Prerequisites

  • A Sherlock organization, and access to Settings → Collector
  • A Node.js service on Node.js 20 or later, 20.6 or later for ES modules
  • The SDK tarball, until the package is on a public registry

Steps

1

Get your credentials

In Sherlock, open Settings and then Collector. The Collector Credentials card shows two values.
  • Endpoint. Click the copy button.
  • Bearer Token. Click Reveal, then copy it.
Decide the value of the env attribute for this service, for example prod or staging. Sherlock routes data into a source by this value.
The Collector page, with the Endpoint field, a copy button, and the masked Bearer Token with a reveal button

Settings → Collector → Collector Credentials

2

Install the package

The package needs Node.js 20 or later, and 20.6 or later for ES modules. It brings its own OpenTelemetry dependencies. Do not add @opentelemetry/* packages yourself. Type definitions are included.
The SDK is in alpha. Until the package is on a public registry, Sherlock provides it as a tarball. Put the tarball in your repository, point the dependency at it, and run npm install again:
3

Register the SDK before your app loads

The SDK patches libraries at the moment they load, so it must load first. How depends on your module system.
Your entry is .mjs, or package.json has "type": "module". A line-1 import is not enough here: static imports are linked before any code runs, so the patches would arrive too late. Register a loader hook with --import instead.Create otel.mjs next to your entrypoint:
Run your app with it, and put the same command in your start script:
@opentelemetry/instrumentation is installed with the SDK. You do not add it. In a container, set NODE_OPTIONS="--import ./otel.mjs" instead of changing the command.
Registering installs the patches. They record nothing until the pipelines start.
4

Set three environment variables and run

The register entry starts the pipelines on its own when it finds SHERLOCK_ACCESS_TOKEN and OTEL_SERVICE_NAME. There is no code to write.The SDK ships with a default endpoint. Compare it with the Endpoint on Settings → Collector, and set SHERLOCK_ENDPOINT to that value when they differ.
5

Send some requests

Hit a few routes of your service.
6

See the data in Sherlock

  • Traces. Open Traces. Your service name appears within about five seconds. Spans leave in batches, so keep the app running. A process that exits without stop() drops the pending batch. Open a trace to see the request and its spans.
  • Metrics. Open Metrics. http.server.request.duration appears after the first export interval, 30 seconds by default. The catalog refreshes every 60 seconds, so allow about a minute.
  • Logs. If your service logs with pino, each line written inside a request now carries trace_id, span_id, and trace_flags. The SDK does not ship logs. Ship and correlate logs shows the two ways to send them.
The Traces page listing requests of one service with span counts and durations

Traces: your service and its requests

The Metrics Explorer charting the p95 of http.server.request.duration

Metrics: http.server.request.duration

The whole thing in one file

This Express app is the quickstart plus one custom histogram with an exemplar and a clean shutdown. Save it as app.mjs next to the otel.mjs preload from step 3 and run node --import ./otel.mjs app.mjs.

Troubleshooting

Look at the first lines of your process output. With no token, the SDK logs one line and stays off:
A rejected token shows at the default log level as an export failure whose message ends in Unauthorized. Compare the token with Settings → Collector. OTEL_LOG_LEVEL=debug shows every export attempt.
The app is an ES module and the SDK was registered with an import instead of the --import preload. Go back to step 3.
More cases are in Troubleshooting.

End-to-end steps

Start from code, deploy, verify, and operate.

Custom metrics

Define your own instruments with exemplars.

Custom spans

Trace queue jobs and database calls.

Troubleshooting

Symptom, cause, and fix.