Skip to content

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

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()

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.