Back to Devoured - June 24, 2026
DEVOURED
Analyzing Claude Code usage with CloudWatch and OpenTelemetry

Analyzing Claude Code usage with CloudWatch and OpenTelemetry

DevOps AWS
CloudWatch OTLP now supports direct bearer token ingestion, allowing developers to monitor AI coding agent usage without complex IAM setup on local machines.
What: AWS updated CloudWatch to support direct OTLP (OpenTelemetry Protocol) metrics ingestion using bearer tokens. This enables organizations to track token usage, cost attribution, and productivity metrics from local instances of Claude Code, GitHub Copilot, and OpenAI Codex.
Why it matters: Standardizing telemetry from local developer tools into a central observability backend allows teams to apply FinOps practices and performance monitoring to AI-assisted coding.
Takeaway: Deploy the Claude Code dashboard using the AWS Observability Accelerator to start tracking your organization's AI coding costs.
Deep dive
  • Bearer Token Authentication: Uses a static API key to authenticate metrics ingestion without needing temporary AWS security credentials.
  • OTLP (OpenTelemetry Protocol): A vendor-agnostic format for transmitting telemetry data.
  • PromQL: A query language for Prometheus, now natively supported in CloudWatch for metric analysis.
Decoder
  • OTLP: A standard specification for how to encode and transport telemetry data (metrics, logs, traces) between services.
Original article

Analyzing Claude Code usage with CloudWatch and OpenTelemetry

If your engineering organization uses AI coding agents like Claude Code, usage is likely growing faster than your ability to track it. Token consumption, cost per team, and developer productivity are questions that existing dashboards don’t answer, because the telemetry never made it to your observability backend.

With Amazon CloudWatch OpenTelemetry Protocol (OTLP) in General Availability, metrics ingestion is now possible with bearer token authentication. This means, tools that emit OTLP can typically ship metrics directly to CloudWatch with a single authorization header. No collectors, no sidecars, no IAM credential wiring on developer machines. Connect the signals in minutes and get per-developer cost attribution, team-level usage analytics, and operational alerting, all queryable with Prometheus Query Language (PromQL).

This post walks through the end-to-end setup for Claude Code. Although the focus here is Claude Code, comprehensive guidance for OpenAI Codex and GitHub Copilot is available on the AWS Observability best practices. This post focuses on bearer token authentication for its simplicity on developer machines. For organizations that require SSO (Single Sign-On) or OIDC (OpenID Connect) for developer authentication, see the guidance repository for federated identity patterns and token refresh helpers.

Bearer token authentication

Bearer tokens (or CloudWatch metrics API key) allow tools running outside AWS (like Claude Code on developer laptops) to send metrics to CloudWatch without requiring the AWS SDK or IAM credential chains. Each token is tied to an AWS IAM user scoped exclusively to the CloudWatchAPIKeyAccess managed policy.

Important: Bearer tokens are long-term credentials. This post uses bearer tokens because AI coding agents run on developer laptops outside of AWS. SigV4 authentication would require either a central collector or running a collector process on every developer machine. Both approaches add operational complexity. Bearer tokens eliminate that infrastructure requirement entirely. For workloads running inside AWS where SigV4 with short-term credentials is feasible, prefer that approach for a stronger security posture. The CloudWatch OTLP endpoint requires HTTPS; requests over plain HTTP are rejected. For more information, see CloudWatch OTLP Metrics Bearer Token Auth.

Granularity strategy

Organizations control how granular their telemetry attribution is based on how they provision bearer tokens. At the finest level, each developer gets their own IAM user and bearer token, so attribution is inherent to the token itself. At a coarser level, a single token can be shared across a team or an entire organization, with identity attribution handled through client-side resource attributes instead.

All three approaches produce identical dashboards and PromQL queries because attribution is driven by resource attributes, not the token itself. Start with a single shared token to validate the pipeline, then split to per-team or per-developer tokens as your security posture demands. Per-developer tokens are recommended when compliance requires credentials traceable to a named individual or when clean offboarding (revoking a single IAM user) is a hard requirement.

Prerequisites

  • An AWS account with permissions to create CloudWatch resources
  • AWS CLI v2 installed and configured
  • Latest Claude Code version
  • A CloudWatch metrics API key (generated below)

Create a bearer token via the console

In the CloudWatch console, navigate to Settings under the Setup section.

  1. Scroll to API Keys.
  2. Choose Create.
  3. Select an API key expiration.

CloudWatch creates the associated IAM user on your behalf with the CloudWatchAPIKeyAccess policy attached.

Create a bearer token via the CLI

Alternatively, create a token with the CLI using the following commands:

# Create an IAM user for CloudWatch metrics ingestion
aws iam create-user --user-name cloudwatch-metrics-api-key-user

# Attach the CloudWatchAPIKeyAccess managed policy
aws iam attach-user-policy \
    --user-name cloudwatch-metrics-api-key-user \
    --policy-arn arn:aws:iam::aws:policy/CloudWatchAPIKeyAccess

# Create a service-specific credential for CloudWatch metrics ingestion
aws iam create-service-specific-credential \
    --user-name cloudwatch-metrics-api-key-user \
    --service-name cloudwatch.amazonaws.com

The response includes the ServiceCredentialSecret field, which is the bearer token value. Store it securely in AWS Secrets Manager or your organization’s vault solution. A reminder that you should never commit the token to version control. For automated key rotation, use AWS Secrets Manager rotation with a Lambda function.

Client-side configuration

With the bearer token set up, you can now configure Claude Code to export metrics. This approach uses client-side resource attributes set by each developer (or distributed via profile management).

# Retrieve token from Secrets Manager
BEARER_TOKEN=$(aws secretsmanager get-secret-value \
 --secret-id cloudwatch-otlp-bearer-token \
 --query SecretString \
 --output text)

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
export OTEL_EXPORTER_OTLP_ENDPOINT="https://monitoring.<AWS_REGION>.amazonaws.com"
export OTEL_RESOURCE_ATTRIBUTES="user.id=$(whoami),user.email=${USER_EMAIL},team.id=${TEAM:-engineering},cost_center=${COST_CENTER:-default},department=${DEPARTMENT:-engineering},environment=${ENV:-dev}"

# Security Note: Environment variables can be exposed through process listings and shell history.
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer ${BEARER_TOKEN}"

# control export frequency (2s, for testing)
export OTEL_METRIC_EXPORT_INTERVAL=2000

Replace <AWS_REGION> with your target Region (for example, us-east-1, eu-west-1).

The OTEL_RESOURCE_ATTRIBUTES line attaches identity dimensions to every metric. Developers set these attributes directly. They become the PromQL labels for filtering and grouping in dashboards and alerts. Use whatever attributes your organization needs. The key requirement is consistency across your fleet so aggregations work.

Attribute PromQL label Purpose Example
user.id @resource.user.id Per-developer attribution jdoe
user.email @resource.user.email Per-developer attribution (email) jdoe@acme.com
team.id @resource.team.id Team-level aggregation platform-eng
cost_center @resource.cost_center Finance/chargeback grouping CC-4200
department @resource.department Org-level rollup engineering
environment @resource.environment Distinguish dev/staging/prod usage production

Verify metrics are flowing

After setting the environment variables, run a short Claude Code session:

# Start a brief session
claude -p "Let's conquer the world" --max-turns 1

To verify metrics are flowing, open CloudWatch Query Studio and enter claude_. You will see a few metrics such as claude_code.token.usage which tracks the number of tokens used.

Sample usage dashboard

Regardless of the granularity strategy described previously, a CloudWatch dashboard is available that uses PromQL to query Claude Code telemetry data. As long as your resource attributes follow the semantic conventions described in the client-side configuration section, all values appear in the dashboard automatically.

Deploy the pre-built dashboard:

# Download the dashboard definition
curl -o claude-code-dashboard.json https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/cloudwatch-dashboards/claude-code/claude-code.json

aws cloudwatch put-dashboard \
  --dashboard-name claude-code-usage \
  --dashboard-body file://claude-code-dashboard.json \
  --output off \
  --region <AWS_REGION>

Alerting

Every panel in the dashboard is backed by a PromQL query. To create an alarm from any panel:

  1. Open the panel you are interested in (for example, token usage by user).
  2. To open the underlying query, choose View in Query Studio.
  3. Choose Create alarm directly from Query Studio.
  4. Adjust the query or thresholds as needed.

Cost estimate

For a 200-developer organization where each developer runs ~20 sessions per day, each emitting ~7 metric data points with resource attributes, and developers are active ~22 days/month:

A typical OTLP data point with 10-15 attributes is 300-600 bytes. Using 450 bytes as a midpoint:

200 developers × 20 sessions/day × 7 metrics × 450 bytes = 12.6 MB/day
12.6 MB/day × 22 days = ~277 MB/month ≈ 0.27 GB/month

At $0.50/GB ingestion, that is ~$0.14/month for the base case. Even with high-cardinality metrics (100x volume), total ingestion stays under $14/month. PromQL queries in the CloudWatch console are free.

The total cost for 200 developers, in this example, would be under $15/month.

Cleanup

Important: CloudWatch retains metrics up to 15 months at no charge. Delete alarms and IAM resources to avoid ongoing costs and security exposure.

Follow these commands to remove all the resources you have created:

# Delete Dashboard
aws cloudwatch delete-dashboards --dashboard-names claude-code-usage --region <AWS_REGION>

# Delete CloudWatch Alarms
aws cloudwatch delete-alarms --alarm-names <alarm-name> --region <AWS_REGION>

# Delete service-specific credential
aws iam delete-service-specific-credential --user-name cloudwatch-metrics-api-key-user --service-specific-credential-id <credential-id>

# Detach policy from IAM user
aws iam detach-user-policy --user-name cloudwatch-metrics-api-key-user --policy-arn arn:aws:iam::aws:policy/CloudWatchAPIKeyAccess

# Delete IAM user
aws iam delete-user --user-name cloudwatch-metrics-api-key-user

# If using Secrets Manager, delete the secret
aws secretsmanager delete-secret --secret-id <secret-name> --region <AWS_REGION>

Conclusion

In this post, you configured Claude Code to export OpenTelemetry metrics to Amazon CloudWatch using bearer token authentication, deployed a PromQL-powered dashboard for cost and usage visibility, and set up alerting for spend anomalies and adoption regression.

Explore all 56 articles in today's digest

Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi