Claude Code Observability: Track Every Tool Call, Token and Cost (2026)

See every prompt, tool call, token and dollar of your Claude Code sessions in one timeline, with one command and your privacy level.

On this page
  1. Why observe Claude Code at all
  2. What Claude Code exposes
  3. Option 1: wire it yourself
  4. Option 2: Voight in one command
  5. What you see
  6. Questions you can answer in a minute
  7. Troubleshooting

Claude Code reads files, runs shell commands, edits code and calls MCP tools on your behalf, sometimes for an hour at a time. When a session goes well you rarely ask what it did. When it goes badly (a surprising bill, a command you did not expect, a session that hangs) you need the full record: every prompt, every tool call, how long each one took and what it cost.

This guide shows what Claude Code exposes, how to capture it yourself, and how to get a complete timeline with one command.

Why observe Claude Code at all

  • Cost. Long sessions with big contexts add up, and cache reads and writes change the bill a lot. You want cost per session and per task, not just a monthly total.
  • What actually ran. Every Bash command, every file edit, every MCP call. Useful for reviews, for audits and for learning what the agent does well.
  • Why it got stuck. A tool call that started and never finished, a loop of failed edits, a compaction in the middle of a task.
  • Team visibility. When several people use Claude Code, a shared view answers "who is spending what, on which repo" without asking around.

What Claude Code exposes

Claude Code gives you two hooks into a session:

  1. Hooks. Shell commands that run on lifecycle events and receive a JSON payload. The useful ones for observability are UserPromptSubmit (a new prompt), PreToolUse and PostToolUse (before and after each tool call), Stop and SubagentStop (a response or subagent finished), Notification and PreCompact (the context is about to be compacted). Hooks live in ~/.claude/settings.json or in a project's .claude/settings.json.
  2. OpenTelemetry. Claude Code can also export metrics and events over OpenTelemetry when telemetry is enabled, which suits teams that already run a collector.

Every hook payload carries a session_id, so all events of one Claude Code launch can be grouped together.

Option 1: wire it yourself

The minimal do-it-yourself setup is a hook that appends each payload to a file:

JSON
{
  "hooks": {
    "PostToolUse": [
      { "hooks": [{ "type": "command", "command": "cat >> ~/claude-tool-calls.jsonl" }] }
    ]
  }
}

It works, and it is a good way to see the raw data. The limits show up quickly: you have to pair each PreToolUse with its PostToolUse to get durations, compute cost from token counts and per-model prices, scrub secrets from prompts and command output before they land anywhere shared, and build the views yourself. The OpenTelemetry route solves transport, not the views: you still need a backend and dashboards.

Option 2: Voight in one command

Voight is an observability and debugging platform for AI agents, and Claude Code is a first-class source. One command sets it up:

Terminal
npx -y @voightxyz/sdk setup

The wizard detects Claude Code (it also supports Cursor and Codex), asks for your privacy level and your Voight API key, and writes two things into ~/.claude/settings.json:

  • env.VOIGHT_KEY and env.VOIGHT_PRIVACY, so the key never lives in your shell profile.
  • Hooks on UserPromptSubmit, PreToolUse, PostToolUse, Stop, SubagentStop, Notification and PreCompact, each calling npx -y @voightxyz/sdk hook.

Restart Claude Code (hooks are read on startup) and the next session appears in the dashboard within seconds.

Choose a privacy level

LevelWhat leaves your machine
MinimalMetadata only: tool names, timings, tokens, cost. No prompts, responses, file paths or git context.
Standard (recommended)Full content, with credentials and personal data scrubbed locally before sending.
FullEverything as captured.

You can change the level later by running setup again, for example npx -y @voightxyz/sdk setup --privacy=standard.

Running setup from a script or another agent

If the terminal is not interactive (CI, or an agent running the command for you), setup works in three explicit steps:

Terminal
npx -y @voightxyz/sdk setup
npx -y @voightxyz/sdk setup --privacy=2
npx -y @voightxyz/sdk setup --privacy=2 --key=vk_YOUR_KEY

What you see

  • Sessions. One per Claude Code launch, grouped by day.
  • Traces. All the work for one ask, inside its session.
  • Tool calls as single rows. Each PreToolUse is paired with its PostToolUse, so every call shows its duration and outcome. A call that starts and gets no result for more than two minutes is flagged, which is how hung commands surface.
  • Tokens and cost on every event, with model tags and cache reads and writes counted separately.
  • A privacy chip on each event (MIN, STD or FULL), so you can confirm what was captured.
  • Issues and AI diagnosis. Failed runs are grouped into issues, and one click returns a root cause and a suggested fix you can hand back to Claude Code.

Questions you can answer in a minute

QuestionWhere to look
Why did yesterday cost so much?Cost per session, then per trace inside it
What commands did it run on this repo?The tool calls of the session, filtered by Bash
Why did the session hang?The flagged call that started and never finished
Did it touch anything sensitive?The audit log, with the privacy level of each event
Which tasks fail most often?The issue queue, ordered by frequency

Troubleshooting

  • No events in the dashboard. Check that ~/.claude/settings.json has env.VOIGHT_KEY and hooks calling npx -y @voightxyz/sdk hook, then restart Claude Code.
  • npx runs an old version. Run npx -y @voightxyz/sdk@latest --version, or clear the cache with rm -rf ~/.npm/_npx.
  • Prompts are not captured. You are on Minimal, which drops content by design. Run setup again with Standard.

See what your agents do. In one command.

Connect Claude Code, Codex or Cursor, or wrap your OpenAI and Anthropic clients. Traces show up in seconds.

npx -y @voightxyz/sdk setup