This message was deleted.
# ask-ai
s
This message was deleted.
t
Thanks for reaching out, G.. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’m responding to your question about why
report.duration
is not always populated. Short answer •
duration
is only set when both the session start and end timestamps are recorded. If the session ends abnormally or teardown completes before the end timestamp is captured,
duration
will be empty. Why this happens (common causes) • Abrupt termination: an unhandled exception, process kill, or forced shutdown can prevent the session end timestamp from being recorded. • Early shutdown order / race condition: your shutdown callback may run before the session lifecycle finishes collecting metrics or before the
MetricsCollectedEvent
fires. • Custom teardown bypass: custom shutdown logic that skips normal cleanup can prevent the end-time being written. • Session never fully initialized: if the session never reached a “started” state (start timestamp missing), there’s nothing to pair with an end timestamp. What to check / quick debugging steps 1. Add logs for start and end timestamps: ◦ Log the session start time when the session begins and log session end time during shutdown so you can confirm both are present. 1. Verify the metrics event: ◦ Confirm the
MetricsCollectedEvent
(or equivalent) fires before shutdown and that
usageCollector.getSummary()
contains expected values. 1. Check shutdown ordering: ◦ Ensure
ctx.makeSessionReport(session)
runs after the session has fully started and before any shutdown routines that remove timestamps or stop metrics collection. 1. Look for exceptions or early exits: ◦ Inspect your logs for errors or exceptions prior to shutdown which might short-circuit normal teardown. 1. Reproduce with a controlled shutdown: ◦ Instrument a normal, clean shutdown path (no forced kills) and verify
duration
is populated. Then compare with failing runs to identify differences. If you’d like, I can help further — please share: • Whether you see start and/or end timestamps in your logs. • Any errors or stack traces around shutdown. • Whether shutdowns that produce no
duration
correspond to crashes/forced kills or to graceful shutdowns. I can then suggest targeted fixes (ordering changes, retrying metrics collection before shutdown, or adding guards to ensure end timestamps are recorded). Sources: Agents (Python) | livekit/livekit_composite | DeepWiki | Build a multilingual voice agent that automatically switches languages | Li... | Redacting PII from agent logs and transcripts | LiveKit | How to implement call greeting retries in voice agents | LiveKit
Thanks — I’m responding to your message showing the Usage log and your question about whether you need to enable anything for
duration
to be populated. Short answer • You don’t need to flip a separate flag to enable
duration
. It’s calculated from the session start and end timestamps, so it will only appear when both timestamps are recorded (i.e., when the session lifecycle completes normally). Why you’re seeing usage metrics but no
duration
• Component-level metrics like
sttAudioDurationMs
,
llmPromptTokens
, and
ttsCharactersCount
are being collected independently and can be present even if the session end timestamp is missing. •
duration
is missing because the session end timestamp wasn’t captured (for example: the session didn’t emit a proper end/close event, the process crashed or was killed before cleanup, or there’s a race where your shutdown runs before lifecycle completion). What to check next (quick checklist) 1. Confirm session start and end logs ◦ Log the exact session start time and the session end time in your code to verify whether the end timestamp is getting written. 1. Ensure proper session termination ◦ Make sure sessions call their normal end/close path (e.g.,
session.close()
or the equivalent) and that participants leave normally. 1. Verify metrics/metrics-collected ordering ◦ Ensure
MetricsCollectedEvent
(or other metrics-finalization step) fires before your shutdown callback runs. 1. Look for crashes or forced kills ◦ Check for unhandled exceptions, process terminations, or container restarts that could cut off normal teardown. 1. SDK version & observability ◦
duration
is part of standard session metadata. Confirm you’re on a current Agent SDK version and that observability is enabled for your project so lifecycle events are recorded. Helpful debugging steps you can add right now • Add explicit logging around lifecycle events: ◦ Log when the session starts, when you receive the metrics-collected event, and when your shutdown callback runs. • Temporarily delay shutdown in a controlled run to ensure metrics collection completes, e.g. wait a few seconds after
getSummary()
before exiting. • If you have separate shutdown logic, call
ctx.makeSessionReport(session)
only after you’ve confirmed the end timestamp exists. If you want, share any of the following and I’ll help narrow it down: • A short snippet showing where you call start/close for the session and where your shutdown callback runs. • Logs that include the session start, metrics-collected, and shutdown timestamps (if present). • Whether the cases with missing
duration
are graceful shutdowns or crashes/forced kills. I can then point out any ordering changes or small code guards to ensure the end timestamp is captured before the process exits. Sources: Agents (Python) | livekit/livekit_composite | DeepWiki | xAI Grok Voice Agent API plugin | LiveKit Documentation | Where to find your Agent Logs | LiveKit
You’re asking how to confirm whether the session end timestamp exists — good question. Below are concrete, easy checks and code examples you can add to verify the end timestamp is present so
duration
can be computed. What you want to verify • There are two timestamps: session start and session end.
duration
is computed only if both exist. • Confirming the end timestamp means: (A) the session emitted its end/close event, and (B) that timestamp was recorded before your report is generated. Steps to confirm the end timestamp exists 1) Log lifecycle events (start, metrics-collected, end) • Add logs at the exact points the session starts, when metrics are finalized, and when the session ends. This shows ordering and whether the end event happened. Example (Node-like pseudocode — adapt to your language):
Copy code
ctx.on('session_start', (session) => {
  <http://logger.info|logger.info>(`session_start: ${session.id} ts=${Date.now()}`);
});

ctx.on('metrics_collected', (session, metrics) => {
  <http://logger.info|logger.info>(`metrics_collected: ${session.id} ts=${Date.now()} metrics=${JSON.stringify(metrics)}`);
});

ctx.on('session_end', (session) => {
  <http://logger.info|logger.info>(`session_end: ${session.id} ts=${Date.now()}`);
});
2) Inspect the SessionReport fields directly before you return/exit • Call
ctx.makeSessionReport(session)
and log the report object. Check for
startTimestamp
,
endTimestamp
, and
duration
fields (field names may vary; log the whole report). Example:
Copy code
const report = ctx.makeSessionReport(session);
<http://logger.info|logger.info>(`Report raw: ${JSON.stringify(report)}`);
<http://logger.info|logger.info>(`start: ${report.startTimestamp}, end: ${report.endTimestamp}, duration: ${report.duration}`);
3) Add defensive checks and a short delay (for race conditions) • If the end timestamp is sometimes missing because metrics are still being finalized, add a short retry/delay before creating the report to allow final events to arrive. Example:
Copy code
// simple retry
for (let i = 0; i < 3; i++) {
  const report = ctx.makeSessionReport(session);
  if (report.endTimestamp) {
    <http://logger.info|logger.info>('end timestamp found');
    break;
  }
  await sleep(500); // wait 500ms then try again
}
4) Search your logs for the session ID • If your system logs a session id at start/end, search for that id and confirm there’s a line showing the session end timestamp. If you only find start but no end, the end event wasn’t recorded. 5) Check for abrupt termination / exceptions • If your process crashes or container is killed, the end timestamp won’t be recorded. Look for error logs, uncaught exceptions, SIGTERM/SIGKILL events, or container restarts around the missing-duration runs. 6) Verify metrics-collected event timing vs. shutdown callback • Ensure your shutdown callback doesn’t run before the metrics-collected (or equivalent) event. Log both and verify the metrics-collected log appears before your shutdown callback runs. If you prefer, I can help interpret your logs • Paste a few lines showing: ◦ the session start log, ◦ any metrics_collected/usage log you already have, ◦ and the shutdown/report logs. I’ll point out whether the end timestamp was recorded and where the ordering issue might be. Next steps I can help with • Show exact code to add retries or wait-for-metrics before calling
ctx.makeSessionReport
. • Suggest changes to shutdown ordering so report generation runs after metrics finalize. • Help identify crash/kill signatures in your logs if you share them.