Skip to main content
Version: Next

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

Consumption boundary: This is a public API for external consumers. Code outside mellea/telemetry/ opens spans via hook plugins (tracing_plugins.py), not by calling these functions. Exceptions are limited to spans opened from sync code, and are documented at their call site.

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: Component class name being generated from (chat).
  • num_actions: Number of actions in the batch call (batch).
  • has_format: Whether structured output was requested; emits gen_ai.output.type="json" when True.
  • format_type: Structured-output class name, when has_format is True.
  • tool_calls_enabled: Whether tool calling is enabled for the call.
  • streaming: Whether streaming was requested; emits gen_ai.request.stream when True (unset/False is left off, which semconv reads as non-streaming).
  • attach_context: Whether to attach the span as the ambient OTel context.

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 start_session_startup_span

start_session_startup_span(session_id: str) -> Span | None

Open the start_session span around backend construction.

Stashed under a derived key so it doesn't collide with the long-lived session span when both share a session_id.

Args:

  • session_id: Session UUID. The in-flight key is derived from this.
  • backend: Requested backend name (e.g. "ollama", "hf"), before resolution to a provider id.
  • model_id: Resolved model id string.
  • context_type: Context class name (e.g. "SimpleContext").

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_session_startup_span

finish_session_startup_span(session_id: str) -> bool

End the nested start_session span if one is in flight.

Args:

  • session_id: Session UUID from the matching open call. The in-flight key is derived from this.
  • exception: If provided, mark the span ERROR.

Returns:

  • True if a child span was open and was finished; False if no-op.

FUNC start_session_span

start_session_span(session_id: str) -> Span | None

Open the long-lived session span over a session's lifetime.

Args:

  • session_id: Session UUID, used as the correlation key.
  • context_type: Context class name.
  • backend: Resolved provider id (e.g. "ollama"), normalized to its gen_ai.provider.name value when provided.

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_session_span

finish_session_span(session_id: str) -> None

End the long-lived session span.

Args:

  • session_id: Correlation key from the matching open call.
  • exception: If provided, mark the span ERROR.

FUNC start_action_span

start_action_span(action_id: str) -> Span | None

Open the action span for a single component execution.

Args:

  • action_id: UUID correlating this component execution across hooks.
  • action_class_name: Class name of the component being executed.
  • has_requirements: Whether requirements were supplied.
  • has_strategy: Whether a sampling strategy was supplied.
  • strategy_type: Sampling strategy class name when present.
  • has_format: Whether a structured-output format was supplied.
  • tool_calls: Whether tool calling is enabled.
  • attach_context: Whether to attach the span as the ambient OTel context.

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_action_span_success

finish_action_span_success(action_id: str) -> None

End the action span with response-side attributes.

The response text is recorded (truncated) only when content capture is enabled; its length is always recorded (a non-content metric).

Args:

  • action_id: Correlation key from the matching open call.
  • num_generate_logs: Number of generate logs the run accumulated.
  • sampling_success: Sampling outcome, set when a strategy ran.
  • response_text: Raw response text. Recorded only when content tracing is enabled.
  • response_length: Response length; always safe to record (ungated).

FUNC finish_action_span_error

finish_action_span_error(action_id: str) -> None

End the action span with ERROR status.

Args:

  • action_id: Correlation key from the matching open call.
  • exception: The exception that ended the action, or None to set ERROR status without a recorded exception.

FUNC start_tool_span

start_tool_span(tool_invocation_id: str, model_tool_call: Any) -> Span | None

Open the execute_tool span for a single tool invocation.

Args:

  • tool_invocation_id: UUID correlating this invocation across the pre/post hooks.
  • model_tool_call: The ModelToolCall being executed.
  • is_control_flow: Whether this tool is framework control flow.
  • attach_context: Whether to attach the span as the ambient OTel context.

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_tool_span_success

finish_tool_span_success(tool_invocation_id: str) -> None

End the tool span with success status and response-side attributes.

gen_ai.tool.call.result is recorded (truncated) only when content capture is enabled.

Args:

  • tool_invocation_id: Correlation key from the matching open call.
  • execution_time_ms: Wall-clock tool execution time.
  • result: The tool's return value. Recorded as gen_ai.tool.call.result only when content tracing is enabled.

FUNC finish_tool_span_error

finish_tool_span_error(tool_invocation_id: str) -> None

End the tool span with ERROR status, recording the exception.

Args:

  • tool_invocation_id: Correlation key from the matching open call.
  • execution_time_ms: Wall-clock tool execution time.
  • exception: The exception raised by the tool, or None to set ERROR status without a recorded exception.

FUNC start_streaming_span

start_streaming_span(streaming_id: str) -> Span | None

Open the stream span for one streaming run.

Args:

  • streaming_id: UUID correlating this streaming run across hooks.
  • has_requirements: Whether requirements were supplied.
  • requirement_count: Number of requirements supplied.
  • chunking_strategy: ChunkingStrategy class name.
  • attach_context: Whether to attach the span as the ambient OTel context.

Returns:

  • The span, or None if tracing is disabled.

FUNC add_span_event

add_span_event(key: str) -> None

Add an OTel span event to any in-flight application span.

Leaves the span in _in_flight_spans for a later finish_* call to close.

Args:

  • key: Correlation key from the matching open call.
  • event_name: Span-event name.
  • attributes: Span-event attributes; None values are skipped.

FUNC finish_streaming_span

finish_streaming_span(streaming_id: str) -> None

End the stream span, recording its outcome.

Sets OK status on success. On failure, marks the span ERROR: with the exception recorded when one is given, otherwise with failure_reason and no recorded exception.

Args:

  • streaming_id: Correlation key from the matching open call.
  • success: True only on a clean completion.
  • failure_reason: Human-readable ERROR-status description, used when success is False and no exception is given.
  • exception: The exception raised by the orchestrator, when one was.
  • model: Model identifier, when known.
  • provider: Provider name, when known.
  • full_text_length: Length of the validated-and-emitted text at stream exit.

FUNC start_sampling_span

start_sampling_span(sampling_id: str) -> Span | None

Open the sampling span for a single sampling loop.

Iterations and repairs are recorded as span events on this span (see add_span_event) rather than as child spans.

Args:

  • sampling_id: UUID correlating this loop across the sampling hooks.
  • strategy_type: Sampling strategy class name.
  • loop_budget: Maximum iterations per subsample.
  • requirement_count: Number of requirements validated each iteration.
  • attach_context: Whether to attach the span as the ambient OTel context.

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_sampling_span

finish_sampling_span(sampling_id: str) -> None

End the sampling span.

Records the outcome attributes, or ERROR status with the exception when the loop raised.

Args:

  • sampling_id: Correlation key from the matching open call.
  • success: True if at least one attempt passed all requirements.
  • iterations_used: Total iterations that completed across subsamples.
  • failure_reason: Reason recorded when success is False.
  • exception: The exception that ended the loop, when one was raised.

FUNC start_validation_span

start_validation_span(validation_id: str) -> Span | None

Open the validation span for a single requirement-validation batch.

Args:

  • validation_id: UUID correlating the pre/post validation hooks.
  • requirement_count: Number of requirements being validated.
  • attach_context: Whether to attach the span as the ambient OTel context.

Returns:

  • The span, or None if tracing is disabled.

FUNC finish_validation_span

finish_validation_span(validation_id: str) -> None

End the validation span.

Records the outcome attributes, or ERROR status with the exception when the check raised. Failure reasons are recorded only when content capture is enabled, since a requirement's reason can echo model output.

Args:

  • validation_id: Correlation key from the matching open call.
  • all_validations_passed: Whether every requirement passed.
  • passed_count: Number of requirements that passed.
  • failed_count: Number of requirements that failed.
  • failure_reasons: One reason per failing requirement. Recorded only when content tracing is enabled.
  • exception: The exception that ended validation, when one was raised.