DeepTracer
SDK Reference

Distributed Tracing

Trace requests across services with spans, W3C traceparent, and auto-tracing.

The simplest way to trace a unit of work. The span automatically ends when the callback finishes:

const result = await logger.startSpan("fetch-user", async (span) => {
  const res = await fetch("https://api.example.com/users/123", {
    headers: span.getHeaders(), // propagate trace context
  })
  return res.json()
})

If the callback throws, the span is marked as "error". If it resolves, the span is marked as "ok". Duration is measured automatically.

Manual spans

For cases where callback-based spans don't fit (e.g., event-driven code):

const span = logger.startInactiveSpan("process-webhook")

try {
  await processEvent(event)
  span.end({ status: "ok" })
} catch (error) {
  span.end({ status: "error", metadata: { error: error.message } })
  throw error
}

You must call span.end() yourself. Forgetting to end a span means it never gets sent to DeepTracer.

Nested spans

Both callback-based and manual spans support nesting:

await logger.startSpan("checkout", async (parentSpan) => {
  // Callback-based child
  await logger.startSpan("validate-cart", async () => {
    await validateItems(cart)
  })

  // Manual child from an inactive span
  const parent = logger.startInactiveSpan("process-payment")
  const child = parent.startInactiveSpan("charge-card")
  await chargeCard(card)
  child.end()
  parent.end()
})

Child spans inherit the trace_id from their parent, creating a connected trace tree on the dashboard.

Propagating trace context

Use span.getHeaders() to pass trace IDs to downstream services:

await logger.startSpan("call-api", async (span) => {
  const response = await fetch("https://api.myapp.com/data", {
    headers: {
      ...span.getHeaders(),
      "Content-Type": "application/json",
    },
  })
  return response.json()
})

The returned headers include:

HeaderFormatExample
traceparentW3C standard00-{traceId}-{spanId}-01
x-trace-idDeepTracer0af7651916cd43dd8448eb211c80319c
x-span-idDeepTracerb7ad6b7169203331

The downstream service can pick up the trace with logger.forRequest(request).

Auto-tracing in Next.js

When you use @deeptracer/nextjs, distributed tracing is enabled by default (autoTracing: true). The SDK:

  1. Registers an OpenTelemetry SpanProcessor that captures all Next.js spans (route handlers, server components, middleware, fetch calls)
  2. Wraps globalThis.fetch to create outgoing HTTP spans and inject traceparent headers

No per-route wrapping needed. Every request is traced automatically.

Restricting trace propagation

By default, traceparent headers are sent to all outgoing fetch URLs. Use tracePropagationTargets to restrict this to your own services:

export const { register, onRequestError } = init({
  tracePropagationTargets: [
    "https://api.myapp.com",
    /^https:\/\/.*\.internal\.myapp\.com/,
  ],
})

The wrap helper

Wrap any function with automatic tracing and error capture:

const tracedFetch = logger.wrap("fetch-data", async (url: string) => {
  const res = await fetch(url)
  return res.json()
})

const data = await tracedFetch("https://api.example.com/data")
// → creates a span named "fetch-data" with duration and status

On this page