jeevesagent.observability.tracing
=================================

.. py:module:: jeevesagent.observability.tracing

.. autoapi-nested-parse::

   Telemetry adapters.

   * :class:`NoTelemetry` — no-op default. Both methods do as little work as
     possible so wrapping every loop step in ``async with telemetry.trace(...)``
     has effectively zero cost when telemetry isn't configured.
   * :class:`OTelTelemetry` — OpenTelemetry-backed. Lazy SDK imports inside
     ``__init__``. Spans go to whatever ``TracerProvider`` is configured;
     metrics go to whatever ``MeterProvider`` is configured. Tests pass
     in-memory providers; production users wire up their exporters once at
     startup and the adapter inherits.

   Metric type dispatch is by suffix:

   * names ending in ``_ms``, ``_seconds``, or ``_bytes`` -> histogram
   * everything else -> counter

   That keeps the public interface a single :meth:`emit_metric` while still
   producing the right OTel instrument under the hood.



Classes
-------

.. autoapisummary::

   jeevesagent.observability.tracing.NoTelemetry
   jeevesagent.observability.tracing.OTelTelemetry


Module Contents
---------------

.. py:class:: NoTelemetry

   No-op telemetry. Very cheap; safe to call on every loop step.


   .. py:method:: emit_metric(name: str, value: float, **attrs: Any) -> None
      :async:



   .. py:method:: trace(name: str, **attrs: Any) -> collections.abc.AsyncIterator[jeevesagent.core.types.Span]
      :async:



.. py:class:: OTelTelemetry(*, tracer_provider: Any | None = None, meter_provider: Any | None = None, instrumentation_name: str = 'jeevesagent')

   OpenTelemetry-backed :class:`~jeevesagent.core.protocols.Telemetry`.


   .. py:method:: emit_metric(name: str, value: float, **attrs: Any) -> None
      :async:



   .. py:method:: trace(name: str, **attrs: Any) -> collections.abc.AsyncIterator[jeevesagent.core.types.Span]
      :async:



