Skip to content

Feature: Session Analytics & Metrics via Claude Code OpenTelemetry #136

@dhilgaertner

Description

@dhilgaertner

Context

Claude Code has a comprehensive OpenTelemetry telemetry system that exports metrics, events, and traces. Crow already orchestrates Claude Code sessions — we should tap into this telemetry to surface analytics and metrics directly in the Crow UI.

What Claude Code Exposes

Metrics (time-series via OTel Metrics)

Metric What it tells us
claude_code.cost.usage Cost in USD per API request (by model)
claude_code.token.usage Token counts by type: input, output, cacheRead, cacheCreation (by model)
claude_code.active_time.total Active time in seconds (user interaction vs CLI processing)
claude_code.lines_of_code.count Lines added/removed
claude_code.commit.count Git commits created
claude_code.pull_request.count PRs created
claude_code.session.count Session starts
claude_code.code_edit_tool.decision Accept/reject counts for Edit/Write tools

Events (via OTel Logs)

Event What it tells us
claude_code.user_prompt Each user prompt (length, optional content)
claude_code.tool_result Tool name, success/failure, duration_ms, error details
claude_code.api_request Model, cost_usd, duration_ms, token breakdown, fast/normal mode
claude_code.api_error Error messages, status codes, retry attempts
claude_code.tool_decision Permission accept/reject with source

Traces (beta — via OTel Traces)

Full distributed traces linking user prompts → API requests → tool executions as spans, giving a complete request waterfall.

Key Attributes Available on All Data

  • session.id — maps directly to a Crow session
  • user.account_uuid / user.email — user identity
  • organization.id — org-level grouping
  • model — which Claude model was used
  • prompt.id — correlates all events from a single user prompt

Brainstorm: How Crow Could Use This

1. Embedded OTel Collector

Crow could run a lightweight OTel collector (or just an OTLP HTTP receiver) that Claude Code sessions export to. Crow would set the env vars when launching each session:

CLAUDE_CODE_ENABLE_TELEMETRY=1
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:{crow_port}

Since Crow already controls how Claude Code is launched (via crow new-terminal + crow send), injecting these env vars is straightforward.

2. Per-Session Dashboard

Map session.id to Crow session UUIDs. Show per-session:

  • Cost: running total and cost-per-prompt sparkline
  • Tokens: input/output/cache breakdown (pie or stacked bar)
  • Active time: wall clock vs active time
  • Tool usage: most-used tools, success rates, avg execution time
  • Lines changed: additions vs removals over time
  • Commits / PRs: count with links

3. Cross-Session Analytics

Aggregate across sessions for a higher-level view:

  • Daily/weekly cost trends across all sessions
  • Model usage distribution (Opus vs Sonnet vs Haiku)
  • Most expensive sessions (cost leaderboard)
  • Tool error rates — which tools fail most often?
  • Avg time-to-first-commit per session
  • Cache hit ratios (cacheRead vs input tokens)

4. Real-Time Session Activity Feed

Stream events as they happen:

  • Prompt submitted → tool running → API call → result
  • Like a live activity log but structured and visual
  • Could use the prompt.id correlation to group related events

5. Cost Alerts / Budgets

  • Set a per-session or daily cost budget
  • Alert in Crow UI when a session approaches the threshold
  • Could pause/flag sessions that exceed limits

6. Session Summary on Completion

When a session completes, auto-generate a summary card:

  • Total cost, tokens, active time
  • Files changed, commits made, PR created
  • Number of prompts, tool calls, errors

Architecture Options

Option A: In-Process OTel Receiver

Crow's Swift app listens on a local port for OTLP (gRPC or HTTP). Parses protobuf/JSON payloads directly. Stores in SQLite or in-memory.

  • Pro: No external dependencies, tight integration
  • Con: Must implement OTLP protocol parsing

Option B: Sidecar Collector + SQLite

Ship a lightweight OTel collector binary that writes to a local SQLite DB. Crow reads from the DB.

  • Pro: Battle-tested OTel collector handles protocol details
  • Con: Extra process to manage

Option C: Prometheus Scrape

Use OTEL_METRICS_EXPORTER=prometheus and scrape the /metrics endpoint.

  • Pro: Simple, well-understood
  • Con: Only gets metrics, not events. Loses the rich event data (tool results, API requests, prompts).

Option D: Console Exporter + Log Parsing

Use OTEL_METRICS_EXPORTER=console and parse stdout from the Claude Code terminal.

  • Pro: Zero infrastructure
  • Con: Fragile, mixes with regular output, hard to parse reliably

Recommendation: Option A is the cleanest for a native app. OTel's OTLP HTTP/JSON protocol is straightforward to receive — it's just POST requests with a known schema.

Configuration Surface

Crow would need:

  • A setting to enable/disable telemetry collection
  • Optional: which signals to collect (metrics, events, traces)
  • Optional: retention period for stored telemetry data
  • The OTLP receiver port (auto-assigned or configurable)

Reference

Success Criteria

  • Decide on architecture (A/B/C/D or hybrid)
  • Prototype: receive OTel data from a Claude Code session in Crow
  • Per-session metrics visible in session detail view
  • Cross-session analytics view

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions