OpenTelemetryでClaude Codeの利用状況を計測する

Claude Code エンジニアリング 8分で読めます

Claude Code は OpenTelemetry(OTel)でメトリクスとイベントを外部に送れます。誰がどれだけ使っているのか、どこにコストが出ているのか、ツールの許可・拒否がどう判断されているのかを、推測ではなく実測で見るための仕組みです。この記事では公式ドキュメントに沿って、有効化の手順から出力される項目、プライバシー設定までをまとめます。

何が計測できるのか

Claude Code が出すデータは、メトリクス(時系列の数値)とイベント(構造化ログ)の2系統に分かれます。まず「そもそも何が見えるようになるのか」を押さえておくと、収集基盤を用意する価値があるかを判断できます。

メトリクス側で分かるのは、セッション数、変更された行数、作成されたプルリクエスト数、コミット数、セッションのコスト(USD)、トークン使用量、コード編集ツールの権限判断、そして総アクティブ時間です。コストとトークンが標準で出る点は、組織で使うときの導入判断に直結します。

イベント側はより細かく、プロンプトの送信、モデルの応答、API リクエストの成否、ツールの実行結果、権限判断、MCP サーバーの接続・切断、プラグインの読み込みまで記録されます。1つのプロンプトに紐づくイベントはすべて同じ prompt.id(UUID)を持つので、「この指示が、どの API 呼び出しとどのツール実行を引き起こしたか」を後から辿れます。

ここで先に断っておくと、プロンプト本文やツールの入出力は既定で伏せられます(後述)。既定のままで外に出るのは、あくまで件数・時間・コストといった数値と、何が起きたかの種別です。

有効化の手順

有効化は環境変数だけで完結します。必須なのは1つ目だけで、残りは送り先の設定です。

# 1. テレメトリを有効化(必須)
export CLAUDE_CODE_ENABLE_TELEMETRY=1

# 2. エクスポータを選ぶ
export OTEL_METRICS_EXPORTER=otlp    # otlp / prometheus / console / none
export OTEL_LOGS_EXPORTER=otlp       # otlp / console / none

# 3. OTLP の送り先とプロトコル
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc   # grpc / http/json / http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

# 4. 認証が要る場合
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer your-token"

# 5. 送信間隔(任意。既定はメトリクス60秒 / ログ5秒)
export OTEL_METRIC_EXPORT_INTERVAL=10000   # ミリ秒
export OTEL_LOGS_EXPORT_INTERVAL=5000

claude

動いているかの確認方法も公式に書かれています。セッション開始時に claude_code.session.count が届くか、プロンプトを1つ送って claude_code.user_prompt イベントが届くかを、収集基盤側で見てください。

まず手元で挙動を確かめたいなら、コレクタを立てずにコンソール出力で試すのが早道です。送信間隔を1秒にしておくと待たされません。

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=1000

Prometheus でスクレイプする構成も選べます(OTEL_METRICS_EXPORTER=prometheus にすると http://localhost:9464/metrics で公開されます)。メトリクスとログを別のエンドポイントへ分けたい場合は、OTEL_EXPORTER_OTLP_METRICS_ENDPOINTOTEL_EXPORTER_OTLP_LOGS_ENDPOINT でそれぞれ上書きできます。

出力されるメトリクスとイベント

出力されるメトリクスは次のとおりです。ダッシュボードを組むときは、この名前をそのまま使います。

メトリクス名意味単位
claude_code.session.count開始された CLI セッション数-
claude_code.lines_of_code.count変更された行数-
claude_code.pull_request.count作成されたプルリクエスト数-
claude_code.commit.count作成されたコミット数-
claude_code.cost.usageセッションのコストUSD
claude_code.token.usage使用トークン数tokens
claude_code.code_edit_tool.decisionコード編集ツールの権限判断-
claude_code.active_time.total総アクティブ時間

イベント側は OTEL_LOGS_EXPORTER 経由で出ます。主なものを挙げます。

より細かく因果を追いたい場合は、ベータの分散トレーシングを有効にできます(CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1OTEL_TRACES_EXPORTER=otlp)。スパンは claude_code.interaction をルートに、llm_request / hook / tool がぶら下がる階層になります。フックの実行時間もここで見えます。

プライバシーとカーディナリティ

ここが実運用で最も重要な節です。Claude Code は既定で本文を伏せます。 内容を送りたい場合だけ、明示的に有効化する設計になっています。

変数内容既定
OTEL_LOG_USER_PROMPTSプロンプト本文を含める無効(伏せ字)
OTEL_LOG_ASSISTANT_RESPONSESモデルの応答本文を含める伏せ字
OTEL_LOG_TOOL_DETAILSツールのパラメータ・コマンド・スキル名を含める無効
OTEL_LOG_TOOL_CONTENTツールの入出力をスパンに含める無効
OTEL_LOG_RAW_API_BODIESAPI のリクエスト/レスポンス JSON をそのまま出す無効

この既定値は、そのまま社内展開の判断材料になります。「テレメトリを入れる=社員の書いた指示文が収集基盤に流れる」ではありません。 逆に、監査目的で本文が要るなら明示的に有効化する必要があり、その判断が設定として残ります。

もう一つ、コストに直結するのがカーディナリティ(属性値の種類数)です。メトリクスに付ける属性が増えるほど時系列の本数が増え、収集基盤の保存コストが上がります。

セッション ID は既定で付きます。 セッションごとに新しい値になるため、これが最もカーディナリティを押し上げる属性です。保存コストが問題になったら、まずここを false にすることを検討してください。

本文を出す設定にした場合、1つの属性の長さは CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH で切り詰められます(既定は 61440 = 約60KB)。

組織で配布する

各自に環境変数を設定してもらう運用は、確実に穴が空きます。組織で配るなら .claude/settings.jsonenv にまとめて書くのが公式の方法です。

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer example-token"
  }
}

管理された設定(managed settings)は優先度が高く、利用者が送信先を勝手に書き換えられません。設定ファイルの階層と優先順位についてはClaude Codeの設定と権限を管理するを参照してください。

チームや部署ごとに分けて見たい場合は、リソース属性を足します。

export OTEL_RESOURCE_ATTRIBUTES="department=engineering,team.id=platform,cost_center=eng-123"

これらは全メトリクス・全イベントに問い合わせ可能なラベルとして付きます。ただし公式が明記しているとおり、値の種類が多い属性は保存コストを押し上げます。利用者名のような一意の値ではなく、チーム ID のようなまとまった識別子を使ってください。

最後に運用上の注意を1つ。テレメトリは入れただけでは意味がありませんclaude_code.cost.usage をチーム別に並べる、claude_code.tool_decision の拒否率を見る、といった「何を判断するために見るのか」を先に決めてからダッシュボードを組むと、収集する属性も自然に絞れます。