foley.obs.trace
The OpenTelemetry MIRROR seam for foley’s observability (#11).
foley’s reproducible run-artifact (the RunManifest)
is built by the recorder from its own clock + id-factory, independent of any
tracer — so a bare pip install foley still emits a complete manifest with zero
dependencies. This module is only the optional OpenTelemetry mirror: when the
foley[obs] extra is installed, foley additionally emits vendor-neutral OTel GenAI
spans (consumable by Langfuse / Datadog / Honeycomb / …); when it is not, a
stdlib NoOpTracer makes every instrumentation call a free no-op.
opentelemetry is imported lazily inside OTelTracer only, never at
module top level, so importing this module (and import foley) stays dol-only.
foley never configures an SDK / exporter — that is the host application’s job
(trace.set_tracer_provider(...)); until it does, even the OTel-backed tracer is a
free ProxyTracer no-op, so instrumentation is safe and ~zero-cost by default.
- foley.obs.trace.GENAI = {'data_source_id': 'gen_ai.data_source.id', 'error_type': 'error.type', 'finish_reasons': 'gen_ai.response.finish_reasons', 'input_tokens': 'gen_ai.usage.input_tokens', 'operation': 'gen_ai.operation.name', 'output_tokens': 'gen_ai.usage.output_tokens', 'provider': 'gen_ai.provider.name', 'request_model': 'gen_ai.request.model', 'response_model': 'gen_ai.response.model'}
The GenAI semantic-convention attribute keys foley emits. HARDCODED as strings on purpose — the
opentelemetry.semconv._incubatingconstants are Development- stability and shift across minor versions. This dict is the single place they are named.
- class foley.obs.trace.NoOpSpan[source]
A zero-cost span: every method does nothing;
trace_idis alwaysNone.
- class foley.obs.trace.NoOpTracer[source]
The default
Tracer— yields the shared_NOOP_SPAN, zero deps.
- class foley.obs.trace.OTelTracer[source]
An OpenTelemetry-backed
Tracer(lazy import; requiresfoley[obs]).
- class foley.obs.trace.Span(*args, **kwargs)[source]
The minimal mirror-span surface foley code calls (structural).
- class foley.obs.trace.Tracer(*args, **kwargs)[source]
Starts mirror spans; the DI seam (default no-op, OTel-backed when present).
- foley.obs.trace.get_tracer(*, prefer_otel: bool = True) Tracer[source]
Return the effective
Tracer(OTel-backed when available, else no-op).- Parameters:
prefer_otel – When
True(default) andopentelemetryis importable, return anOTelTracer(itself a free no-op until the host configures an SDK); any construction failure falls back to the no-op.Falseforces the stdlibNoOpTracer— the hermetic-test lever (this dev env may have otel).- Returns:
A
Tracer(never raises).