Files
skills/docs/observability/monitor/logger/src/otel/otel-context.md
2026-05-29 08:20:56 +01:00

2.5 KiB

otel-context

(no submodules)

Purpose

otel-context extracts the active OpenTelemetry trace context (trace_id and span_id) from the current OTel context and returns them as lowercase hex strings. This allows AbstractLogger to automatically annotate every log record with the correlation IDs of the span in which the log call was made — without requiring callers to pass trace context explicitly. When no span is active or the OTel API is configured with a no-op provider, the function returns an empty object without throwing.

Features

  • Reads trace_id and span_id from the active span via @opentelemetry/api
  • Returns {} when no span is active, the span context has all-zero IDs (no-op provider), or the OTel API throws unexpectedly
  • Never throws — defensive try/catch wraps the entire extraction
  • Zero side effects: pure function, no caching, safe to call on every log line

Usage: Basic Example

import { getOtelTraceContext } from "@suaveplan/logger/otel";

const traceCtx = getOtelTraceContext();
// When inside an active span: { trace_id: "abc123...", span_id: "def456..." }
// When no span is active: {}

Usage: Advanced Example

import { buildRecord } from "@suaveplan/logger/record";
import { getOtelTraceContext } from "@suaveplan/logger/otel";

// Used internally by AbstractLogger on every log call:
const traceCtx = getOtelTraceContext();
const record = buildRecord(level, msg, ctx, ts, traceCtx, errorPayload);
// record.trace_id and record.span_id are populated when a span is active

API Reference

getOtelTraceContext(): OtelTraceContext

Returns an object with optional trace_id and span_id string fields.

Returns {} when:

  • No span is active in the current context
  • The active span has an all-zero trace ID (indicates a no-op OTel SDK)
  • @opentelemetry/api throws for any reason

interface OtelTraceContext

interface OtelTraceContext {
  trace_id?: string;
  span_id?:  string;
}

Implementation Notes

The zero-ID guard (00000000000000000000000000000000) exists because the OTel no-op provider returns a valid-looking SpanContext with all-zero IDs rather than returning undefined. Emitting those zero IDs would mislead log consumers into thinking a real trace exists. The try/catch guard exists because OTel API implementations can throw in unusual environments (e.g., incompatible versions, patched globals in test environments).