Skip to main content

mellea.telemetry.tracing

OpenTelemetry tracing instrumentation for Mellea.

Provides distributed tracing with two independent tracer scopes:

  1. Application Trace (mellea.application) - User-facing operations
  2. Backend Trace (mellea.backend) - LLM backend interactions

Follows OpenTelemetry Gen-AI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/

Configuration via environment variables:

  • MELLEA_TRACES_ENABLED: Enable tracing (default: false).
  • MELLEA_TRACES_OTLP: Enable OTLP span exporter (default: false).
  • MELLEA_TRACES_CONSOLE: Print spans to console (default: false).
  • MELLEA_TRACES_CONTENT: Capture prompt/response content on spans (default: false). Content may include PII; enable only in controlled environments. Also recognised: OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT (OTel standard).
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: Trace-specific OTLP endpoint (optional).
  • OTEL_EXPORTER_OTLP_ENDPOINT: General OTLP endpoint (fallback).
  • OTEL_SERVICE_NAME: Service name for traces (default: mellea).

Functions

FUNC is_tracing_enabled

is_tracing_enabled() -> bool

Check if tracing is enabled.

Returns:

  • True if MELLEA_TRACES_ENABLED is truthy AND OpenTelemetry is installed.

FUNC is_content_tracing_enabled

is_content_tracing_enabled() -> bool

Check if content capture is enabled.

Content capture records prompt and response text on spans and may contain PII; enable only in controlled environments.

Returns:

  • True if enabled via MELLEA_TRACES_CONTENT or
  • OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT.

FUNC get_application_tracer

get_application_tracer() -> Any

Return the application tracer.

Returns:

  • Tracer instance for application-level spans, or None if tracing is
  • disabled or OpenTelemetry is not available.

FUNC get_backend_tracer

get_backend_tracer() -> Any

Return the backend tracer.

Returns:

  • Tracer instance for backend-level spans, or None if tracing is
  • disabled or OpenTelemetry is not available.

FUNC start_backend_span

start_backend_span(operation: str, generation_id: str) -> Span | None

Open a backend span, activate it as the current OTel context, and stash both under generation_id.

The span is also attached as the current OTel context so nested OTel-instrumented work (HTTP clients, framework wrappers, etc.) parents under it. Activation propagates to asyncio tasks spawned after this call: each new task snapshots the current context at creation time.

Args:

  • operation: Span name ("chat" or "text_completion").
  • generation_id: Correlation key for the matching finish call.
  • model: Model identifier, or None if not yet known (chat path populates this in post_processing).
  • provider: Provider name, or None if not yet known.
  • action_class_name: Optional mellea.action_type attribute (chat).
  • num_actions: Optional mellea.num_actions attribute (batch).
  • has_format: Optional mellea.has_format attribute (whether structured output was requested).
  • format_type: Optional mellea.format_type attribute (the structured output class name, when has_format is True).
  • tool_calls_enabled: Optional mellea.tool_calls_enabled attribute.

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_backend_span_success

finish_backend_span_success(generation_id: str) -> None

Add response-side attrs and end the in-flight backend span.

Refreshes request-side attrs from gen first, since chat-path backends populate model/provider on the MOT only after the API call returns.

Args:

  • generation_id: Correlation key from the matching pre-call.
  • operation: Span name used to refresh request attrs.
  • usage: Aggregate token-usage dict (OpenAI shape).
  • mot: The fully-computed ModelOutputThunk, or None.
  • gen: The GenerationMetadata from the MOT, or None.

FUNC finish_backend_span_error

finish_backend_span_error(generation_id: str) -> None

Set ERROR status, record the exception, and end the in-flight span.

Args:

  • generation_id: Correlation key from the matching pre-call.
  • operation: Span name used to refresh request attrs (chat path may have late-populated model/provider on the MOT before the error).
  • exception: The exception raised by the backend.
  • gen: Optional GenerationMetadata for refreshing request attrs.

FUNC trace_application

trace_application(name: str, **attributes: Any) -> Generator[Any, None, None]

Create an application trace span if application tracing is enabled.

Args:

  • name: Name of the span.
  • **attributes: Additional attributes to add to the span.

FUNC set_span_attribute

set_span_attribute(span: Any, key: str, value: Any) -> None

Set an attribute on a span if the span is not None.

Args:

  • span: The span object (may be None if tracing is disabled).
  • key: Attribute key.
  • value: Attribute value.

FUNC set_span_error

set_span_error(span: Any, exception: BaseException) -> None

Record an exception on a span if the span is not None.

Args:

  • span: The span object (may be None if tracing is disabled).
  • exception: The exception to record.

FUNC set_span_status_error

set_span_status_error(span: Any, description: str) -> None

Mark a span as ERROR without recording a phantom exception event.

Use this for validation failures and other non-exception error conditions where the span should be marked failed but no exception was actually raised. Calling set_span_error in these cases would create a misleading recorded exception event in OTEL traces.

Args:

  • span: The span object (may be None if tracing is disabled)
  • description: Human-readable reason for the failure.