Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/introduction/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 0 additions & 5 deletions lite_bootstrap/bootstrappers/faststream_bootstrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
10 changes: 9 additions & 1 deletion tests/test_faststream_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -346,13 +352,15 @@ 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)
bootstrapper.bootstrap()
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()
Loading