trace, context, SpanKind, SpanStatusCode, and the Span, SpanContext, Attributes, and Tracer types.
When to add a manual span
Auto-instrumentation creates spans for libraries, not for units of work. Add a manual span for:- A queue job or a cron tick. There is no incoming request, so nothing opens a root span. Without one, every database and Redis span the job makes is an orphan.
- A database client with no instrumentation. Wrap each call in a
CLIENTspan. - A unit of work you want to see by name inside a request.
A withSpan helper
The SDK does not ship a span wrapper yet. Copy this one. It sets the attributes, runs the function with the span active, sets the status, records an exception on throw, and always ends the span.
A root span per job
startActiveSpan puts the span in async-local storage. Every patched library call inside the handler parents to it. That one span turns the fragments into a waterfall.
A CLIENT span for a database call
Sampling and the kill switch
tracing.sampleRatiois parent-based. A request is traced whole or not at all. A manual span inside an unsampled request is not recorded.- A root span you open yourself takes a fresh sampling decision.
- When traces are off through
setTelemetryEnabledorSHERLOCK_TRACES_ENABLED=false, new spans are not recorded. The API calls still succeed, so your code does not need to check.
Related topics
Custom metrics
A histogram recorded inside a span links its exemplar to that span.
Traces in Sherlock
Find a trace and read the waterfall.

