Skip to content

symfonic.observability.otel.ports

ports

Facade-facing port into the optional OpenTelemetry runtime service.

The implementation remains in :mod:.exporter; this named port keeps the facade compiler dependent on the service entry surface rather than its internals, as required by the layer dependency matrix.

OTelExporterHandles dataclass

OTelExporterHandles(callback_bridge: CallbackBridge, framework_bridge: FrameworkBridge, tracer: OTelTracer)

Bundle of references the engine wires into its registration sites.

The engine prepends callback_bridge to per-invocation callback lists, hands framework_bridge to the framework-hook dispatcher, and keeps tracer for the start_run_span context manager plus shutdown on agent close.

register_into

register_into(*, callback_handlers: list[CallbackHandler], framework_hooks: list[Any]) -> None

Append the two bridges to their respective registration sites.

Both lists are mutated in place. The engine owns the lists, so the exporter does not need to track membership separately. Tests can verify wiring by inspecting the lists after construction.

Source code in src/symfonic/observability/otel/exporter.py
def register_into(
    self,
    *,
    callback_handlers: list[CallbackHandler],
    framework_hooks: list[Any],
) -> None:
    """Append the two bridges to their respective registration sites.

    Both lists are mutated in place. The engine owns the lists, so
    the exporter does not need to track membership separately. Tests
    can verify wiring by inspecting the lists after construction.
    """
    callback_handlers.append(self.callback_bridge)  # type: ignore[arg-type]
    framework_hooks.append(self.framework_bridge)

build_if_enabled

build_if_enabled(config: Any) -> OTelExporterHandles | None

Convenience wrapper: return handles when config.otel_enabled.

Used by SymfonicAgent.__init__ so the engine site stays a single-line statement. When otel_enabled is False this function returns None without touching any module under symfonic.observability.otel.tracer/etc, preserving the zero-cost invariant.

Source code in src/symfonic/observability/otel/exporter.py
def build_if_enabled(config: Any) -> OTelExporterHandles | None:
    """Convenience wrapper: return handles when ``config.otel_enabled``.

    Used by ``SymfonicAgent.__init__`` so the engine site stays a
    single-line statement. When ``otel_enabled`` is False this function
    returns ``None`` **without** touching any module under
    ``symfonic.observability.otel.tracer``/etc, preserving the zero-cost
    invariant.
    """
    if not getattr(config, "otel_enabled", False):
        return None
    endpoint = getattr(config, "otel_endpoint", None)
    service_name = getattr(config, "otel_service_name", "symfonic")
    capture_prompts = getattr(config, "otel_capture_prompts", False)
    span_exporter = getattr(config, "_otel_test_span_exporter", None)
    use_batch_processor = getattr(config, "_otel_test_use_batch", None)
    return OTelExporter.build(
        endpoint=endpoint,
        service_name=service_name,
        capture_prompts=capture_prompts,
        span_exporter=span_exporter,
        use_batch_processor=use_batch_processor,
    )