telemetry
module wittgenstein_observability.telemetry
OpenTelemetry configuration — multi-exporter factory with env-driven config.
Ported from wittgenstein-core's backend/src/observability/otel_config.py (ADR-092)
that implementation was a strict superset of what this lib originally shipped (single OTLP-trace-only exporter) — this is now the canonical implementation, the backend consumes it via a thin facade.
Supports additive exporter selection via OTEL_EXPORTERS env var
otlp, datadog, prometheus, console (comma-separated) Backward compatible with ENABLE_OTEL_TRACING=true (defaults to OTLP).
Functions
-
is_otel_enabled — Check if OpenTelemetry is enabled.
-
get_otel_endpoint — Get the OTEL collector endpoint.
-
configure_opentelemetry — Configure OpenTelemetry SDK with multi-exporter factory.
-
setup_telemetry — Configure OTel — alias for configure_opentelemetry(), kept for backward compat.
-
get_tracer — Get a tracer for creating spans.
-
get_meter — Get a meter for creating metrics.
-
trace_llm_request — Decorator to trace LLM requests with OpenTelemetry.
-
trace_method — Decorator that wraps any service method in an OTel span.
-
shutdown_opentelemetry — Shutdown OpenTelemetry providers gracefully.
-
instrument_app — Instrument a FastAPI instance with OpenTelemetry.
wittgenstein_observability.telemetry.is_otel_enabled
is_otel_enabled() → bool
Check if OpenTelemetry is enabled.
Returns True if EITHER
- OTEL_EXPORTERS is non-empty, OR
- ENABLE_OTEL_TRACING=true (legacy, backward compat)
wittgenstein_observability.telemetry.get_otel_endpoint
get_otel_endpoint() → str
Get the OTEL collector endpoint.
wittgenstein_observability.telemetry.configure_opentelemetry
configure_opentelemetry(service_name: str = 'wittgenstein-core-backend') → bool
Configure OpenTelemetry SDK with multi-exporter factory.
Supports additive exporter selection via OTEL_EXPORTERS env var. Each exporter is configured for traces, metrics, and logs where applicable.
Parameters
-
service_name : str — Name of the service for tracing
Returns
-
bool — True if configuration was successful, False otherwise
wittgenstein_observability.telemetry.setup_telemetry
setup_telemetry(service_name: str = 'agent-platform') → bool
Configure OTel — alias for configure_opentelemetry(), kept for backward compat.
Pre-ADR-092 callers used ENABLE_OTEL=true/OTEL_EXPORTER_OTLP_ENDPOINT and got OTLP-traces-only. Both env vars still work: ENABLE_OTEL_TRACING is the equivalent enable-flag consulted by is_otel_enabled(), and OTEL_EXPORTER_OTLP_ENDPOINT is still read by get_otel_endpoint(). Also runs pydantic-ai and SQLAlchemy auto-instrumentation, matching this function's original behavior.
wittgenstein_observability.telemetry.get_tracer
get_tracer(name: str = 'wittgenstein-core')
Get a tracer for creating spans.
Parameters
-
name : str — Name of the tracer (typically module name)
Returns
-
Tracer object or NoOp tracer if OTEL is disabled
wittgenstein_observability.telemetry.get_meter
get_meter(name: str = 'wittgenstein-core')
Get a meter for creating metrics.
Parameters
-
name : str — Name of the meter
Returns
-
Meter object or None if OTEL is disabled
wittgenstein_observability.telemetry.trace_llm_request
trace_llm_request(func)
Decorator to trace LLM requests with OpenTelemetry.
Adds spans for LLM API calls with relevant attributes. Works alongside Langfuse for LLM-specific observability.
wittgenstein_observability.telemetry.trace_method
trace_method(span_name: Optional[str] = None, component: str = 'service')
Decorator that wraps any service method in an OTel span.
Works with both sync and async methods. A no-op when OTel is not enabled.
Usage
@trace_method() async def ingest(self, doc): ...
@trace_method("embedding.encode", component="embedding") def encode(self, text): ...
wittgenstein_observability.telemetry.shutdown_opentelemetry
Shutdown OpenTelemetry providers gracefully.
wittgenstein_observability.telemetry.instrument_app
instrument_app(app: Any) → None
Instrument a FastAPI instance with OpenTelemetry.
Pre-existing lib capability (not present in the backend's own otel_config.py, which relied on the consuming app calling FastAPIInstrumentor directly) — kept as-is. Checks both this lib's original enable flag (ENABLE_OTEL) and the ported one (OTEL_EXPORTERS/ENABLE_OTEL_TRACING, via is_otel_enabled()) so pre-ADR-092 standalone consumers that only ever set ENABLE_OTEL keep working unchanged.