はじめに
Claude Codeを日常的に使っていると、ふと気になることがあります。「今月いくら使ったんだろう」「チームの誰がどれくらいトークンを消費しているんだろう」「キャッシュはちゃんと効いているのか」——しかし、ターミナルに流れていく会話ログを眺めているだけでは、これらの問いに答えることはできません。
Claude CodeはネイティブのOpenTelemetry(OTel)対応を備えています。サードパーティのラッパーやサイドカーは不要で、環境変数を数個設定するだけで、メトリクスとイベントログがOTLPプロトコルで送出されます。
本記事では、まずClaude Codeのテレメトリがなぜこのように設計されているのかを掘り下げた上で、ローカルでの動作確認からDocker Composeによる本格的な可視化基盤の構築までを段階的に解説します。
対象読者
- Claude Codeの利用コストを定量的に把握したいエンジニア
- チームへのClaude Code導入にあたり、利用状況の可視化基盤を構築したい管理者
- OpenTelemetryの実践的な活用事例に興味がある方
前提知識
- Claude Codeの基本的な使い方
- Docker / Docker Composeの基礎
- OpenTelemetryの概念(メトリクス、ログ、トレース)の概要レベルの理解
テレメトリ設計の背景——なぜメトリクスとイベントなのか
トレースが無い理由
OpenTelemetryには3つのシグナルタイプがあります——メトリクス、ログ(イベント)、トレースです。Claude Codeが出力するのはメトリクスとイベントの2種類のみで、トレース(スパン)は出力しません。
これはおそらく意図的な設計判断です。
トレースは、マイクロサービス間のリクエスト伝播を追跡するために設計されたシグナルです。Claude CodeはCLIツールであり、ユーザーのプロンプトがClaude Messages APIに送信され、レスポンスが返る——という本質的に2者間の同期的なやり取りです。分散トレースが真価を発揮する「複数サービスをまたぐリクエストチェーン」は存在しません。
代わりに、Claude Codeはイベントにprompt.id(UUID v4)を付与することで、1つのプロンプトから派生したすべてのイベントを相関付けできるようにしています。ユーザーがプロンプトを送信すると、そこから発生するツール実行、APIリクエスト、パーミッション判定のすべてが同じprompt.idを共有します。トレースの代替としては十分に機能する設計です。
メトリクスの粒度設計
Claude Codeのメトリクスは8種類と、多すぎず少なすぎない数に絞られています。
| メトリクス名 | 何を測るか | 単位 |
|---|---|---|
claude_code.session.count |
セッション開始数 | count |
claude_code.token.usage |
トークン消費量 | tokens |
claude_code.cost.usage |
セッションコスト | USD |
claude_code.lines_of_code.count |
コード変更行数 | count |
claude_code.commit.count |
コミット作成数 | count |
claude_code.pull_request.count |
PR作成数 | count |
claude_code.code_edit_tool.decision |
編集ツールの許可/拒否判定 | count |
claude_code.active_time.total |
アクティブ時間 | seconds |
注目すべきは、これらがビジネスに直結するメトリクスに集中している点です。「APIレイテンシ」や「メモリ使用量」といったインフラ寄りのメトリクスはありません。Claude Codeのテレメトリは、インフラの健全性監視ではなくコスト管理と生産性の可視化を目的として設計されています。
各メトリクスには属性(attribute)が付与され、多次元的な分析が可能です。
claude_code.token.usage
├── type: "input" | "output" | "cacheRead" | "cacheCreation"
└── model: "claude-opus-4-6" | "claude-sonnet-4-6" | ...
claude_code.cost.usage
└── model: "claude-opus-4-6" | ...
claude_code.code_edit_tool.decision
├── tool_name: "Edit" | "Write" | "NotebookEdit"
├── decision: "accept" | "reject"
├── source: "config" | "hook" | "user_permanent" | "user_temporary" | ...
└── language: "TypeScript" | "Python" | ...
イベントの設計——ログパイプラインの再利用
Claude Codeのイベントは、OTelのLogs/Events APIを通じて送出されます。5種類のイベントは、1つのプロンプトのライフサイクルをカバーするように設計されています。
ユーザープロンプト送信
│
├── claude_code.user_prompt ← プロンプトの受信を記録
│
├── claude_code.tool_decision ← ツール使用の許可/拒否
│
├── claude_code.tool_result ← ツール実行の結果
│ └── tool_name, success, duration_ms, error
│
├── claude_code.api_request ← Claude APIへのリクエスト
│ └── model, cost_usd, duration_ms, input_tokens, output_tokens
│
└── claude_code.api_error ← APIエラー(発生時のみ)
└── error, status_code, attempt
これらすべてのイベントが同じprompt.idを共有するため、「このプロンプトでいくらかかったか」「どのツールが失敗したか」をイベント単位で追跡できます。
プライバシー・バイ・デザイン
テレメトリ設計で特筆すべきは、デフォルトでプロンプト内容もツール入力も送信されないという点です。
-
claude_code.user_promptイベントにはprompt_length(文字数)のみが含まれ、プロンプト本文は含まれません - ツール実行結果にはツール名と成否のみが含まれ、bashコマンドの内容やファイルパスは含まれません
- ファイルの中身やコードスニペットはいかなる場合も含まれません
これらの詳細情報を取得するには、明示的にオプトインが必要です。
| 環境変数 | 有効にすると | デフォルト |
|---|---|---|
OTEL_LOG_USER_PROMPTS |
プロンプトの本文がイベントに含まれる | 無効 |
OTEL_LOG_TOOL_DETAILS |
bashコマンド、MCPサーバー名、ツール入力引数がイベントに含まれる | 無効 |
コスト管理やチーム利用量の把握だけが目的であれば、これらを有効にする必要はありません。「誰がいくら使ったか」は分かるが「何をしていたか」は分からない——という線引きが、テレメトリのデフォルト設計に組み込まれています。
最速セットアップ——consoleエクスポーターで動作確認
まずは何も構築せずに、Claude Codeのテレメトリが動作することを確認しましょう。
# 3つの環境変数だけでテレメトリが動く
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=10000 # 10秒間隔(デフォルトは60秒)
claude
Claude Codeを起動して適当なプロンプトを送ると、10秒後にターミナルにメトリクスがJSON形式で出力されます。
{
"resourceMetrics": [{
"scopeMetrics": [{
"metrics": [{
"name": "claude_code.token.usage",
"sum": {
"dataPoints": [{
"attributes": {
"type": "input",
"model": "claude-opus-4-6"
},
"asInt": "2847"
}]
}
}]
}]
}]
}
イベント(ログ)も同様に確認できます。
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=console
claude
動作が確認できたら、次のステップでOTLPエクスポーターに切り替えます。
本格セットアップ——OTel Collector + Prometheus + Grafana
Anthropicが公開しているclaude-code-monitoring-guideをベースに、Docker Composeで可視化基盤を構築します。
アーキテクチャ
Claude Code (CLI)
│
│ OTLP/gRPC (:4317)
▼
OTel Collector
│
│ Prometheus scrape (:8889)
▼
Prometheus (:9090)
│
│ データソース
▼
Grafana (:3000)
OTel Collectorの設定
otel-collector-config.yamlを作成します。
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
send_batch_size: 1024
memory_limiter:
check_interval: 5s
limit_mib: 512
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
metric_expiration: 180m
enable_open_metrics: true
debug:
verbosity: detailed
service:
pipelines:
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [prometheus, debug]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [debug]
ポイントは以下の通りです。
-
metric_expiration: 180m: Claude Codeのセッションは断続的なので、メトリクスの有効期限を長めに設定します。短すぎるとセッション間でメトリクスが消失します -
debugエクスポーター: 構築中はCollectorのログにテレメトリの中身が出力されるので、トラブルシューティングに有用です。本番運用時は除外してください - logsパイプライン: 現時点ではdebugエクスポーターのみですが、Lokiなどのログバックエンドを追加すればイベントも永続化できます
Prometheusの設定
prometheus.ymlを作成します。
global:
scrape_interval: 15s
scrape_configs:
- job_name: "otel-collector"
static_configs:
- targets: ["otel-collector:8889"]
Docker Compose
docker-compose.ymlを作成します。
services:
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317"
- "4318:4318"
- "8889:8889"
depends_on:
- prometheus
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.retention.time=200h"
- "--web.enable-lifecycle"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- prometheus
volumes:
prometheus_data:
grafana_data:
起動と接続
# 1. 可視化基盤を起動
docker compose up -d
# 2. Claude Codeのテレメトリを有効化
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# 3. Claude Codeを起動して操作する
claude
起動後のアクセス先は以下の通りです。
| サービス | URL | 用途 |
|---|---|---|
| Grafana | http://localhost:3000 | ダッシュボード(admin/admin) |
| Prometheus | http://localhost:9090 | メトリクス直接クエリ |
Grafanaにログイン後、データソースとしてPrometheus(URL: http://prometheus:9090)を追加してください。
Grafanaダッシュボードで何を見るか
コスト分析
# 総コスト
sum(claude_code_cost_usage_USD_total)
# モデル別コスト
sum(claude_code_cost_usage_USD_total) by (model)
# ユーザー別コスト(チーム利用時)
sum(claude_code_cost_usage_USD_total) by (user_email)
トークン消費
# トークン種別ごとの消費量
sum(claude_code_token_usage_tokens_total) by (type)
# キャッシュ効率の確認
sum(claude_code_token_usage_tokens_total{type="cacheRead"})
/
sum(claude_code_token_usage_tokens_total{type="cacheCreation"})
キャッシュ効率比(cacheRead / cacheCreation)は、Claude Codeの利用効率を測る重要な指標です。公式モニタリングガイドの実測データでは39:1という比率が報告されており、プロンプトキャッシュが効果的に機能していることが分かります。この比率が極端に低い場合、セッションを頻繁に切り替えすぎている可能性があります。
生産性指標
# トークン消費速度(5分間移動平均)
rate(claude_code_token_usage_tokens_total[5m])
# コード変更行数
sum(claude_code_lines_of_code_count_total) by (type)
# コミット・PR作成数
sum(claude_code_commit_count_total)
sum(claude_code_pull_request_count_total)
Prometheusでのメトリクス名は、OTelの定義(ドット区切り: claude_code.cost.usage)からアンダースコア区切り(claude_code_cost_usage_USD_total)に自動変換されます。単位やカウンターの_totalサフィックスも自動付与されます。
環境変数の全体像
Claude CodeのOTel対応で使用できる環境変数を整理します。
必須
| 変数 | 値 | 説明 |
|---|---|---|
CLAUDE_CODE_ENABLE_TELEMETRY |
1 |
テレメトリのマスタースイッチ |
エクスポーター設定
| 変数 | 値の例 | 説明 |
|---|---|---|
OTEL_METRICS_EXPORTER |
otlp, prometheus, console, none
|
メトリクスのエクスポーター(カンマ区切りで複数指定可) |
OTEL_LOGS_EXPORTER |
otlp, console, none
|
イベント/ログのエクスポーター |
OTEL_EXPORTER_OTLP_PROTOCOL |
grpc, http/json, http/protobuf
|
OTLPプロトコル |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:4317 |
OTLPエンドポイント |
OTEL_EXPORTER_OTLP_HEADERS |
Authorization=Bearer token |
認証ヘッダー |
エクスポート間隔
| 変数 | デフォルト | 説明 |
|---|---|---|
OTEL_METRIC_EXPORT_INTERVAL |
60000(60秒) |
メトリクスの送出間隔(ミリ秒) |
OTEL_LOGS_EXPORT_INTERVAL |
5000(5秒) |
イベントの送出間隔(ミリ秒) |
プライバシー制御
| 変数 | デフォルト | 有効にすると |
|---|---|---|
OTEL_LOG_USER_PROMPTS |
無効 | プロンプト本文がイベントに含まれる |
OTEL_LOG_TOOL_DETAILS |
無効 | bashコマンド、MCPサーバー名、ツール入力がイベントに含まれる |
カーディナリティ制御
| 変数 | デフォルト | 説明 |
|---|---|---|
OTEL_METRICS_INCLUDE_SESSION_ID |
true |
セッションIDをメトリクス属性に含める |
OTEL_METRICS_INCLUDE_VERSION |
false |
Claude Codeバージョンをメトリクス属性に含める |
OTEL_METRICS_INCLUDE_ACCOUNT_UUID |
true |
アカウントUUIDをメトリクス属性に含める |
大規模チームではOTEL_METRICS_INCLUDE_SESSION_ID=falseに設定することで、メトリクスのカーディナリティ(組み合わせ数)を大幅に削減できます。セッション単位の分析が不要な集計用途では、これを無効にすることでPrometheusのストレージ効率が向上します。
高度な設定
| 変数 | デフォルト | 説明 |
|---|---|---|
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE |
delta |
メトリクスの時間集約方式。cumulativeに変更するとバックエンドによっては互換性が向上 |
OTEL_RESOURCE_ATTRIBUTES |
なし | カスタムリソース属性(例: department=engineering,team.id=platform) |
OTEL_RESOURCE_ATTRIBUTESはチーム別・部署別のセグメント分析に有用ですが、値にスペースを含めることはできません。アンダースコアで代替してください。
# ❌ 動作しない
export OTEL_RESOURCE_ATTRIBUTES="org.name=My Organization"
# ✅ 正しい
export OTEL_RESOURCE_ATTRIBUTES="org.name=My_Organization"
settings.jsonでの永続化
毎回環境変数を設定するのは面倒なので、Claude Codeのsettings.jsonに記述して永続化できます。
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317"
}
}
この設定ファイルの配置場所は以下の通りです。
| スコープ | パス | 用途 |
|---|---|---|
| ユーザー | ~/.claude/settings.json |
個人の開発環境 |
| プロジェクト | .claude/settings.json |
リポジトリ単位の設定 |
| 管理者(Managed) | MDM配布 | チーム全体にポリシーを強制 |
管理者がsettings.jsonをManaged設定として配布すれば、ユーザーが個別にテレメトリ設定を上書きすることを防止できます。
チーム導入時の考慮事項
認証の設定
OTLPエンドポイントに認証が必要な場合は、静的ヘッダーまたは動的ヘッダーを使用します。
# 静的ヘッダー
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer your-token"
# mTLS(メトリクス用)
export OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY=/path/to/client.key
export OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE=/path/to/client.crt
トークンの定期更新が必要な環境では、settings.jsonのotelHeadersHelperにスクリプトを指定することで、動的にヘッダーを生成できます。デフォルトでは29分間隔でスクリプトが再実行されます。
メトリクスとイベントの送出先を分ける
メトリクスはPrometheusに、イベントログはLokiに——といった構成も、エンドポイントの個別指定で実現できます。
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://prometheus-gateway:4318/v1/metrics
export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://loki-gateway:4318/v1/logs
export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/protobuf
標準属性によるセグメント分析
すべてのメトリクスとイベントには、以下の標準属性が自動付与されます。
| 属性 | 説明 |
|---|---|
session.id |
セッション識別子 |
user.account_uuid |
アカウントUUID |
user.email |
ユーザーメール(OAuth認証時) |
organization.id |
組織UUID |
terminal.type |
ターミナル種別(iTerm.app, vscode, cursor, tmux等) |
terminal.typeは地味ですが興味深い属性です。VS Code拡張として使っているのか、ターミナルから直接使っているのか、tmux越しなのか——チームのClaude Code利用パターンを把握する手がかりになります。
Grafana Cloudへの直接送信(Collector不要)
ローカルにOTel Collectorを立てたくない場合、Grafana Cloudに直接送信する構成も可能です。
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-ap-northeast-0.grafana.net/otlp
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic <base64-encoded-credentials>"
この構成ではCollectorのメンテナンスが不要になる反面、すべてのテレメトリが直接外部に送信されるため、OTEL_LOG_USER_PROMPTSやOTEL_LOG_TOOL_DETAILSの有効化は慎重に判断してください。
既知の制限と注意点
CLIのみの対応
2026年3月時点で、OTelテレメトリが利用できるのはCLI版のClaude Codeのみです。Web版(claude.ai/code)では利用できません。この点はGitHubのIssue #32364でフィーチャーリクエストとして挙がっています。
テレメトリはオプトイン
CLAUDE_CODE_ENABLE_TELEMETRY=1を明示的に設定しない限り、テレメトリは一切送出されません。これはAnthropicのプライバシー方針として意図的な設計です。
deltaテンポラリティ
メトリクスのデフォルトのテンポラリティはdeltaです。一部のバックエンド(例: 古いバージョンのMimir)ではcumulativeが必要な場合があります。メトリクスが正しく表示されない場合は、OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulativeを試してください。
まとめ
Claude CodeのOpenTelemetry対応は、「とりあえずメトリクスを出せるようにした」という最小限の実装ではありません。
- トレースを省き、メトリクス+イベントに絞る判断は、CLIツールという性質に対して合理的
-
prompt.idによるイベント相関は、トレースなしでもプロンプト単位の追跡を可能にする - プロンプト内容をデフォルトで送信しない設計は、テレメトリとプライバシーの両立を示す
- 8つのメトリクスはビジネスメトリクスに集中しており、コスト管理とROI測定に直結する
LLMベースの開発ツールに対して「いくらかかっているのか分からない」「チームの利用状況が見えない」という不安を持つのは自然なことです。Claude Codeは、その不安に対して標準的なプロトコル(OpenTelemetry)で回答を用意しています。環境変数を3つ設定するところから始めてみてください。
参考
- Claude Code Monitoring Documentation — 公式ドキュメント(本記事の一次情報源)
- anthropics/claude-code-monitoring-guide — Anthropicによるモニタリングガイド(Docker Compose構成、Grafanaダッシュボード例を含む)
- OpenTelemetry Documentation — OpenTelemetryの公式リファレンス