Skip to content

Agent and LLM Observability

The Agent layer is the core of LLM intelligence, including Turn execution flow, LLM calls, token management, context compression, Sub-Agent orchestration, and more. These logs help you understand the Agent’s decision-making process and resource consumption.

EventTriggerKey Fields
[turnagent] llm.completeLLM call completedsession_id, turn_id, model, input_tokens, output_tokens, cached_read_tokens, cached_write_tokens, reasoning_tokens, total_tokens, cost_micros
[turnagent] token_callback.compression_approachingToken usage approaching compression thresholdsession_id, usage_ratio
[turnagent] cache hit rate below thresholdCache hit rate below thresholdhit_rate, threshold
llm.http.requestLLM HTTP request sent (payload log)method, url, host
llm.http.response (stream complete)LLM streaming response completed (payload log)url, total_bytes, stream_complete
llm.http.errorLLM request failed (payload log)url, error

Note: Each LLM call may produce two llm.complete log entries — one with full token statistics (with model) and one with incremental statistics (model is empty). When investigating token consumption, focus on the entry that includes the model.

EventTriggerKey Fields
[turnagent] compact.startCompression startedsession_id, turn_id
[turnagent] compact.completedCompression completedsession_id, messages_before, messages_after, tokens_saved
[turnagent] compact.reestimateRe-estimate token countsession_id, old_tokens, new_tokens
[turnagent] compress.completedContext compression completedsession_id, turn_id, messages_compressed
[turnagent] summarize.threshold_fallbackSummarization threshold fallbacksession_id, threshold
[turnagent] summarize.llm_token_usageSummarization LLM token consumptioninput_tokens, output_tokens
[turnagent] summarize.llm_completeSummarization LLM call completed-
[turnagent] reactive_compact.startReactive compression startedsession_id, turn_id, reason
EventTriggerKey Fields
[session_memory_extractor] extractor.startMemory extraction startedsession_id, message_count
[session_memory_extractor] extractor.doneMemory extraction completedsession_id, memory_tokens
[session_memory_extractor] extractor.skip_threshold_not_metExtraction threshold not metsession_id, token_count, threshold
[triggerSessionMemoryExtraction] extractedMemory extraction successfulsession_id, memory_tokens
save_session_memory.successSession memory extracted successfully (background agent)session_id, memory_tokens
saveMemory.successUser memory saved successfullyuser_id, memory_id, category, importance
tool.webSearch.completedWeb search completedsession_id, query, result_count, provider
tool.webFetch.completedWeb fetch completedsession_id, url, bytes, status_code, cached
EventTriggerKey Fields
[turnagent] handleStreamEnd.startStream response end processing startedturn_id, session_id, role, token_usage_total, markdown_finalized, thinking_finalized
[turnagent] handleStreamEnd.update_token_usageUpdate token usageturn_id, session_id, input_tokens, output_tokens
[turnagent] appendStreamChunk.finalizeStream chunk final mergemessage_id, kind (thinking/markdown), chunk_count, full_content_len, full_content_preview
[turnagent] on_agent_events.startAgent event processing startedsession_id, turn_id
[turnagent] on_agent_events.doneAgent event processing completedsession_id, turn_id
[turnagent] on_agent_events.interruptedAgent event processing interruptedsession_id, turn_id, num_contexts
EventTriggerKey Fields
[turnagent] gen_input.startLLM input generation startedsession_id, turn_id, checkpoint_id, item_count, is_resume
[turnagent] gen_resume.calledResume parameters generatedturn_id, session_id, checkpoint_id, interrupted_count, unhandled_count, newItems_count
[turnagent] gen_resume.resume_paramsResume parameter detailsturn_id, session_id, interrupt_id, has_result
[turnagent] gen_resume.resultResume resultturn_id, session_id, consumed_count, has_resume_params
[turnagent] normalizeMessagesForLLM.appliedMessage sequence normalizedsession_id, before, after
EventTriggerKey Fields
[turnagent] session_manager.createdSession manager createdsession_id, turn_id, worker_id
[turnagent] session_manager.cleanup_doneSession manager cleanup completedsession_id, turn_id
EventTriggerKey Fields
notificationMessage.createdNotification message created (e.g., Loop triggered)session_id, text_len
[primitives.CreateMessage]Message persistedid, session, turn, role, content_type
EventTriggerKey Fields
[turnagent] subAgent.createdSub-Agent createdsub_agent_session_id, parent_session_id, mode
[turnagent] subAgent.work_submittedSub-Agent task submittedsub_agent_session_id, turn_id
[turnagent] subAgent.async.returned_immediatelyAsync Sub-Agent returned immediatelysub_agent_session_id
[turnagent] subAgent.resume.completedSub-Agent resume completedsub_agent_session_id
[turnagent] stopSubAgent.stoppedSub-Agent stoppedsub_agent_session_id
[turnagent] stopSubAgent.completedSub-Agent cleanup completedsub_agent_session_id
[turnagent] resumeParentAfterSubAgent.doneParent Session resume completedparent_session_id
[turnagent] notifyParentAfterAsyncSubAgent.doneAsync Sub-Agent notifies parent Sessionparent_session_id
EventTriggerKey Fields
[turnagent] createTools.doneAgent tools createdsession_id, tool_count
[turnagent] createAgent.startAgent creation startedsession_id, turn_id
[turnagent] createAgent.doneAgent creation completedsession_id, turn_id
[turnagent] createAgent.failedAgent creation failedsession_id, error
[turnagent] todoWriteTool.publish_updateTodo tool update publishedsession_id, turn_id
{service="server"} | json input_tokens="input_tokens", output_tokens="output_tokens" | msg="[turnagent] llm.complete"
{service="server"} | json session_id="session_id", usage_ratio="usage_ratio" | msg="[turnagent] token_callback.compression_approaching"
{service="server"} | json session_id="session_id" | msg=~"\\[turnagent\\] (compact\\.(start|completed|reestimate)|compress\\.completed|reactive_compact\\.start)" | session_id="session-abc"
{service="server"} | json tokens_saved="tokens_saved" | msg="[turnagent] compact.completed"
{service="server"} | json session_id="session_id", memory_tokens="memory_tokens" | msg=~"\\[session_memory_extractor\\] extractor\\.(start|done)|\\[triggerSessionMemoryExtraction\\] extracted"
{service="server"} | json hit_rate="hit_rate", threshold="threshold" | msg="[turnagent] cache hit rate below threshold"
{service="server"} | json sub_agent_session_id="sub_agent_session_id" | msg=~"\\[turnagent\\] (subAgent\\.(created|work_submitted|resume\\.completed|async\\.returned_immediately)|stopSubAgent\\.(stopped|completed))"
{service="server"} | json | msg=~"\\[turnagent\\] (subAgent|stopSubAgent|resumeParentAfterSubAgent|notifyParentAfterAsyncSubAgent)\\..*(failed|error)"
{service="server"} | json session_id="session_id", error="error" | msg="[turnagent] createAgent.failed"
{service="server"} | json | msg="llm.http.error"
{service="server"} | json provider="provider", model="model" | msg="LLM initialized"
{service="server"} | msg="LLM not configured"
{service="server"} | json chunk_count="chunk_count", full_content_len="full_content_len", kind="kind" | msg="[turnagent] appendStreamChunk.finalize"

View LLM Call Token Details (Including Cache Hits)

Section titled “View LLM Call Token Details (Including Cache Hits)”
{service="server"} | json model="model", input_tokens="input_tokens", output_tokens="output_tokens", cached_read_tokens="cached_read_tokens", reasoning_tokens="reasoning_tokens", cost_micros="cost_micros" | msg="[turnagent] llm.complete" | model!=""
{service="server"} | json session_id="session_id", turn_id="turn_id", num_contexts="num_contexts" | msg="[turnagent] on_agent_events.interrupted"

View Message Normalization (Context Trimming)

Section titled “View Message Normalization (Context Trimming)”
{service="server"} | json session_id="session_id", before="before", after="after" | msg="[turnagent] normalizeMessagesForLLM.applied"

View Resume Parameters (Troubleshoot RTC Interrupt Recovery)

Section titled “View Resume Parameters (Troubleshoot RTC Interrupt Recovery)”
{service="server"} | json turn_id="turn_id", interrupt_id="interrupt_id", has_result="has_result" | msg="[turnagent] gen_resume.resume_params"
{service="server"} | json session_id="session_id", text_len="text_len" | msg="notificationMessage.created"

Trace the Full Agent Execution Chain for a Session

Section titled “Trace the Full Agent Execution Chain for a Session”
{service="server"} | json session_id="session_id", msg="msg" | msg=~"\\[turnagent\\] (agent\\.process|createTurn|beginTurn|turn\\.(start|end)|llm\\.complete|on_agent_events|session_manager)" | session_id="session-abc"
MetricTypeLabelsPurpose
rtc_llm_tokens_totalCountermodel, type (input/output)Total LLM token consumption
rtc_llm_request_duration_secondsHistogrammodel, statusLLM API latency
rtc_llm_http_request_totalCounter-Total LLM HTTP requests
rtc_llm_http_request_duration_secondsHistogram-LLM HTTP request latency
rtc_llm_http_response_tokens_totalCounter-LLM HTTP response token count
# Token consumption rate per minute
sum by (model, type) (rate(rtc_llm_tokens_total[5m]))
# LLM API latency P95
histogram_quantile(0.95, sum(rate(rtc_llm_request_duration_seconds_bucket[5m])) by (le, model))
# LLM request error rate
sum(rate(rtc_llm_request_duration_seconds_count{status="error"}[5m])) / sum(rate(rtc_llm_request_duration_seconds_count[5m]))

In addition to structured logs and Prometheus metrics, the Agent layer automatically creates OpenTelemetry Spans for key operations, enabling you to view complete call chains in tracing backends like Grafana Tempo.

💡 All structured logs are automatically injected with trace_id and span_id (from the OpenTelemetry context), allowing you to correlate logs with Spans via Trace ID. See Common Log Query Patterns — Query by Trace ID for details.

Span NameTriggerKey Attributes
tool.searchMemorysearchMemory tool callquery, limit, result_count
tool.saveMemorysaveMemory tool callcategory, importance
tool.updateMemoryupdateMemory tool callmemory_id
tool.deleteMemorydeleteMemory tool callmemory_id
tool.listMemorieslistMemories tool call—
tool.webSearchwebSearch tool callquery, provider, result_count
tool.webFetchwebFetch tool callurl, cached
tool.subAgentsubAgent tool callmode
tool.stopSubAgentstopSubAgent tool call—
tool.createGoalcreateGoal tool call—
tool.todoWritetodoWrite tool call—
rtcTool.<name>RTC tool calls (ls/read/write/grep/find/script, etc.)tool_name
goalWorkflow.onTurnCompleteGoal workflow turn check—
loopWorkflow.onTurnCompleteLoop workflow progress check—
loopWorkflow.scheduleNextLoop scheduling next execution—
gorm.*All SQL operations (GORM tracing plugin)SQL statements, affected rows
centrifuge-plus.*Centrifuge publish/subscribe operationschannel, offset, queue

📌 OpenTelemetry tracing is enabled in production by configuring a TracerProvider. When not configured, a no-op tracer is used with zero overhead.

AlertConditionDescription
High LLM error rateLLM request error rate > 5%LLM service is unstable
Excessive token consumptionrate(rtc_llm_tokens_total[5m]) abnormally highPossible context leak
Low cache hit ratecache hit rate below threshold appears frequentlyAutoCacheControl may have failed

💡 For a complete list of Prometheus metrics, Grafana dashboards, and alert rules, see Monitoring & Observability.