理系学生日記

おまえはいつまで学生気分なのか

Claude CodeとOpenTelemetry Collector、Amazon Managed Service for Prometheus(AMP)を組み合わせて利用状況を可視化する

毎日Claude Codeを使っていると、ふと「自分はどのような使い方をしているんだろう」と気になることがあります。 セッションあたりどれくらいトークンを消費しているのか、費用はどの程度かかっているのか。もちろんccusageのようなツールもありますが、Claude Codeには組み込みのモニタリング機能があり、OpenTelemetryでさまざまなメトリクスを送出してくれます。

このメトリクスを収集・可視化すれば、自分の利用パターンを客観的に把握できるようになるはずです。

今回はAmazon Managed Service for Prometheus(AMP)とGrafanaを組み合わせて、Claude Codeの利用状況を可視化するシステムを構築しました。

Grafanaダッシュボード

IaCはこちら。

Claude Codeが送出するメトリクス

Claude Codeは、利用状況を把握するためのさまざまなメトリクスをOpenTelemetryで送出します。これらのメトリクスを活用することで、トークン消費量やコストをリアルタイムに近い形で監視できます。

主要なメトリクス

Claude Codeが送出する主なメトリクスは以下のとおりです。

メトリクス名 説明
claude_code.token.usage 消費したトークン数
claude_code.cost.usage トークン使用量から算出された推定コスト(USD)
claude_code.active_time.total セッションの中でアクティブに Claude Code が利用されている時間(秒)
claude_code.lines_of_code.count 追加された行、削除された行数

これらのメトリクスには、session_idなどのラベルが付与されており、セッション単位やターン単位での集計・分析が可能です。

テレメトリの有効化

Claude Codeでテレメトリを有効化するには、環境変数を設定します。OTLP/HTTPでメトリクスを送出する場合の設定例は以下のとおりです。

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://your-collector-endpoint:4318

OTEL_EXPORTER_OTLP_PROTOCOLにはgrpchttp/protobufが指定できますが、今回の構成ではファイアウォールやプロキシを通過しやすいhttp/protobufを採用しています。

なぜOpenTelemetry Collectorが必要なのか

Claude CodeはOTLP(OpenTelemetry Protocol)とPrometheusのPull形式をサポートしていますが、Prometheus Remote Writeは直接サポートしていません。一方、AMPはPrometheus Remote Write APIのみを受け付けます。この両者を繋ぐために、プロトコルを変換するOpenTelemetry Collectorが必須となります。

Claude Codeがサポートするプロトコルを整理すると、OTLPはHTTP(port 4318)とgRPC(port 4317)の両方でネイティブサポートされており、Prometheusのscrape形式もサポートされています。しかし、Prometheus Remote Writeは直接サポートされていません。今回の構成ではOTLP/HTTPを採用しました。どこでも動作するよう、gRPCではなくHTTP/protobufでメトリクスが送出される前提としています。

アーキテクチャ

全体のアーキテクチャは次のようになります。

diagram

AMPに直接OTLPを送信できれば構成がシンプルになりますが、現時点では対応していません。自前でPrometheusをホストすると、Thanosなどを構築してデータの長期保存や可用性を担保する必要があり、運用負荷が高くなります。AMPをデータの蓄積先およびPromQLのバックエンドとして使うことで、マネージドサービスの恩恵を受けつつ、150日間のデフォルト保持期間1と自動スケーリングを活用できます。

OpenTelemetry Collectorの設定

OpenTelemetry Collectorの設定では、いくつかの点に気を遣う必要がありました。

Delta to Cumulative変換の必要性

Claude CodeはDelta temporalityでメトリクスを送信します。Delta temporalityとは、前回の測定からの差分値を送信する方式です。一方、Prometheus Remote WriteはCumulative temporality、つまり累積値を期待します。この違いを吸収するために、deltatocumulativeプロセッサーで変換をかけています。

processors:
  deltatocumulative:
    max_stale: 5m      # 5分間更新がないメトリクスはstaleとみなす
    max_streams: 10000 # 同時に追跡するストリーム数の上限

なお、Claude Code側で環境変数OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCEcumulativeに設定することで、最初からCumulative形式で送信できる可能性があります。

今回はClaude Code以外にもDelta形式でメトリクスを送信するクライアントを受け付けるユースケースを想定しているため、OpenTelemetry Collector側で変換する構成としました。

パイプラインの構成

データフローは「receivers → processors → exporters」の順で処理されます。processorsは左から右の順に適用されるため、順序に意味があります。

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, resourcedetection, deltatocumulative, batch, resource]
      exporters: [prometheusremotewrite, debug]

diagram

最初にmemory_limiterでメモリ使用量を制限してOOMを防止し、次にresourcedetectionでECSタスクの情報を自動検出してラベルに追加します。その後deltatocumulativeでtemporalityを変換し、batchでデータをまとめて送信効率を上げ、最後にresourceで追加のラベルを付与します。

リソース検出の最適化

ECS上で動作する場合、resourcedetectionプロセッサーでタスク情報を自動検出できます。ただし、すべての属性を有効にすると不要なラベルが増えてしまうため、必要な属性のみを有効化しています。

processors:
  resourcedetection:
    detectors: [ecs, env]
    timeout: 2s
    override: false
    ecs:
      resource_attributes:
        aws.ecs.task.id:
          enabled: true
        aws.ecs.task.revision:
          enabled: true
        # 以下は不要なため無効化
        aws.ecs.cluster.arn:
          enabled: false
        aws.ecs.launchtype:
          enabled: false
        # ... 他の属性も同様に無効化

SigV4認証

AMPへの書き込みにはAWS SigV4認証が必要です。OpenTelemetry Collectorではsigv4authエクステンションを使用し、IAMロールの認証情報で署名を付与します。

extensions:
  sigv4auth:
    region: ${AWS_REGION}
    service: aps  # AWS Managed Prometheusのサービス名

exporters:
  prometheusremotewrite:
    endpoint: ${AMP_REMOTE_WRITE_ENDPOINT}
    auth:
      authenticator: sigv4auth
    resource_to_telemetry_conversion:
      enabled: true  # リソース属性をメトリクスのラベルに変換

可視化の例

Grafanaでの可視化では、PromQLを使ってさまざまな切り口でメトリクスを分析できます。

セッションごとのトークン数推移

セッションごとのトークン使用量は、以下のPromQLで可視化できます。

sum by (session_id) (
  claude_code_token_usage_tokens_total
)

セッションごとのトークン使用量

これにより、各セッションでどのようにトークンが消費されているかを時系列で把握できます。急激にトークンが増加しているセッションがあれば、そこで何をしていたのかを振り返るきっかけになります。 同一セッションは同じ色になっていますが、急激に減っているのは /clear を実行しているためですね。

セッションごとの費用

費用も同様にPromQLで可視化できます。

sum by (session_id) (
  claude_code_cost_usage_USD_total
)

セッションごとの費用

日々の利用コストを可視化することで、コスト意識を持ちながらClaude Codeを活用できるようになります。

まとめ

Claude CodeのOpenTelemetryメトリクスをAMPで可視化するシステムを構築しました。ポイントをまとめると以下のとおりです。

  • Claude CodeはOTLPをサポートするがPrometheus Remote Writeは直接サポートしないため、OpenTelemetry Collectorによるプロトコル変換が必須
  • Claude CodeはDelta temporalityでメトリクスを送信するため、Cumulative temporalityを期待するAMPとの間でdeltatocumulativeプロセッサーによる変換が必要
  • AMPをマネージドなPromQLバックエンドとして活用することで、運用負荷を抑えつつ長期のメトリクス保存が可能

自分のClaude Code利用パターンを客観的に把握できるようになったことで、トークン消費やコストを意識した使い方を模索できるようになりました。毎日使っているツールだからこそ、こうした可視化の仕組みを整えておく価値があると感じています。


  1. 3年まで保存期間を拡張できます。