Claude Code

Claude Code can export its sessions over OpenTelemetry. Send them to Packrat, and the analyst knows why a change was made: when it checks a deploy, it reads what was asked in the sessions that made the deploy's commits, and what those sessions ran in production after the commit.

This is a setting in Claude Code. Nothing is installed in your app.

Prerequisites

  1. Sign up for Packrat. It's free.

  2. Copy your ingest key from the setup page. It starts with packrat_ingest_.

  3. Install the Packrat CLI and sign in, so you can check what Packrat receives:

    curl -fsSL https://packrat.sh/cli | sh
    packrat login
    

The analyst matches a session to a commit by repository, so connect your app's GitHub repository on the app's Analyst page.

What Packrat gets

Claude Code sends logs, metrics and traces for each session:

  • The prompts you type
  • Each tool call, with the command for a Bash call
  • Token counts, cost and time for each request to the model
  • The repository the session ran in

Prompts and commands can hold anything you type, a secret included. To send only counts, leave out OTEL_LOG_USER_PROMPTS and OTEL_LOG_TOOL_DETAILS. The analyst then cannot match a session to a commit, because it finds the commit by the git commit command the session ran.

Send every session

Claude Code reads the exporter settings only from your user settings. In a project's .claude/settings.json it ignores them and says so only under claude --debug.

Add this to ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_TRACES_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://ingest.packrat.sh",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer <your ingest key>",
    "OTEL_SERVICE_NAME": "claude-code",
    "OTEL_RESOURCE_ATTRIBUTES": "deployment.environment.name=development",
    "OTEL_METRICS_INCLUDE_REPOSITORY": "true",
    "OTEL_LOG_USER_PROMPTS": "1",
    "OTEL_LOG_TOOL_DETAILS": "1"
  }
}

Keep OTEL_SERVICE_NAME as claude-code: the analyst looks for sessions in the org's claude-code apps. The protocol must be http/protobuf; Packrat does not take OTLP as JSON.

Every session on this machine now goes to one org, whatever repository it runs in.

Send only some repositories

If you work on repositories that belong to someone else, give the key to each repository instead. Keep everything above in ~/.claude/settings.json except OTEL_EXPORTER_OTLP_HEADERS. A session with no key is refused, so Packrat keeps nothing from it.

In each repository that should report, add a script that prints the header, and name it in the project's .claude/settings.json. The script reads the key from the environment or from the repository's git-ignored .env, so the key is never committed:

#!/bin/sh
# bin/claude-otel-headers
cd "$(dirname "$0")/.." || exit 1
key=${PACKRAT_INGEST_KEY:-$(sed -n 's/^PACKRAT_INGEST_KEY=//p' .env 2>/dev/null | tail -1)}
if [ -n "$key" ]; then printf '{"Authorization":"Bearer %s"}\n' "$key"; else echo '{}'; fi
{
  "otelHeadersHelper": "bin/claude-otel-headers"
}

Make the script executable with chmod +x bin/claude-otel-headers.

Check it works

Start a new Claude Code session, ask it one thing, and quit. After a minute, ask Packrat what it receives from claude-code/development:

packrat status --app claude-code/development

Logs and metrics arrive first. A short session can send no traces.

Not seeing data?

  • Nothing arrives: run claude --debug and look for a warning that a setting was ignored. The exporter settings must be in ~/.claude/settings.json, not in the project's settings.
  • Sessions arrive, but no deploy names them: check that the app's repository is connected, and that OTEL_METRICS_INCLUDE_REPOSITORY and OTEL_LOG_TOOL_DETAILS are set.