agents
agents copied to clipboard
feat: add opentelemetry instrumentation for tracing
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
+1
same here
+1
+1
@marcklingen we'd love to get this integrated into the framework. will take a look at this
+1
+1
+1
Hey, we're going to work on it this month!
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.
+1
+1
+1
+1
+1
+1
+1
+1
+1
hello. any update regarding this
+1
Hey team - any update on this?
we are working on it in https://github.com/livekit/agents/pull/2844, will be ready soon!
+1
+1
this feature is released with agents 1.2
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!
Perfect but does this also work with Realtime. If an example could be provided that would be great.
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
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")