agents icon indicating copy to clipboard operation
agents copied to clipboard

feat: add opentelemetry instrumentation for tracing

Open marcklingen opened this issue 8 months ago • 5 comments

Context

I'm one of the maintainers of github.com/langfuse/langfuse. livekit is growing in popularity and I've gotten multiple requests by community members who'd like to get traces of their livekit applications in order to evaluate them.

Suggestion

I'd suggest to follow the example of the AI SDK (docs) by adding native Opentelemetry-based instrumentation to livekit. Thereby, the implementation is vendor-agnostic and teams can use an LLM-specific backend like Langfuse (tracing, evals, prompt management) or their traditional observability platforms (Grafana, Datadog, ...).

Potential addition next to traces: Exporting metrics (livekit docs) via OpenTelemetry would allow teams to easily track them within their observability stack.

Resources

  • https://opentelemetry.io/blog/2025/ai-agent-observability/
  • https://opentelemetry.io/docs/specs/semconv/gen-ai/
  • https://langfuse.com/docs/opentelemetry/get-started
  • https://github.com/orgs/langfuse/discussions/5235

marcklingen avatar Mar 26 '25 17:03 marcklingen

+1

sebhs avatar Apr 09 '25 09:04 sebhs

same here

ipv4sq avatar Apr 21 '25 17:04 ipv4sq

+1

timopetric avatar Apr 22 '25 10:04 timopetric

+1

initpwn avatar May 08 '25 06:05 initpwn

@marcklingen we'd love to get this integrated into the framework. will take a look at this

davidzhao avatar May 13 '25 00:05 davidzhao

+1

khantseithu avatar May 21 '25 06:05 khantseithu

+1

rohanmitra14 avatar May 29 '25 06:05 rohanmitra14

+1

Hey, we're going to work on it this month!

theomonnom avatar Jun 02 '25 19:06 theomonnom

Excited for it, ping me in case you have a preview. Would love to support this in a good state in Langfuse once this is available.

Side note: pipecat just released this. Might be interesting to check out their attribute mapping.

marcklingen avatar Jun 02 '25 23:06 marcklingen

+1

vishal-bluebash avatar Jun 14 '25 05:06 vishal-bluebash

+1

Trivedi-grv avatar Jun 17 '25 10:06 Trivedi-grv

+1

TomCC7 avatar Jun 18 '25 20:06 TomCC7

+1

isaaccs avatar Jun 25 '25 14:06 isaaccs

+1

xavphi avatar Jun 25 '25 15:06 xavphi

+1

danishshaik avatar Jun 25 '25 21:06 danishshaik

+1

us-asad avatar Jun 25 '25 22:06 us-asad

+1

Dramilio avatar Jun 29 '25 16:06 Dramilio

+1

ferreirapmartin avatar Jun 30 '25 16:06 ferreirapmartin

hello. any update regarding this

ShaheerCH avatar Jul 02 '25 17:07 ShaheerCH

+1

ma08 avatar Jul 03 '25 11:07 ma08

Hey team - any update on this?

nischalj10 avatar Jul 04 '25 06:07 nischalj10

we are working on it in https://github.com/livekit/agents/pull/2844, will be ready soon!

longcw avatar Jul 10 '25 07:07 longcw

+1

mubin986 avatar Jul 13 '25 10:07 mubin986

+1

romanpcloudx avatar Jul 17 '25 12:07 romanpcloudx

this feature is released with agents 1.2

longcw avatar Jul 18 '25 06:07 longcw

this feature is released with agents 1.2

Thanks for adding the opentelemetry support. I believe now the tracing will be easier than before with third party tools like Langfuse. Looking forward to their integration now!

mubin986 avatar Jul 18 '25 06:07 mubin986

Perfect but does this also work with Realtime. If an example could be provided that would be great.

ShaheerCH avatar Jul 18 '25 06:07 ShaheerCH

Perfect but does this also work with Realtime. If an example could be provided that would be great.

it works for realtime model, here is an example https://github.com/livekit/agents/blob/[email protected]/examples/voice_agents/langfuse_trace.py

longcw avatar Jul 18 '25 09:07 longcw

Thanks for the work on this! Is there any way to set metadata attributes such as a session ID? Usually you'd do this via start_as_current_span, but seems like that's called internally in LiveKit. The only option I'd see right now is implementing a custom span processor?

i.e. https://langfuse.com/docs/opentelemetry/example-python-sdk#flattened-attributes

Update: Implemented it using a basic custom span processor. Maybe there's a better way to do this though?

class CustomSpanProcessor(BatchSpanProcessor):
    def __init__(self, session_id: str, span_exporter):
        super().__init__(span_exporter)
        self.session_id = session_id

    # Called when span is started
    def on_start(self, span, parent_context=None):
        span.set_attribute("langfuse.session.id", self.session_id)
        super().on_start(span, parent_context)

def setup_langfuse(session_id: str):
    """Setup Langfuse tracing via OpenTelemetry."""

    # Ensure required environment variables are set
    langfuse_public_key = os.getenv("LANGFUSE_PUBLIC_KEY")
    langfuse_secret_key = os.getenv("LANGFUSE_SECRET_KEY")
    langfuse_host = os.getenv("LANGFUSE_HOST", "https://cloud.langfuse.com")

    if not langfuse_public_key or not langfuse_secret_key:
        logger.warning("Langfuse tracing is disabled: missing LANGFUSE_PUBLIC_KEY or LANGFUSE_SECRET_KEY")
        return

    # Create tracer provider
    provider = TracerProvider()

    # Configure the OTLP exporter
    credentials = base64.b64encode(f"{langfuse_public_key}:{langfuse_secret_key}".encode()).decode()
    os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = f"{langfuse_host.rstrip('/')}/api/public/otel"
    os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {credentials}"

    # Add batch span processor
    processor = CustomSpanProcessor(session_id=session_id, span_exporter=OTLPSpanExporter())
    provider.add_span_processor(processor)

    # Set the tracer provider
    trace.set_tracer_provider(provider)

    # Instrument libraries
    RequestsInstrumentor().instrument()
    URLLib3Instrumentor().instrument()
    HTTPXClientInstrumentor().instrument()

    logger.info("Langfuse tracing setup completed")

mfkrause avatar Jul 18 '25 10:07 mfkrause