Skip to content

fix(tracing): instrument FastAPI ASGI layer for inbound traceparent propagation#4972

Open
STHITAPRAJNAS wants to merge 1 commit intogoogle:mainfrom
STHITAPRAJNAS:fix/fastapi-otel-instrumentation-4767
Open

fix(tracing): instrument FastAPI ASGI layer for inbound traceparent propagation#4972
STHITAPRAJNAS wants to merge 1 commit intogoogle:mainfrom
STHITAPRAJNAS:fix/fastapi-otel-instrumentation-4767

Conversation

@STHITAPRAJNAS
Copy link

Fixes #4767.

Root cause

get_fast_api_app() calls _setup_telemetry() which correctly configures a TracerProvider and registers the W3C TraceContextTextMapPropagator. However, the FastAPI app returned to callers never had the OTel ASGI middleware applied to it. Because the traceparent header is only extracted at the ASGI boundary, every inbound HTTP request started a new trace root instead of continuing the distributed trace initiated by the upstream caller.

The existing workaround — FastAPIInstrumentor().instrument_app(app) applied manually after get_fast_api_app() returns — confirms the plumbing is otherwise correct.

What this PR does

After the FastAPI instance is created inside AdkWebServer.get_fast_api_app(), call FastAPIInstrumentor.instrument_app(app) when an OTel export pipeline is active (OTEL_EXPORTER_OTLP_* env vars or otel_to_cloud=True):

if otel_to_cloud or _otel_env_vars_enabled():
    try:
        from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
        FastAPIInstrumentor.instrument_app(app)
    except ImportError:
        logger.debug("opentelemetry-instrumentation-fastapi not installed ...")

Key design decisions:

  • Conditional — only when OTel is actually configured, so local dev with the default in-memory tracer is unaffected.
  • Best-effortImportError is caught and logged at DEBUG level; the server continues normally without the instrumentation.
  • Middleware ordering — applied before CORSMiddleware and _OriginCheckMiddleware so that Starlette's reverse-registration order leaves the security wrappers outermost, and the OTel middleware extracts headers before the route handler runs.

Dependency changes

opentelemetry-instrumentation-fastapi is added to:

  • otel-gcp extras — users who install google-adk[otel-gcp] now get automatic end-to-end tracing without any manual post-instrumentation step.
  • test extras — required by the new unit tests.

Tests

Four new tests in tests/unittests/cli/test_fast_api.py:

Test Verifies
test_fastapi_instrumented_when_otlp_env_var_set instrument_app called when an OTLP env var is present
test_fastapi_instrumented_when_otel_to_cloud_enabled instrument_app called when otel_to_cloud=True
test_fastapi_not_instrumented_without_otel_config instrument_app NOT called when OTel is unconfigured
test_missing_fastapi_instrumentor_does_not_prevent_startup Server starts and /health responds 200 even if the package is absent

…ropagation

Fixes google#4767.

When get_fast_api_app() is used in production behind an OTel-instrumented
caller (e.g. a Next.js service using @opentelemetry/sdk-node), every inbound
request carried a W3C traceparent header that ADK silently discarded.  The
TracerProvider and W3C propagator were already wired up correctly by
_setup_telemetry(), but without an ASGI-level hook to extract the header,
each request spawned a new trace root instead of continuing the caller's trace.

The fix calls FastAPIInstrumentor.instrument_app(app) immediately after the
FastAPI instance is created, but only when an OTel export pipeline is actually
active (OTLP env vars or otel_to_cloud=True).  The instrumentation is applied
before the CORS and origin-check middleware are registered so that Starlette's
reverse-registration order leaves the security wrappers outermost in the stack.

The call is best-effort: if opentelemetry-instrumentation-fastapi is absent a
debug-level message is emitted and the server starts normally.  The package is
added to the otel-gcp extras so users who install google-adk[otel-gcp] get
end-to-end distributed tracing out of the box without any manual
post-instrumentation step.

opentelemetry-instrumentation-fastapi is also added to the test extras so the
new unit tests can import it directly.

google#4767
@adk-bot adk-bot added the tracing [Component] This issue is related to OpenTelemetry tracing label Mar 24, 2026
@rohityan rohityan self-assigned this Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tracing [Component] This issue is related to OpenTelemetry tracing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exposed FastAPI server is not instrumented automatically using get_fast_api_app

3 participants