diff --git a/docs/introduction/configuration.md b/docs/introduction/configuration.md index e562731..3d0706a 100644 --- a/docs/introduction/configuration.md +++ b/docs/introduction/configuration.md @@ -102,9 +102,13 @@ For FastAPI there is additionally: request on the benchmark endpoint, at the cost of two thirds of the spans disappearing from your trace view. -For FastStream you must provide additionally: +For FastStream there is additionally: -- `opentelemetry_middleware_cls` +- `opentelemetry_middleware_cls` - the broker telemetry middleware, e.g. + `faststream.redis.opentelemetry.RedisTelemetryMiddleware`. You must provide it to trace broker + messages. Without it the rest of the configuration above still applies: the exporter is built, the + health-check span is recorded unless `opentelemetry_generate_health_check_spans` is False, and any + `opentelemetry_instrumentors` are applied. ## Pyroscope diff --git a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py index 56cf1b5..5b7d52d 100644 --- a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py @@ -143,11 +143,6 @@ def teardown(self) -> None: @dataclasses.dataclass(kw_only=True) class FastStreamOpenTelemetryInstrument(OpenTelemetryInstrument): bootstrap_config: FastStreamConfig - not_configured_reason = OpenTelemetryInstrument.not_configured_reason + " or opentelemetry_middleware_cls is empty" - - @classmethod - def is_configured(cls, bootstrap_config: "FastStreamConfig") -> bool: # ty: ignore[invalid-method-override] - return super().is_configured(bootstrap_config) and bool(bootstrap_config.opentelemetry_middleware_cls) def bootstrap(self) -> None: super().bootstrap() diff --git a/tests/test_faststream_bootstrap.py b/tests/test_faststream_bootstrap.py index 83d8109..39aaff8 100644 --- a/tests/test_faststream_bootstrap.py +++ b/tests/test_faststream_bootstrap.py @@ -332,7 +332,13 @@ def test_faststream_bootstrap_builds_its_own_tracer_provider(broker: RedisBroker bootstrapper.teardown() -def test_faststream_bootstrap_applies_opentelemetry_instrumentors(broker: RedisBroker) -> None: +@pytest.mark.parametrize( + "middleware_cls", [RedisTelemetryMiddleware, None], ids=["with_middleware", "without_middleware"] +) +def test_faststream_bootstrap_applies_opentelemetry_instrumentors( + broker: RedisBroker, + middleware_cls: type | None, +) -> None: recorded_tracer_providers: list[object] = [] class RecordingInstrumentor(BaseInstrumentor): @@ -346,6 +352,7 @@ def _uninstrument(self, **_kwargs: object) -> None: ... bootstrap_config = dataclasses.replace( build_faststream_config(broker=broker), + opentelemetry_middleware_cls=middleware_cls, opentelemetry_instrumentors=[RecordingInstrumentor()], ) bootstrapper = FastStreamBootstrapper(bootstrap_config=bootstrap_config) @@ -353,6 +360,7 @@ def _uninstrument(self, **_kwargs: object) -> None: ... try: instruments = [one for one in bootstrapper.instruments if isinstance(one, FastStreamOpenTelemetryInstrument)] assert len(instruments) == 1 + assert instruments[0]._tracer_provider is not None # noqa: SLF001 assert recorded_tracer_providers == [instruments[0]._tracer_provider] # noqa: SLF001 finally: bootstrapper.teardown()