Skip to content

Use Litestar's OpenTelemetryPlugin in the Litestar bootstrapper - #154

Open
personage-hub wants to merge 1 commit into
community-of-python:mainfrom
personage-hub:litestar-opentelemetry-plugin
Open

personage-hub wants to merge 1 commit into
community-of-python:mainfrom
personage-hub:litestar-opentelemetry-plugin

Conversation

@personage-hub

Copy link
Copy Markdown
Contributor

Summary

Litestar ships its own OpenTelemetryPlugin now, so the Litestar bootstrapper registers it instead of hand-building an ASGI middleware around OpenTelemetryMiddleware (the old LitestarOpenTelemetryInstrumentationMiddleware, which also re-created the OTel middleware on every request in handle).

  • opentelemetry_exclude_urls (plus the health check path when opentelemetry_generate_health_check_spans is off) map to the plugin's exclude; OTEL_PYTHON_LITESTAR_EXCLUDED_URLS keeps working through the plugin's exclude_urls_env_key, so CombinedExcludeList is no longer needed for Litestar.
  • User-supplied plugins are preserved, the lists are merged like any other container config.
  • Requires litestar>=2.22.0, where litestar.plugins.opentelemetry appeared (2.21 only has the deprecated litestar.contrib.opentelemetry path).

Why there is still a middleware

Litestar applies the plugin's middleware outside the router (Litestar.__init__ wraps asgi_handler with it), i.e. before path_template is known. That is also why Litestar's default scope_span_details_extractor reports GET /users/123. To keep the span names and http.route as they are today (GET /users/{user_id}), a tiny LitestarOpentelemetryRouteMiddleware inside the route handler stack renames the current server span by the route template. It does nothing for excluded urls (the span is non-recording there).

Tests

  • test_litestar_opentelemetry_server_spans_use_path_template asserts real exported spans: GET /users/{user_id} with http.route, and GET /missing for a 404.
  • Exclusion via settings and via OTEL_PYTHON_LITESTAR_EXCLUDED_URLS are now integration tests over exported spans.
  • just test: 344 passed.

Note: uv run mypy . reports two pre-existing errors in microbootstrap/helpers.py:29 with the locked mypy on Python 3.14; untouched here.

🤖 Generated with Claude Code

Litestar ships its own OpenTelemetry plugin since the custom middleware was written, so the
bootstrapper now registers OpenTelemetryPlugin instead of building an ASGI middleware around
OpenTelemetryMiddleware by hand (which also re-created the OTel middleware on every request).
opentelemetry_exclude_urls map to the plugin's exclude, OTEL_PYTHON_LITESTAR_EXCLUDED_URLS keeps
working through the plugin's exclude_urls_env_key.

Litestar applies the plugin middleware outside the router, before path_template is known, so a
small LitestarOpentelemetryRouteMiddleware inside the handler stack renames the server span by the
route template and sets http.route, keeping the span names unchanged.

Requires litestar>=2.22.0, where litestar.plugins.opentelemetry appeared.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@personage-hub
personage-hub force-pushed the litestar-opentelemetry-plugin branch from 5e8d302 to 80a9b11 Compare October 7, 2026 06:33

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant