Skip to content

Honor opentelemetry_exclude_urls in the Litestar bootstrapper - #151

Merged
vrslev merged 1 commit into
community-of-python:mainfrom
personage-hub:faststream-http-server-spans
Oct 6, 2026
Merged

vrslev merged 1 commit into
community-of-python:mainfrom
personage-hub:faststream-http-server-spans

Conversation

@personage-hub

@personage-hub personage-hub commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

LitestarOpenTelemetryInstrumentationMiddleware read excluded urls only from OTEL_PYTHON_LITESTAR_EXCLUDED_URLS (or OTEL_PYTHON_EXCLUDED_URLS), so the opentelemetry_exclude_urls setting documented in the README had no effect for Litestar, and opentelemetry_generate_health_check_spans=False did not suppress health-check spans either.

Changes

  • LitestarOpenTelemetryInstrumentationMiddleware combines define_exclude_urls() with the env-based list via CombinedExcludeList, built once at middleware creation instead of per request.
  • define_exclude_urls moves to BaseOpentelemetryInstrument and build_span_name to instruments/opentelemetry_instrument.py, so other bootstrappers can reuse them without importing the Litestar module (the litestar extra may be missing). Add OpenTelemetry instrument for FastMCP #152 relies on this.
  • README: the default of opentelemetry_exclude_urls is ["/metrics"], and both settings are described precisely.

Scope note: an earlier revision of this PR also added SERVER spans for FastStream ASGI routes. That part was dropped after review; the FastStream bootstrapper is untouched now.

Breaking

opentelemetry_exclude_urls used to be ignored for Litestar. Now the default /metrics exclusion applies, so /metrics stops producing spans, and opentelemetry_generate_health_check_spans=False suppresses health-check spans (the default is True). This affects every Litestar user and should go into the release notes.

Tests

  • opentelemetry_exclude_urls=["/internal"] suppresses spans without env vars; other routes still produce SERVER spans.
  • Settings and env exclusions combine.

just lint-ci and just test pass (222 tests).

🤖 Generated with Claude Code

from microbootstrap.config.faststream import FastStreamConfig
from microbootstrap.instruments.health_checks_instrument import HealthChecksInstrument
from microbootstrap.instruments.logging_instrument import LoggingInstrument
from microbootstrap.instruments.opentelemetry_instrument import (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давай тут импортнем сразу instrument, чтобы импорт не разрастался

def __init__(self, **kwargs: typing.Any) -> None: # noqa: ANN401
# `broker` argument is positional-only
super().__init__(kwargs.pop("broker", None), **kwargs)
self.http_app: ASGIApp = super().__call__

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Выглядит как-то оч странно, почему метод - это объект asgiapp?

super().__init__(kwargs.pop("broker", None), **kwargs)
self.http_app: ASGIApp = super().__call__

def add_http_middleware(self, build_middleware: typing.Callable[[ASGIApp], ASGIApp]) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поч функцию извне прокидываем? Разве нет какой-то функции, добаляющей миддлварь в фастстриме для веб приложения?

def add_http_middleware(self, build_middleware: typing.Callable[[ASGIApp], ASGIApp]) -> None:
self.http_app = build_middleware(self.http_app)

async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не оч нравится, что мы так переопределяем поведение объекта приложения, без этого никак не обойтись?

Comment on lines +79 to +88
def build_faststream_route_details_from_scope(
scope: Scope,
routes: typing.Iterable[tuple[str, ASGIApp]],
) -> tuple[str, dict[str, str]]:
method: typing.Final = str(scope.get("method", "HTTP")).strip()
path: typing.Final = scope.get("path")
# FastStream matches ASGI routes by exact path, unmatched paths get no `http.route` to keep its cardinality low
if path is None or all(path != route_path for route_path, _ in routes):
return method, {}
return build_span_name(method, path), {"http.route": path}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Короче, мы тут как будто начинаем делать работу за фастстрим. Это не целевое решение. Давай закинем им в чат, что очень надо это поддержать. Пока предлагаю это не вливать и если очень надо сделать именно так, то это можно переопределить в конкретной репе (или сделать как у нас в репах)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можешь даже сам пойти в фастстрим и запилить там ПР. Или зайти к Роме, есть там такой чувак, который за телеметрию отвечает

@personage-hub
personage-hub force-pushed the faststream-http-server-spans branch from 8493dc5 to b0eb8b7 Compare October 5, 2026 08:57
@personage-hub personage-hub changed the title Add SERVER spans for FastStream ASGI routes Honor opentelemetry_exclude_urls in the Litestar bootstrapper Oct 5, 2026
@personage-hub
personage-hub force-pushed the faststream-http-server-spans branch from b0eb8b7 to 5f8e27e Compare October 5, 2026 10:10
LitestarOpenTelemetryInstrumentationMiddleware read exclusions only from
OTEL_PYTHON_LITESTAR_EXCLUDED_URLS, so the opentelemetry_exclude_urls setting
was ignored for Litestar. Combine define_exclude_urls() with the env-based
list (CombinedExcludeList) and build it once instead of per request.

define_exclude_urls moves to BaseOpentelemetryInstrument and build_span_name
to instruments/opentelemetry_instrument.py so other bootstrappers can reuse
them without importing the Litestar module.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@personage-hub
personage-hub force-pushed the faststream-http-server-spans branch from 5f8e27e to 7564f48 Compare October 6, 2026 08:35
@vrslev
vrslev merged commit 83113b4 into community-of-python:main Oct 6, 2026
17 checks passed
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.

3 participants