Skip to main content
The Sherlock SDK for Node.js is a distribution: it starts from one import and sets Sherlock’s defaults for you. In Go you use the upstream SDK with the sherlock.go file from Setup, in either of its two variants. The result is the same data in Sherlock, with these differences.

Setup

Exemplars

Both mean the same thing on the Metrics page: 01 opens a trace, 00 has none.

HTTP instrumentation

  • No default ignore list. Health check paths are traced and counted until you add otelhttp.WithFilter. See Skip health checks.
  • Route on metrics, not on spans. http.route comes from the ServeMux pattern on the metric and in the span name. The span attribute needs the middleware. otelhttp.WithRouteTag no longer exists in v0.71.0.
  • Stable names only. OTEL_SEMCONV_STABILITY_OPT_IN is gone. The histograms are http.server.request.duration and http.client.request.duration in seconds, with no _ms variants.
  • 5xx responses. The span status is Error for status 500 and above. The server data point carries http.response.status_code=500 and no error.type.
  • A filtered request still traces its outbound calls, without a parent.
  • Counters. The Node.js Express adapter adds app.http.server.count and app.http.server.errors. otelhttp emits no counters; count requests from the histogram, or add your own.

Runtime switches

  • No kill-switch environment variables. SHERLOCK_TRACES_ENABLED and SHERLOCK_METRICS_ENABLED are Node.js SDK features. The kill switches section shows the two wrappers that give Go the same behavior, with a flag you own.
  • Sampling across services. Go’s ParentBased sampler follows the caller’s decision for a remote parent. The Node.js SDK resamples remote parents with its local ratio.

Logs

  • The Node.js SDK stamps pino lines and leaves shipping to a pino transport or a collector. Go can send logs itself over OTLP through the otelslog bridge, or stamp stdout lines with a 13-line slog.Handler wrapper for a collector. In both, only context-aware calls such as InfoContext get the ids.

Traps that are specific to Go

  • Only the first otel.SetMeterProvider delegates. Instruments handed out before a second call keep writing to the first provider, silently. Call Setup once, and never rebuild the provider at runtime.
  • Two views that match one instrument export it twice. Keep every histogram rule inside sherlockView.
  • Host header. WithHeaders(map[string]string{"Host": ...}) is ignored by Go’s HTTP client. Use WithHTTPClient with a transport that sets req.Host, and reapply timeout, proxy, and TLS settings on that client. See Endpoint on a private network.
  • WithEndpointURL keeps the path you give it. sherlock.go appends /v1/traces and /v1/metrics itself. A base URL alone sends every export to /.
  • Exporter self-reporting is not a concern. The OTLP exporters use their own HTTP client, so wrapping http.DefaultTransport with otelhttp.NewTransport does not trace the exports.

Go setup

The bootstrap file in both variants and a complete main.go.

Node.js SDK overview

What the distribution sets for you.