Skip to content

fix: instrument every FastStream broker, with per-type middleware classes - #299

Merged
lesnik512 merged 1 commit into
mainfrom
fix/faststream-every-broker
Oct 24, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
fix/faststream-every-broker

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Closes #295.

The FastStream OpenTelemetry, Prometheus and logging instruments used application.broker, which FastStream defines as brokers[0]. Every other broker ran without spans or metrics and kept FastStream's default logger.

What changes

The logging instrument now replaces the logger params storage on every broker. Teardown restores each broker's own previous storage.

The OpenTelemetry and Prometheus instruments now add middleware to every broker. FastStream's middleware classes each handle one broker type: KafkaTelemetryMiddleware wires in a settings provider that reads msg.raw_message.topic, and a Redis raw message is a dict. So one class can't simply go on every broker. Two rules cover this:

  • 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 old meaning. It goes on every broker of the first broker's type (subclasses included). With one broker, or several of the same type, nothing changes for existing configs.

A broker with no matching class is left uninstrumented, and bootstrap() warns through warn_at_caller, naming the broker types and the config field.

All brokers share the instrument's single Prometheus registry. FastStream's MetricsContainer reuses a metric that already exists in the registry, and every metric has a broker label, so brokers of different types write separate series under one name. OpenTelemetry returns the existing instrument for an identical name, unit and description, so per-broker middleware instances don't conflict there either.

Brokers added after bootstrap() are not instrumented. The FastStream guide now says to add brokers first. A startup hook would only catch brokers added by hooks registered before it, so documenting this is more honest than a partial fix.

Tests

Written first and failing before the change:

  • two brokers of the same type both get both middlewares, with no warning
  • a single class with mixed broker types instruments the matching brokers and warns about the rest
  • a mapping gives each broker its most specific class
  • a mapping with no entry for a broker type skips that broker and warns
  • logging covers every broker, and teardown restores each one

The mixed-type tests use a RedisBroker subclass as the second type, since the dev dependencies don't include Kafka. I also ran the new docs example on a real KafkaBroker plus RedisBroker with faststream[kafka]==0.7.8, and each broker got its own Kafka or Redis middleware pair.

brokers exists from FastStream 0.6, so the faststream>=0.6 floor stays.

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.

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

1 participant