OpenTelemetry¶
Helpers for surfacing OpenTelemetry context on HTTP responses.
imbi-common does not configure the OpenTelemetry SDK itself —
that is the responsibility of the consuming service (see the
Installation guide for the
recommended environment variables). The helpers in this module
operate on whatever span context is already active when the middleware
runs.
Trace ID Response Middleware¶
imbi.common.otel.TraceIdResponseMiddleware is an ASGI middleware
that adds the active trace ID to every HTTP response. Operators and
frontend code can paste the value into the configured tracing backend
(Tempo, Jaeger, Honeycomb, etc.) to jump straight to the request's
trace.
from fastapi import FastAPI
from imbi.common.otel import TraceIdResponseMiddleware
app = FastAPI()
app.add_middleware(TraceIdResponseMiddleware)
The default header name is trace-id. Override it when installing
the middleware — for example, to expose the trace ID under a
vendor-specific name:
The header value is the 32-character lowercase hexadecimal trace ID
(the same format that appears in the W3C traceparent header).
When the header is added¶
The middleware checks for a valid recording span on each request and only writes the header when one is present. Specifically, no header is added when:
opentelemetry-apiis not installed (the middleware is safe to install unconditionally — it becomes a pass-through).- No OpenTelemetry instrumentation has activated a server span for
the request (e.g. the SDK is disabled via
OTEL_SDK_DISABLED=true, or the request was sampled out). - The request is not an HTTP request (lifespan, WebSocket, etc.).
Middleware ordering¶
Install TraceIdResponseMiddleware outside the OpenTelemetry
FastAPI/ASGI instrumentation so that the server span is active when
the response headers are written. In practice this means calling
app.add_middleware(TraceIdResponseMiddleware) after the
instrumentation has wrapped the application — Starlette's
add_middleware installs middleware in last-added-is-outermost
order, so the most-recently-added wrapper sees the response on its
way out.
Standards note¶
There is no IANA-registered HTTP response header for tracing context.
The W3C traceparent and tracestate headers are scoped to request
direction; the W3C Trace Context Level 2 traceresponse header is an
unfinished draft. The pragmatic, standards-clean alternative for
browser clients is the IANA-registered
Server-Timing header
carrying a traceparent entry in addition to trace duration —
services that need browser-side correlation should expose the trace
ID through Server-Timing in addition to (or instead of) the
simple trace-id header.
Trace ID Helper¶
imbi.common.otel.current_trace_id() returns the active span's trace
ID as a 32-character lowercase hexadecimal string, or None when no
valid OpenTelemetry span is recording (or opentelemetry-api is not
installed). Use it to correlate application logs, audit records, or
calls to external systems with a trace without depending directly on
the OpenTelemetry API:
from imbi.common.otel import current_trace_id
trace_id = current_trace_id()
if trace_id is not None:
audit_record.trace_id = trace_id
This is the same helper that AccessLogMiddleware and
TraceIdResponseMiddleware use internally.
API Reference¶
TraceIdResponseMiddleware ¶
ASGI middleware that adds the active OTEL trace ID to responses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
ASGIApp
|
The wrapped ASGI application. |
required |
header_name
|
str
|
HTTP header name added to each response when a
valid trace ID is available. Defaults to |
DEFAULT_HEADER_NAME
|
Source code in libraries/common/src/imbi/common/otel.py
current_trace_id ¶
Return the active span's trace ID as a 32-char lowercase hex string.
Returns None when opentelemetry-api is not installed or the
current span has no valid context (e.g. the request is not being
recorded). Useful for correlating application logs, audit records,
or external system calls to an OpenTelemetry trace without
depending directly on the OTel API.