# `orchestrator.obs.tracing`
<!-- generated by `orchestrator understand`; the PKG is source of truth, edits here are advisory -->

[← Episteme](../README.md) · [Architecture](../architecture.md)

**Source:** [`src/orchestrator/obs/tracing.py`](../../src/orchestrator/obs/tracing.py)

2 types · 11 functions · python

## Changing this safely

**Tested by** (2): `tests.agentic.test_loop_tracing`, `tests.obs.test_tracing`

**Most depended-upon here** — a change to these reaches the most code (call graph, ≤4 hops):

- [`_ensure_configured`](../../src/orchestrator/obs/tracing.py#L61) — reaches **20** symbols
- [`_NoopSpan`](../../src/orchestrator/obs/tracing.py#L52) — reaches **13** symbols
- [`span`](../../src/orchestrator/obs/tracing.py#L137) — reaches **12** symbols
- [`get_tracer`](../../src/orchestrator/obs/tracing.py#L110) — reaches **7** symbols
- [`temporal_interceptors`](../../src/orchestrator/obs/tracing.py#L116) — reaches **6** symbols
- [`add_event`](../../src/orchestrator/obs/tracing.py#L167) — reaches **4** symbols · **no test path visible**
- [`bind_trace_id`](../../src/orchestrator/obs/tracing.py#L208) — reaches **1** symbol

_1 of the symbols other code depends on here have no test path the graph can see — worth a second look before changing them. Absence of a path is not proof of absence of a test: calls through an attribute chain (`obj.method()`) are skipped rather than guessed at, so indirect coverage is invisible._

## Types

### `_NoopSpan`

[`src/orchestrator/obs/tracing.py:52`](../../src/orchestrator/obs/tracing.py#L52)

- **Called by** (1): [`span`](../../src/orchestrator/obs/tracing.py#L137)

### `_State`

[`src/orchestrator/obs/tracing.py:40`](../../src/orchestrator/obs/tracing.py#L40)

- **Fields**: `configured`, `provider`, `tracer`

## Functions

### `_ensure_configured`

[`src/orchestrator/obs/tracing.py:61`](../../src/orchestrator/obs/tracing.py#L61)

- **Called by** (4): [`add_event`](../../src/orchestrator/obs/tracing.py#L167), [`get_tracer`](../../src/orchestrator/obs/tracing.py#L110), [`is_enabled`](../../src/orchestrator/obs/tracing.py#L104), [`span`](../../src/orchestrator/obs/tracing.py#L137)
- **Calls** (5): `create`, `getenv`, `opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter`, `opentelemetry.sdk.trace.TracerProvider`, `opentelemetry.sdk.trace.export.BatchSpanProcessor`

### `add_event`

[`src/orchestrator/obs/tracing.py:167`](../../src/orchestrator/obs/tracing.py#L167)

- **Called by** (1): [`_process_calls`](../../src/orchestrator/agentic/loop.py#L353)
- **Calls** (2): [`_ensure_configured`](../../src/orchestrator/obs/tracing.py#L61), `get_current_span`

### `bind_trace_id`

[`src/orchestrator/obs/tracing.py:208`](../../src/orchestrator/obs/tracing.py#L208)

- **Called by** (1 production · 1 test): [`execute_graph_pass`](../../src/orchestrator/temporal/activities.py#L141), [`test_bound_trace_id_attached_as_join_key`](../../tests/obs/test_tracing.py#L92)
- **Documented in**: `docs/specs/README.md#3-gap-taxonomy-g1g17`, `docs/specs/live-observability-otel.md#design-live-observability-opentelemetry-over-the-existing-trace-id`, `docs/specs/live-observability-otel.md#layer-3-temporal-activities-the-cross-process-trace-live-verified`

### `configure_for_testing`

[`src/orchestrator/obs/tracing.py:223`](../../src/orchestrator/obs/tracing.py#L223)

- **Called by** (0 production · 6 test): [`exporter`](../../tests/agentic/test_loop_tracing.py#L21), [`test_bound_trace_id_attached_as_join_key`](../../tests/obs/test_tracing.py#L92), [`test_exception_marks_span_error`](../../tests/obs/test_tracing.py#L105), [`test_recording_client_emits_llm_span`](../../tests/obs/test_tracing.py#L124), [`test_span_tree_and_attributes`](../../tests/obs/test_tracing.py#L72), [`test_temporal_interceptors_present_when_enabled`](../../tests/obs/test_tracing.py#L39)
- **Calls** (4): `create`, `opentelemetry.sdk.trace.TracerProvider`, `opentelemetry.sdk.trace.export.SimpleSpanProcessor`, `opentelemetry.sdk.trace.export.in_memory_span_exporter.InMemorySpanExporter`

### `flush`

[`src/orchestrator/obs/tracing.py:217`](../../src/orchestrator/obs/tracing.py#L217)

- **Called by** (0 production · 7 test): [`test_bound_trace_id_attached_as_join_key`](../../tests/obs/test_tracing.py#L92), [`test_exception_marks_span_error`](../../tests/obs/test_tracing.py#L105), [`test_policy_block_recorded_as_span_event`](../../tests/agentic/test_loop_tracing.py#L79), [`test_recording_client_emits_llm_span`](../../tests/obs/test_tracing.py#L124), [`test_span_tree_and_attributes`](../../tests/obs/test_tracing.py#L72), [`test_step_and_tool_spans_nest`](../../tests/agentic/test_loop_tracing.py#L50), [`test_unknown_tool_span_marks_error`](../../tests/agentic/test_loop_tracing.py#L99)

### `get_tracer`

[`src/orchestrator/obs/tracing.py:110`](../../src/orchestrator/obs/tracing.py#L110)

- **Called by** (1): [`temporal_interceptors`](../../src/orchestrator/obs/tracing.py#L116)
- **Calls** (1): [`_ensure_configured`](../../src/orchestrator/obs/tracing.py#L61)

### `is_enabled`

[`src/orchestrator/obs/tracing.py:104`](../../src/orchestrator/obs/tracing.py#L104)

- **Called by** (0 production · 3 test): [`test_disabled_by_default_is_noop`](../../tests/obs/test_tracing.py#L28), [`test_endpoint_set_but_extra_missing_stays_disabled`](../../tests/obs/test_tracing.py#L53), [`test_span_tree_and_attributes`](../../tests/obs/test_tracing.py#L72)
- **Calls** (1): [`_ensure_configured`](../../src/orchestrator/obs/tracing.py#L61)

### `reset`

[`src/orchestrator/obs/tracing.py:244`](../../src/orchestrator/obs/tracing.py#L244)

- **Called by** (0 production · 8 test): [`_reset_tracing`](../../tests/obs/test_tracing.py#L17), [`exporter`](../../tests/agentic/test_loop_tracing.py#L21), [`test_bound_trace_id_attached_as_join_key`](../../tests/obs/test_tracing.py#L92), [`test_endpoint_set_but_extra_missing_stays_disabled`](../../tests/obs/test_tracing.py#L53), [`test_exception_marks_span_error`](../../tests/obs/test_tracing.py#L105), [`test_recording_client_emits_llm_span`](../../tests/obs/test_tracing.py#L124), [`test_span_tree_and_attributes`](../../tests/obs/test_tracing.py#L72), [`test_temporal_interceptors_present_when_enabled`](../../tests/obs/test_tracing.py#L39)

### `span`

[`src/orchestrator/obs/tracing.py:137`](../../src/orchestrator/obs/tracing.py#L137)

- **Called by** (8 production · 6 test): [`_dispatch`](../../src/orchestrator/agentic/loop.py#L444), [`_drive`](../../src/orchestrator/agentic/loop.py#L289), [`autorun`](../../src/orchestrator/sdlc/autorun.py#L237), [`awrapper`](../../src/orchestrator/obs/tracing.py#L191), [`complete`](../../src/orchestrator/core/llm/recording.py#L116), [`execute_graph_pass`](../../src/orchestrator/temporal/activities.py#L141), [`stage_span`](../../src/orchestrator/sdlc/autorun.py#L127), [`wrapper`](../../src/orchestrator/obs/tracing.py#L198), [`test_bound_trace_id_attached_as_join_key`](../../tests/obs/test_tracing.py#L92), [`test_disabled_by_default_is_noop`](../../tests/obs/test_tracing.py#L28), [`test_disabled_span_propagates_exceptions`](../../tests/obs/test_tracing.py#L64), [`test_endpoint_set_but_extra_missing_stays_disabled`](../../tests/obs/test_tracing.py#L53), [`test_exception_marks_span_error`](../../tests/obs/test_tracing.py#L105), [`test_span_tree_and_attributes`](../../tests/obs/test_tracing.py#L72)
- **Calls** (3): [`_NoopSpan`](../../src/orchestrator/obs/tracing.py#L52), [`_ensure_configured`](../../src/orchestrator/obs/tracing.py#L61), `opentelemetry.trace.Status`
- **Documented in**: `docs/specs/README.md#3-gap-taxonomy-g1g17`, `docs/specs/live-observability-otel.md#design-live-observability-opentelemetry-over-the-existing-trace-id`

### `temporal_interceptors`

[`src/orchestrator/obs/tracing.py:116`](../../src/orchestrator/obs/tracing.py#L116)

- **Called by** (1 production · 2 test): [`connect_client`](../../src/orchestrator/temporal/config.py#L61), [`test_temporal_interceptors_empty_when_disabled`](../../tests/obs/test_tracing.py#L35), [`test_temporal_interceptors_present_when_enabled`](../../tests/obs/test_tracing.py#L39)
- **Calls** (2): [`get_tracer`](../../src/orchestrator/obs/tracing.py#L110), `temporalio.contrib.opentelemetry.TracingInterceptor`
- **Documented in**: `docs/specs/README.md#3-gap-taxonomy-g1g17`, `docs/specs/live-observability-otel.md#design-live-observability-opentelemetry-over-the-existing-trace-id`, `docs/specs/live-observability-otel.md#layer-3-temporal-activities-the-cross-process-trace-live-verified`, `docs/specs/live-observability-otel.md#phasing`

### `traced`

[`src/orchestrator/obs/tracing.py:183`](../../src/orchestrator/obs/tracing.py#L183)

- **Documented in**: `docs/specs/README.md#3-gap-taxonomy-g1g17`, `docs/specs/live-observability-otel.md#design-live-observability-opentelemetry-over-the-existing-trace-id`

## Imports

`__future__.annotations`, `collections.abc.Callable`, `collections.abc.Iterator`, `contextlib`, `contextvars.ContextVar`, `functools`, `inspect`, `logging`, `opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter`, `opentelemetry.sdk.resources.Resource`, `opentelemetry.sdk.trace.TracerProvider`, `opentelemetry.sdk.trace.export.BatchSpanProcessor`, `opentelemetry.sdk.trace.export.SimpleSpanProcessor`, `opentelemetry.sdk.trace.export.in_memory_span_exporter.InMemorySpanExporter`, `opentelemetry.trace`, `opentelemetry.trace.Status`, `opentelemetry.trace.StatusCode`, `os`, `temporalio.contrib.opentelemetry.TracingInterceptor`, `typing.Any`

## Imported by

[`orchestrator.agentic.loop`](../../src/orchestrator/agentic/loop.py#L1), [`orchestrator.core.llm.recording`](../../src/orchestrator/core/llm/recording.py#L1), [`orchestrator.sdlc.autorun`](orchestrator.sdlc.autorun.md), [`orchestrator.temporal.activities`](../../src/orchestrator/temporal/activities.py#L1), [`orchestrator.temporal.config`](../../src/orchestrator/temporal/config.py#L1), [`tests.agentic.test_loop_tracing`](../../tests/agentic/test_loop_tracing.py#L1), [`tests.obs.test_tracing`](../../tests/obs/test_tracing.py#L1)
