Skip to main content

Logs, metrics, and telemetry

Collecting logs, metrics, and telemetry data from your agent for debugging and insights.

Overview

LiveKit Agents provides built-in support for logging, collecting, and analyzing metrics to help you monitor and optimize your agent's performance. Agent sessions emit structured metrics events that can be logged in real time or aggregated to analyze latency and usage patterns.

In addition to per-event metrics, LiveKit’s OpenTelemetry integration provides trace-based observability. This enables you to capture the execution flow of an agents's lifecycle—from session start to individual node operations. You can use any OpenTelemetry-compatible provider to collect and analyze telemetry data, giving you insight into conversation latency, tool usage, and performance bottlenecks.

For information on log levels, see the worker options page.

Logging events

Agent metrics events are fired by the AgentSession whenever there is a new metrics object available during an active session.

A log_metrics helper function is also provided to format logging output for each metric type.

from livekit.agents import metrics, MetricsCollectedEvent
...
@session.on("metrics_collected")
def _on_metrics_collected(ev: MetricsCollectedEvent):
metrics.log_metrics(ev.metrics)

Aggregating metrics

The metrics module also includes a UsageCollector helper class for aggregating usage metrics across a session. It tracks metrics such as LLM, TTS, and STT API usage, which can help estimate session cost.

from livekit.agents import metrics, MetricsCollectedEvent
...
usage_collector = metrics.UsageCollector()
@session.on("metrics_collected")
def _on_metrics_collected(ev: MetricsCollectedEvent):
usage_collector.collect(ev.metrics)
async def log_usage():
summary = usage_collector.get_summary()
logger.info(f"Usage: {summary}")
# At shutdown, generate and log the summary from the usage collector
ctx.add_shutdown_callback(log_usage)

Metrics reference

Diagram where metrics are measured.

Speech-to-text (STT)

STTMetrics is emitted after the STT model has processed the audio input. This metrics is only available when an STT component is used, which does not apply to Realtime APIs.

MetricDescription
audio_durationThe duration (seconds) of the audio input received by the STT model.
durationFor non-streaming STT, the amount of time (seconds) it took to create the transcript. Always 0 for streaming STT.
streamedTrue if the STT is in streaming mode.

LLM

LLMMetrics is emitted after each LLM inference completes. If the response includes tool calls, the event does not include the time taken to execute those calls. Each tool call response triggers a separate LLMMetrics event.

MetricDescription
durationThe amount of time (seconds) it took for the LLM to generate the entire completion.
completion_tokensThe number of tokens generated by the LLM in the completion.
prompt_tokensThe number of tokens provided in the prompt sent to the LLM.
prompt_cached_tokensThe number of cached tokens in the input prompt.
speech_idAn unique identifier representing a turn in the user input.
total_tokensTotal token usage for the completion.
tokens_per_secondThe rate of token generation (tokens/second) by the LLM to generate the completion.
ttftThe amount of time (seconds) that it took for the LLM to generate the first token of the completion.

Text-to-speech (TTS)

TTSMetrics is emitted after a TTS has generated speech from text input.

MetricDescription
audio_durationThe duration (seconds) of the audio output generated by the TTS model.
characters_countThe number of characters in the text input to the TTS model.
durationThe amount of time (seconds) it took for the TTS model to generate the entire audio output.
ttfbThe amount of time (seconds) that it took for the TTS model to generate the first byte of its audio output.
speech_idAn identifier linking to a user's turn.
streamedTrue if the TTS is in streaming mode.

End-of-utterance (EOU)

EOUMetrics is emitted when the user is determined to have finished speaking. It includes metrics related to end-of-turn detection and transcription latency.

This event is only available in Realtime APIs when turn_detection is set to either VAD or LiveKit's turn detector plugin. When using server-side turn detection, EOUMetrics is not emitted, as this information is not available.

MetricDescription
end_of_utterance_delayTime (in seconds) from the end of speech (as detected by VAD) to the point when the user's turn is considered complete. This includes any transcription_delay.
transcription_delayTime (seconds) between the end of speech and when final transcript is available
on_user_turn_completed_delayTime (in seconds) taken to execute the on_user_turn_completed callback.
speech_idA unique identifier indicating the user's turn.

Measuring conversation latency

Total conversation latency is defined as the time it takes for the agent to respond to a user's utterance. Given the metrics above, it can be computed as follows:

total_latency = eou.end_of_utterance_delay + llm.ttft + tts.ttfb

Telemetry

ONLY Available in
Python

LiveKit's OpenTelemetry integration automatically collects telemetry data from your agents and publishes it to any OpenTelemetry-compatible provider you choose. This enables monitoring and analysis of your agent's behavior and performance.

Collected data

A trace represents the execution flow of a single request within an LLM application. It captures all relevant steps, including duration and metadata.

Agent telemetry records traces for the following activities:

  • Session start
  • Agent turn
  • LLM node
  • Function tool
  • TTS node
  • End-of-turn detection
  • LLM and TTS metrics

Enabling telemetry

To enable telemetry, configure a tracer provider using set_tracer_provider in your entrypoint function. You can use any OpenTelemetry-compatible provider.

The following example uses LangFuse. Set the required public key, secret key, and host as environment variables:

import base64
import os
from livekit.agents.telemetry import set_tracer_provider
def setup_langfuse(
host: str | None = None, public_key: str | None = None, secret_key: str | None = None
):
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
public_key = public_key or os.getenv("LANGFUSE_PUBLIC_KEY")
secret_key = secret_key or os.getenv("LANGFUSE_SECRET_KEY")
host = host or os.getenv("LANGFUSE_HOST")
if not public_key or not secret_key or not host:
raise ValueError("LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, and LANGFUSE_HOST must be set")
langfuse_auth = base64.b64encode(f"{public_key}:{secret_key}".encode()).decode()
os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = f"{host.rstrip('/')}/api/public/otel"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {langfuse_auth}"
trace_provider = TracerProvider()
trace_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
set_tracer_provider(trace_provider)
async def entrypoint(ctx: JobContext):
setup_langfuse() # set up the langfuse tracer provider
# ...

Trace example

The following diagram shows a trace of an agent session with user turns.

Diagram showing a trace of an agent session with two user turns.

Example

For a full example, see the following in the LiveKit Agents GitHub repository.

LangFuse trace example

An example of an agent using LangFuse as the tracer provider.