Claude Code Telemetry
1. What? — Definition and context
Section titled “1. What? — Definition and context”Every time a Claude Code session starts on this project, a shell hook captures the context (branch, issue, repo) and forwards it to N8N. When the session ends, a second hook collects the Prometheus metrics (active time, cost, tokens, lines of code), reconstructs the branch segments traversed, and syncs everything to the matching Odoo tasks.
The result: every Odoo task shows the Claude time spent on it, the API cost, the number of tokens, and the lines changed — automatically, without manual entry.
Workflows in the system
Section titled “Workflows in the system”| Workflow | Nodes | Trigger | Role |
|---|---|---|---|
| Session Start | 4 | Webhook POST | Records the active session |
| Session End (main) | 30 | Webhook POST | Metrics + Odoo sync |
| Orphan Detection | ~20 | Schedule 12 h | Recovers crashed sessions |
| Session Categorizer | 17 | Sunday 11 PM | Categorises unsorted sessions |
| Session Metrics Updater | 7 | Webhook POST | Enriched update (backfill) |
End-to-end architecture
Section titled “End-to-end architecture”2. Why? — Stakes and motivations
Section titled “2. Why? — Stakes and motivations”Without telemetry, there is no way to know how much time and money Claude Code consumes per task. You know the tool was used, but not on what or for how much. For a freelancer billing time, that is a blind spot.
Problems solved
Section titled “Problems solved”| Problem | Without telemetry | With telemetry |
|---|---|---|
| Cost per task | Read it manually from the API console | USD cost per issue, per model |
| Time spent | Estimate from memory | Active time from Prometheus + Odoo timesheets |
| Attribution | ”I worked on the project” | Segments per branch, per issue |
| Lost sessions | Crash = data lost | Orphan Detection recovers metrics |
| Categorisation | dev branches without context | AI categorises into dev/docs/refactor/fix/test |
Metrics collected
Section titled “Metrics collected”| Metric | Source | Granularity |
|---|---|---|
| Active time (seconds) | Prometheus OTEL | Per session, per model |
| API cost (USD) | Prometheus OTEL | 4 decimals, per model |
| Tokens (input/output/cache) | Prometheus OTEL | Per type, per model |
| Lines added/removed | git log | Per commit |
3. How? — Technical implementation
Section titled “3. How? — Technical implementation”The SessionEnd hook
Section titled “The SessionEnd hook”This is the most complex hook. When Claude Code exits, it:
- Reads the state file written at start (frozen issue_id, timestamp)
- Rebuilds branch segments through
git reflog --since - Collects commits with
git log --since --all - Enriches each commit with its branch and matching issue
- Builds a TLDR (changed files, insertions, deletions, dominant type)
- Sends the enriched payload to N8N
The key point: the issue_id is frozen when the session starts. Even if the user switches branches mid-session, the system knows which task to attribute the work to.
Proportional split
Section titled “Proportional split”When a session crosses several branches (for example feature/176-fix for 40 minutes then dev for 20 minutes), metrics are split proportionally:
Total session: 60 minutes Branch feature/176: 40 min → 66% of metrics Branch dev: 20 min → 33% of metrics
If total cost = 0.15 USD: Issue #176 → 0.10 USD Branch dev → 0.05 USD (generic task)Generic tasks
Section titled “Generic tasks”Sessions without an issue (work on dev, main, or branches without a number) are routed to generic tasks: one per (repo + category) combination. The category is derived from the dominant commit type:
| Dominant commits | Category | Generic task |
|---|---|---|
| feat, chore | dev | ”Dev without issue (features & chores)“ |
| docs | docs | ”Documentation maintenance” |
| refactor | refactor | ”Refactoring” |
| fix | fix | ”Fixes (no issue)“ |
| test | test | ”Testing” |
Odoo fields synchronised
Section titled “Odoo fields synchronised”Each Odoo task receives 11 enriched fields automatically:
| Field | Type | Description |
|---|---|---|
x_claude_time_total | Float | Cumulative active hours |
x_claude_cost_total | Float | Cumulative USD cost |
x_claude_token_total | Integer | Cumulative tokens |
x_claude_sessions | Integer | Number of sessions |
x_claude_lines_added | Integer | Lines added |
x_claude_lines_removed | Integer | Lines removed |
x_claude_cost_by_model | JSON | Breakdown per model |
x_claude_tokens_input | Integer | Input tokens |
x_claude_tokens_output | Integer | Output tokens |
x_claude_tokens_cache | Integer | Cache tokens |
x_claude_last_session | Datetime | Last session |
Fields are cumulative: each session adds its metrics on top of those already on the task.
Orphan Detection
Section titled “Orphan Detection”Every 12 hours, a workflow checks whether sessions remain stuck in the active sessions table (a sign of a Claude Code crash). Sessions older than 6 hours are considered orphans.
The workflow fetches the Prometheus metrics (if still available — 15-day retention), saves them with status orphaned, and updates the matching Odoo task. Nothing is lost.
Weekly categorisation
Section titled “Weekly categorisation”Every Sunday at 11 PM, the Session Categorizer uses Claude to analyse uncategorised sessions. The AI receives a batch of sessions with their “topic” (first user message) and can:
- Assign a category (dev, docs, refactor, fix, test)
- Rename the Odoo task with a more descriptive name
- Re-link a session to an issue task if it was misattributed
4. What if? — Outlook and limits
Section titled “4. What if? — Outlook and limits”Current limits
Section titled “Current limits”| Limit | Impact | Mitigation |
|---|---|---|
| Prometheus 15-day retention | Metrics lost after 15 days | Saved into a Data Table at session end |
| No metrics per branch | Prometheus only knows session_id | Proportional split by segment duration |
| Shell hook only | Depends on bash and git | Scripts tested and shipped through scripts/claude-hooks/ |
Evolution scenarios
Section titled “Evolution scenarios”If a real-time dashboard is needed:
- Prometheus metrics already exist in Grafana
- Add a “Claude Code Sessions” dashboard with cost, tokens, and active sessions
- Alert if cost crosses a daily threshold
If multi-user support is required:
- Add a
user_idfield in the payload - Split costs per developer
- Comparative dashboard inside Odoo
If finer analysis is needed:
- Store full transcripts (only the “topic” is kept today)
- Analyse usage patterns: which prompts cost the most
- Optimise caches and model choice
Related pages
Section titled “Related pages”Infrastructure
Section titled “Infrastructure”- Monitoring Stack — Prometheus and Grafana
- AI Stack — CLI Ollama
Workflows
Section titled “Workflows”- GitHub-Odoo Sync — Odoo tasks synced from GitHub
- Global Error Handler — Error workflow for the telemetry pipeline
Reference
Section titled “Reference”- Glossary — OTEL, Prometheus, hook