Skip to content

FastStream OpenTelemetry, Prometheus and logging instruments attach only to the first broker #295

Closed

Description

@lesnik512

This was generated by AI during triage.

Split out of #293, which covers the same problem in the health check.

The FastStream instruments read config.application.broker, which FastStream defines as brokers[0]:

  • FastStreamOpenTelemetryInstrument adds opentelemetry_middleware_cls to that broker only.
  • FastStreamPrometheusInstrument adds prometheus_middleware_cls to that broker only.
  • FastStreamLoggingInstrument replaces the logger params storage on that broker only, and its teardown restores only that broker.

In an app with more than one broker (for example through add_broker in FastStream 0.7), messages handled by any broker after the first produce no spans and no metrics, and that broker keeps FastStream's default logger instead of structlog.

Open questions

  • Can one Prometheus middleware registry be shared across several brokers of different types, or do the metric names collide?
  • Brokers added with add_broker after bootstrap() would still be missed. Is documenting that enough?

Activity

  1. added
    bugSomething isn't working
    needs-triageMaintainer needs to evaluate this issue
    on Oct 20, 2026
  2. lesnik512 commented on Oct 24, 2026

    @lesnik512
    MemberAuthor

    This was generated by AI during triage.

    Open questions

    Can one Prometheus registry serve brokers of different types? Yes. MetricsContainer.__init__ looks each metric name up in the registry and reuses an existing collector, so a second middleware instance does not hit a duplicate-registration error. Every metric carries a broker label ("kafka", "redis", ...), so brokers of different types write separate series under one name. The only condition is that every middleware on the registry uses the same metrics_prefix and custom label names, and lite-bootstrap sets neither.

    OpenTelemetry behaves the same way: the SDK returns the existing instrument for an identical name, unit and description, without a conflict warning.

    Brokers added after bootstrap()? Document it. In FastStream 0.7.8 add_broker only appends to brokers, and start() runs the on_startup hooks in order before starting brokers. A lite-bootstrap hook would miss brokers that later hooks add, which FastStream's own docstring suggests doing.

    A third problem

    FastStream middleware classes are tied to one broker type. KafkaTelemetryMiddleware and KafkaPrometheusMiddleware wire in Kafka's settings provider, which reads msg.raw_message.topic, and a Redis raw message is a dict. So applying the one configured class to every broker would fix apps with two Kafka brokers and break apps that mix Kafka and Redis.

    Plan

    • opentelemetry_middleware_cls and prometheus_middleware_cls also accept a mapping from broker class to middleware class. Lookup walks the broker's MRO, so the most specific entry wins.
    • A single class keeps its current meaning: it goes on every broker of the first broker's type.
    • A broker with no matching class is skipped, with one warn_at_caller warning naming it.
    • The logging instrument replaces params_storage on every broker and restores each one on teardown.
    • Docs: the mapping form, and that brokers must be added before bootstrap().
  3. added
    ready-for-agentFully specified, ready for an AFK agent
    and removed
    needs-triageMaintainer needs to evaluate this issue
    on Oct 24, 2026
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

    bugSomething isn't workingready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions