Skip to content

Programmatic autoinstrumentation of FastAPI fails depending on import order #3551

Closed
@yamplum

Description

@yamplum

Hi. Sorry if this is the wrong channel to report this, I'm not entirely sure if what I'm seeing is incorrect behavior or if I'm holding it wrong.

I'm trying to autoinstrument a FastAPI application served through uvicorn with traces and metrics. I'm aware of the issues with autoinstrumentation around the forking model, so I've abandoned the opentelemetry-instrument tool and am currently trying to autoinstrument post-fork by calling the opentelemetry.instrumentation.auto_instrumentation.initialize function in my application code.

I've noticed that if I call initialize() after importing FastAPI, I get no traces for my FastAPI routes. If I call it before the import, however, I do get the traces working correctly. Other instrumentations like psycopg, aiohttp and redis still work regardless of import order. I don't get any errors in the logs (other than the line about skipping Starlette instrumentation due to version mismatch, but I get it in both cases so it's probably not related).

# works: traces for route handlers
from opentelemetry.instrumentation.auto_instrumentation import initialize

initialize()

from fastapi import APIRouter, FastAPI, Request, Response


# doesn't work: no traces for route handlers
from fastapi import APIRouter, FastAPI, Request, Response
from opentelemetry.instrumentation.auto_instrumentation import initialize

initialize()

pyproject.toml dependencies:

"fastapi[standard]==0.112.2",
"psycopg[binary,pool]>=3.2.3,<4",
"redis[hiredis]>=5.1.0,<6",
"aiohttp[speedups]>=3.10.10,<4",
"opentelemetry-distro==0.54b1",
"opentelemetry-exporter-otlp>=1.33.1,<2",
"uvloop>=0.21.0,<0.22",

Relevant Dockerfile sections:

RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project --no-dev

RUN uv run opentelemetry-bootstrap --action=requirements >requirements.txt && \
    uv pip install -r requirements.txt


FROM python:3.13-slim-bookworm
WORKDIR /app
COPY --from=builder /app /app
COPY ./src ./src
ENV PATH="/app/.venv/bin:$PATH"
CMD ["uvicorn", "--reload", "--loop", "uvloop", "--host", "0.0.0.0", "--port", "8000", "--app-dir", "src", "--factory", "my_project.app_factory:make_app"]

Activity

changed the title [-]Programmatic autoinstrumentation of FastAPI fails depending on initialization order[/-] [+]Programmatic autoinstrumentation of FastAPI fails depending on import order[/+] on May 29, 2025
yamplum

yamplum commented on May 29, 2025

@yamplum
Author

Looking deeper into it, I see that the other modules get instrumented by wrapping runtime calls, whereas FastAPI gets instrumented by performing a class replacement. I guess my question is, what is the intended way to do instrumentation here? Should I not rely on initialize() and manually instrument my dependencies, or is there a better way? Maybe the FastAPI instrumentation method is too aggressive?

xrmx

xrmx commented on May 29, 2025

@xrmx
Contributor

@yamplum auto-instrumentation is supposed to run before your code so yeah the first hunk is the correct one. Said that we're trying to make things work on more cases so as you spotted there are some room for improvements on how the fastapi instrumentor works.

yamplum

yamplum commented on May 30, 2025

@yamplum
Author

I see, thank you. It's a bit unfortunate that the semantics for autoinstrumentation aren't precisely defined, but works for me. Hopefully this can help someone else struggling with the same problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @xrmx@yamplum

        Issue actions

          Programmatic autoinstrumentation of FastAPI fails depending on import order · Issue #3551 · open-telemetry/opentelemetry-python-contrib