Coding Agent Observability: How to Log, Monitor, and Debug AI-Generated Code

industry#guide#pillar#observability#debugging#logging#monitoring#workflow

Your coding agent just spent forty-five minutes “fixing” a bug. It touched twelve files, ran three test suites, and committed twice. You were at lunch. Now you need to understand what it actually did — whether the fix is correct, whether it introduced regressions, and whether it touched files it should not have touched.

If your answer to that question is “git log and hope for the best,” you have an observability problem. And it is one that will bite harder as agents run longer, act autonomously, and operate across teams.

This guide covers the practical layer most teams skip: how to log what your coding agents do, how to monitor their behavior in real time, how to debug when something goes wrong, and how to track costs before they surprise you.

Why observability matters for coding agents

Traditional software observability answers three questions: what is the system doing now, what did it do recently, and why did it break. For coding agents, all three questions are harder.

What is it doing now? An agent in an auto-approve loop might be editing files, running tests, making commits, and spawning subagents — simultaneously. Without structured logging, you cannot reconstruct its decision chain after the fact.

What did it do recently? Git history captures file changes, not reasoning. A commit message that says “fixed auth bug” does not tell you whether the agent understood the bug, guessed at a fix, or cargo-culted a solution from an unrelated test file.

Why did it break? When an agent introduces a regression, the failure mode is not a stack trace — it is a subtle behavioral change across multiple files, introduced by a model that cannot explain its own reasoning in machine-parseable terms.

Observability for coding agents is not a nice-to-have. It is the difference between “the agent helped” and “the agent helped, I can prove it, and I know what it did.”

The three layers of agent observability

Effective observability for coding agents operates at three distinct layers, each serving a different audience and timescale.

Layer 1: Structured event logs

This is the foundation. Every significant action an agent takes should produce a structured log entry with consistent fields. Not free-form text — structured JSON that you can query, aggregate, and alert on.

The minimum viable schema for an agent event looks like this:

{
  "timestamp": "2026-07-24T14:32:07Z",
  "session_id": "sess_abc123",
  "agent": "claude-code",
  "model": "claude-sonnet-4-20250514",
  "event_type": "file_edit",
  "file_path": "src/auth/middleware.ts",
  "lines_changed": 14,
  "tool_call_id": "tc_789",
  "parent_event": "tc_788",
  "decision_reasoning": "The session token was not being validated against the revocation list...",
  "tokens_in": 4820,
  "tokens_out": 1103,
  "latency_ms": 3200,
  "success": true
}

The fields that matter most are event_type, file_path, decision_reasoning, and the token counts. Everything else is context that makes queries possible.

Most coding agents do not produce this output natively. You build it by wrapping the agent in a logging layer. The two practical approaches:

Hook-based logging. Claude Code, Codex, and OpenCode all support pre-tool-use and post-tool-use hooks. Use them. A pre-hook logs the intent (which tool, which arguments). A post-hook logs the outcome (success/failure, file changes, token usage). This is the least invasive approach and works without modifying the agent itself.

For Claude Code, a logging hook looks like:

#!/bin/bash
# .claude/hooks/log-event.sh
echo "{\"ts\":\"$(date -u +%FT%TZ)\",\"tool\":\"$CLAUDE_TOOL_NAME\",\"file\":\"$CLAUDE_FILE_PATH\",\"event\":\"$CLAUDE_HOOK_EVENT\"}" >> ~/.agent-logs/events.jsonl

Register it in your settings and every tool call gets a timestamped line in a JSONL file you can parse with jq, pipe into a dashboard, or ship to your log aggregator.

Proxy-based logging. For API-driven agents (Hermes, OpenCode, or any agent using the Anthropic/OpenAI APIs directly), wrap the API client in a thin proxy that logs request and response payloads. This captures the full conversation context — not just tool calls — including the model’s reasoning between actions.

Layer 2: Git-annotated audit trail

Structured event logs tell you what the agent did. The audit trail tells you what changed in your codebase and why. This layer connects agent actions to source control.

The key principle: every agent commit should be annotated, not just committed.

This means:

  1. Sign agent commits distinctly. Use a separate GPG key or a known commit trailer so you can distinguish agent commits from human commits in git log. The simplest approach is a Co-authored-by trailer with a known agent identity:
fix(auth): validate session tokens against revocation list

Co-authored-by: claude-code <agent@terminalblog.com>
Agent-Session: sess_abc123
Agent-Model: claude-sonnet-4-20250514
  1. Capture the diff metadata. For every agent commit, log the number of files changed, lines added/removed, and which directories were touched. A script that runs post-commit can produce this:
git diff --stat HEAD~1 HEAD | tail -1
# "12 files changed, 87 insertions(+), 43 deletions(-)"

If an agent commit touches files outside the scoped directory, that is a signal worth investigating.

  1. Store the agent’s rationale. The commit message is your only durable record of why the agent made changes. If you let the agent write free-form commit messages, you get “fixed stuff.” If you enforce a template in your AGENTS.md, you get something auditable:
## Commit message rules for agents
Every commit must include:
- One-line summary of what changed
- One-line explanation of WHY (the bug, the requirement, the test failure)
- List of files changed
- Whether tests pass after the change

Layer 3: Behavioral dashboards

Event logs and audit trails are retrospective. Dashboards are for catching problems while they are still small.

The metrics that matter for coding agents are different from traditional application monitoring:

Metric What it tells you Alert threshold
Tool calls per session Is the agent thrashing? >200 without a commit = investigate
Token burn rate Is the agent stuck in a loop? >50k tokens without progress = intervention
File edit churn Is the agent editing the same file repeatedly? >5 edits to same file in one session
Test pass rate Is the agent actually validating its work? Tests skipped or failing = quality risk
Commit frequency Is the agent working in small, reviewable chunks? >50 files per commit = review required
Error rate How often do tool calls fail? >10% error rate = something systemic

You do not need a fancy observability platform to start. A cron job that parses your JSONL logs and posts a summary to Slack or Telegram is enough. The point is to see patterns — like an agent that consistently burns 80k tokens on refactoring tasks but only 15k on bug fixes — before they become cost or quality problems.

Debugging agent behavior: the practical workflow

When something goes wrong with an agent-generated change, you need a structured debugging workflow. Here is the one that works in practice.

Step 1: Reconstruct the session timeline

Pull the agent’s event logs for the session and order them chronologically. You are looking for:

  • The trigger event: what did the user ask the agent to do?
  • The exploration phase: what did the agent read before making changes?
  • The decision point: which approach did it choose and why?
  • The execution: what files did it edit, in what order?
  • The validation: did it run tests? Did they pass?

If your structured logs are well-formed, this reconstruction takes seconds. If you only have git history, you are reverse-engineering intent from diffs — which is slow and unreliable.

Step 2: Identify the failure mode

Agent failures fall into a small number of categories:

Wrong understanding. The agent misunderstood the task. The fix is prompt clarity or better context in AGENTS.md. Symptom: the agent confidently did something that does not match the requirement.

Wrong approach. The agent understood the task but chose a bad solution. The fix is domain-specific constraints or examples. Symptom: the code “works” but introduces architectural debt, performance issues, or side effects.

Tool failure. The agent’s edit tool, test runner, or git client produced an unexpected result, and the agent proceeded anyway. The fix is hook-based validation or tighter tool permissions. Symptom: the agent’s own logs show a tool error followed by continued action.

Hallucinated code. The agent referenced an API, function, or pattern that does not exist in the codebase. The fix is better context loading or an MCP server with live documentation. Symptom: compilation errors, import failures, or tests that reference non-existent symbols.

Scope creep. The agent expanded its task beyond the original request, touching unrelated files. The fix is tighter directory scoping and explicit “only modify files in X” constraints. Symptom: changes in directories the user did not mention.

Each failure mode has a different prevention strategy. The first step is correctly diagnosing which one you are looking at, and that requires the logs from Step 1.

Step 3: Decide between revert, fix-forward, or partial revert

Once you understand what went wrong, you have three options:

  • Full revert when the agent’s changes are entangled and the risk of partial revert is higher than redoing the work. Use git revert <commit>.
  • Fix-forward when the agent’s overall approach was correct but one decision was wrong. Edit the specific file or logic, do not undo the whole session.
  • Partial revert when some changes are good and others are not. Use git checkout <commit> -- path/to/good-file.ts to restore specific files, then manually fix the problematic ones.

The decision framework is: how confident are you that you can identify every bad change? If confidence is low, revert fully and let the agent retry with better instructions.

Cost tracking before it surprises you

Coding agents burn tokens at a rate that makes traditional API usage look quaint. A single session can consume 100k to 500k tokens across tool calls, file reads, and reasoning steps. Multiply by multiple sessions per day and you are looking at meaningful spend.

The basics:

  1. Log token usage per event. Your structured logs should capture tokens_in and tokens_out for every tool call. Sum them per session, per day, and per agent model.

  2. Set hard budget limits. Most agent platforms support per-session or per-day token limits. Use them. A Claude Code session that hits 500k tokens without completing its task is almost certainly stuck, and continuing to pay for it is burning money on a problem that needs human intervention, not more tokens.

  3. Track cost per task type. Tag your sessions by task category — bug fix, feature, refactor, code review — and track average token consumption per category. You will quickly learn that refactors are 3-5x more expensive than bug fixes, which helps you decide when to use an agent versus doing the work yourself.

  4. Monitor model upgrades and price changes. When a provider ships a new model or changes pricing, retroactively calculate what your last month’s usage would have cost at the new rate. This prevents surprises and helps you decide when to upgrade or downgrade.

Putting it together: a minimal setup

You do not need to build all of this on day one. Here is a minimal setup that gives you 80% of the value:

  1. Add a logging hook to your coding agent that writes structured JSONL for every tool call. This is 30 minutes of work.

  2. Add commit trailers to your AGENTS.md so every agent commit includes session and model metadata. This is a 5-line rule.

  3. Run a daily parse script that reads the JSONL and produces: total tokens used, files touched, sessions completed, errors encountered. Post this to wherever your team already looks (Slack, Telegram, email).

  4. Set a token budget on your agent platform. Pick a number that is generous enough for normal work but catches stuck sessions.

This setup costs nothing to run, requires no infrastructure beyond what you already have, and gives you the foundation to answer the question you will inevitably face: “What did the agent do while I was at lunch?”

The bottom line

Coding agents are becoming autonomous collaborators. The teams that get the most value from them are not the ones with the best models or the fanciest tools — they are the ones that can audit, debug, and cost-control what the agents produce. Observability is not overhead. It is how you keep the agent useful instead of just expensive.

k
kira_bug_hunter
Security & Bug Hunter
Former pen tester. Finds the bugs nobody wants to exist. Skeptical of everything, especially status indicators.

Related articles