Overview

Monitor Claude Code with Axiom

Prerequisites#

How Axiom routes OpenTelemetry data#

Axiom routes data to datasets via headers, and the header differs by signal type:

  • Logs use x-axiom-dataset
  • Metrics use x-axiom-metrics-dataset

This means signal-specific header configuration is required rather than a single shared OTEL_EXPORTER_OTLP_HEADERS value.

The /v1/metrics endpoint only supports the application/x-protobuf content type.

Configure environment variables#

Create a file named setup-otel.sh with the following content:

Don't execute the script directly. Source the script instead. The exported variables must exist in the current shell where Claude inherits them.

setup-otel.sh

#!/bin/bash
 
# Claude Code OpenTelemetry configuration for Axiom
# Usage: source ./setup-otel.sh && claude
 
# Replace these with your own values
AXIOM_API_TOKEN="API_TOKEN"
AXIOM_HOST="AXIOM_DOMAIN"
AXIOM_METRICS_DATASET="METRICS_DATASET_NAME"
AXIOM_LOGS_DATASET="LOGS_DATASET_NAME"
 
# Enable telemetry and configure both exporters
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
 
# Axiom's metrics endpoint requires protobuf (no JSON support)
export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/protobuf
 
# Separate endpoints per signal type
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://${AXIOM_HOST}/v1/metrics
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://${AXIOM_HOST}/v1/logs
 
# Separate headers per signal type (Axiom routes to datasets via different headers)
export OTEL_EXPORTER_OTLP_METRICS_HEADERS="Authorization=Bearer ${AXIOM_API_TOKEN},x-axiom-metrics-dataset=${AXIOM_METRICS_DATASET}"
export OTEL_EXPORTER_OTLP_LOGS_HEADERS="Authorization=Bearer ${AXIOM_API_TOKEN},x-axiom-dataset=${AXIOM_LOGS_DATASET}"
 
# Shorter intervals for testing (default: 60s metrics, 5s logs)
export OTEL_METRIC_EXPORT_INTERVAL=10000
export OTEL_LOGS_EXPORT_INTERVAL=5000
 
# Optional: log full prompt content and tool/MCP details
export OTEL_LOG_USER_PROMPTS=1
export OTEL_LOG_TOOL_DETAILS=1
 
echo "Axiom OTel configured: metrics -> ${AXIOM_METRICS_DATASET}, logs -> ${AXIOM_LOGS_DATASET}"

Replace API_TOKEN with the Axiom API token you have generated. For added security, store the API token in an environment variable.

Replace AXIOM_DOMAIN with the base domain of your edge deployment. For more information, see Edge deployments.

Replace METRICS_DATASET_NAME with the name of the Axiom dataset for metrics.

Replace LOGS_DATASET_NAME with the name of the Axiom dataset for logs.

Verify the integration#

1
Source the script and start Claude Code

Run the following command in your terminal:

source ./setup-otel.sh && claude
2
Interact with Claude Code

Use Claude Code for 15 to 20 seconds to generate telemetry data. Ask questions, run commands, or perform any typical tasks.

3
Observe telemetry in Axiom

In Axiom, go to your datasets and observe the telemetry data:

  • The logs dataset shows events like claude_code.user_prompt, claude_code.tool_result, and claude_code.api_request.
  • The metrics dataset shows counters like claude_code.session.count and claude_code.token.usage, updating on the 10-second interval configured above.

If one signal arrives but the other doesn't, double-check the headers. The most common mistake is using x-axiom-dataset for metrics instead of x-axiom-metrics-dataset.

Production considerations#

When moving from testing to production, consider these adjustments:

  • Disable prompt logging: Remove OTEL_LOG_USER_PROMPTS=1 unless prompt content is needed in your observability backend. This reduces the volume of sensitive data stored.

  • Use managed settings for teams: For team deployments, administrators can set these variables in Claude Code's managed settings file instead of relying on each developer to source a script.

  • Add resource attributes: Use OTEL_RESOURCE_ATTRIBUTES to tag all telemetry with department, team, or cost center identifiers for filtering and alerting in Axiom.

    export OTEL_RESOURCE_ATTRIBUTES="team=platform,cost_center=engineering,environment=production"
  • Adjust export intervals: For production, consider using longer intervals to reduce overhead:

    export OTEL_METRIC_EXPORT_INTERVAL=60000  # 60 seconds
    export OTEL_LOGS_EXPORT_INTERVAL=30000    # 30 seconds

Reference#

Environment variables#

Variable Description
CLAUDE_CODE_ENABLE_TELEMETRY Set to 1 to enable OpenTelemetry export.
OTEL_METRICS_EXPORTER Set to otlp to enable OTLP metrics export.
OTEL_LOGS_EXPORTER Set to otlp to enable OTLP logs export.
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL Protocol for metrics. Use http/protobuf for Axiom.
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL Protocol for logs. Use http/protobuf for Axiom.
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT Axiom metrics endpoint URL.
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT Axiom logs endpoint URL.
OTEL_EXPORTER_OTLP_METRICS_HEADERS Headers for metrics including authorization and dataset.
OTEL_EXPORTER_OTLP_LOGS_HEADERS Headers for logs including authorization and dataset.
OTEL_METRIC_EXPORT_INTERVAL Metrics export interval in milliseconds. Default: 60000.
OTEL_LOGS_EXPORT_INTERVAL Logs export interval in milliseconds. Default: 5000.
OTEL_LOG_USER_PROMPTS Set to 1 to log full prompt content.
OTEL_LOG_TOOL_DETAILS Set to 1 to log tool and MCP details.
OTEL_RESOURCE_ATTRIBUTES Comma-separated key=value pairs for resource attributes.

Expected telemetry data#

Claude Code exports the following telemetry:

Logs:

  • claude_code.user_prompt: User prompts sent to Claude Code.
  • claude_code.tool_result: Results from tool executions.
  • claude_code.api_request: API requests made by Claude Code.

Metrics:

  • claude_code.session.count: Number of Claude Code sessions.
  • claude_code.token.usage: Token usage counters.

Updated

Was this page helpful?