"""Business telemetry helpers (no real Collector required).""" from __future__ import annotations import pytest from opentelemetry import trace from app.core.business_telemetry import business_span from app.core.config import settings class TestBusinessSpan: def test_disabled_is_noop(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(settings, "otel_enabled", False) with business_span("memoir.phase1", user_id="u1") as span: assert span == trace.INVALID_SPAN def test_filters_high_cardinality_attrs(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(settings, "otel_enabled", True) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( InMemorySpanExporter, ) exporter = InMemorySpanExporter() provider = TracerProvider() provider.add_span_processor(SimpleSpanProcessor(exporter)) monkeypatch.setattr( "app.core.business_telemetry.get_tracer", lambda _name: provider.get_tracer("test"), ) with business_span( "memoir.phase2", user_id="user-123", chapter_category="childhood", ): pass spans = exporter.get_finished_spans() assert spans attrs = dict(spans[0].attributes or {}) assert attrs.get("business.chapter_category") == "childhood" assert "business.user_id" not in attrs def test_enabled_yields_span(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(settings, "otel_enabled", True) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( InMemorySpanExporter, ) exporter = InMemorySpanExporter() provider = TracerProvider() provider.add_span_processor(SimpleSpanProcessor(exporter)) monkeypatch.setattr( "app.core.business_telemetry.get_tracer", lambda _name: provider.get_tracer("test"), ) with business_span("conversation.ws.process_turn") as span: assert span.is_recording()