Claude Code の利用状況(コスト・トークン・セッション数)を OpenTelemetry で収集し、Grafana で可視化する自前の監視スタック。
Claude Code (local)
│ OTLP over HTTPS
▼
otel.<domain> ──┐
├── EC2 t3.micro (動的IP + Route53 自動更新)
grafana.<domain>──┘
nginx (Let's Encrypt)
├── OTel Collector :4318 (Basic Auth)
└── Grafana :3000
│
Prometheus :9090 (メトリクス)
Loki :3100 (ログ)
収集データ: メトリクス(コスト・トークン・セッション数)→ Prometheus、ログ(ツール呼び出し履歴)→ Loki
コスト: 使用時のみ起動(~$3/月)
- AWS アカウント・CLI 設定済み(
aws loginで SSO 可) - Route53 で管理しているドメイン
- Terraform >= 1.5
- EC2 キーペア作成済み
# キーペア作成(未作成の場合)
aws ec2 create-key-pair --key-name claude-monitoring `
--query 'KeyMaterial' --output text `
| Out-File -Encoding ascii "$HOME\.ssh\claude-monitoring.pem"aws s3 mb s3://claude-monitoring-tfstate --region ap-northeast-1cp infra\terraform.tfvars.example infra\terraform.tfvars
cp infra\backend.tfbackend.example infra\backend.tfbackend
cp .env.example .envinfra\terraform.tfvars を編集:
hosted_zone_id = "Z0000000000000000000" # Route53 ホストゾーン ID
ssh_key_name = "claude-monitoring" # EC2 キーペア名infra\backend.tfbackend を確認(デフォルトのまま変更不要):
bucket = "claude-monitoring-tfstate"
key = "terraform.tfstate"
region = "ap-northeast-1"cd infra
.\manage.ps1 apply -Profile default
cd ...\manage.ps1 start -Profile default.\manage.ps1 setup -KeyFile $HOME\.ssh\claude-monitoring.pem -Profile defaultbcrypt の $ は Docker Compose の .env 展開で壊れやすいため、Basic 認証は otel.htpasswd ファイルで渡す(.gitignore 済み)。
docker run --rm httpd htpasswd -nbB claude "<任意のパスワード>" > otel.htpasswd.env には Grafana 用など(GF_SECURITY_ADMIN_PASSWORD 等)だけを設定する。
.\manage.ps1 deploy -KeyFile $HOME\.ssh\claude-monitoring.pem -Profile default注意: 初回デプロイ時は
grafana_dataボリュームが存在しない状態で起動する必要がある。既存ボリュームがある場合は削除してから再デプロイ。docker compose down && docker volume rm claude-monitoring_grafana_data
.\manage.ps1 start -Profile default
# DNS 反映まで最大 60 秒.\manage.ps1 stop -Profile default.\manage.ps1 start -Profile default
.\manage.ps1 deploy -KeyFile $HOME\.ssh\claude-monitoring.pem -Profile defaultTeam または Enterprise プランでは、管理者が Admin Console で一度設定するだけでチーム全員に自動配布できます。メンバー側の作業は不要です。
Admin Console に登録する JSON:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.<your-domain>",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Basic <base64(claude:<password>)>",
"OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE": "delta",
"OTEL_METRIC_EXPORT_INTERVAL": "10000",
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
"OTEL_LOG_TOOL_DETAILS": "1"
}
}~/.claude/settings.json に直接追加します。詳細: テレメトリ設定ガイド
Authorization ヘッダーの値は次のコマンドで生成:
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("claude:<password>"))Claudeへ頼むと楽
設定方法:Claudeへ以下のプロンプトを入力する
以下のドキュメントを参照し、テレメトリの設定をしてください
https://github.com/karuru6225/claude-opentelemetry/blob/main/claude-code-telemetry-setup.md
エンドポイントは xxxxx
パスワードは xxxx
SSH ポートはデフォルト 2222。開閉は Terraform で管理:
# infra/terraform.tfvars
ssh_open = true # 開く
ssh_open = false # 閉じる(デフォルト)変更後に infra\manage.ps1 apply で反映。
ssh -i $HOME\.ssh\claude-monitoring.pem -p 2222 ec2-user@<IP>| コマンド | 説明 |
|---|---|
.\manage.ps1 start |
EC2 起動 + Route53 A レコード更新 |
.\manage.ps1 stop |
EC2 停止 |
.\manage.ps1 setup -KeyFile <pem> |
初回のみ: docker/nginx/certbot インストール |
.\manage.ps1 deploy -KeyFile <pem> |
設定ファイル転送 + nginx 設定 + コンテナ起動 |
すべてのコマンドに -Profile <name> を付けると AWS プロファイルを指定できる。
| EC2 セルフホスト(本ドキュメント) | Grafana Cloud | |
|---|---|---|
| インフラ管理 | 必要(EC2/nginx/certbot) | 不要 |
| コスト | ~$3/月 | Free Tier あり |
| OTel Collector | 必要 | 不要 |
| データ保持 | 90日(設定変更可) | 14日(Free) |
Grafana Cloud を使う場合: grafana-cloud/README.md を参照してください。
Grafana ダッシュボードにはチーム全体のサマリーに加え、ユーザー別分析セクションが含まれています。
- ユーザー選択ドロップダウン: 特定のメンバーに絞り込んで全パネルを確認
- ユーザー別コスト / トークン / セッション数: 横棒グラフで一覧比較
- ユーザー別コスト・トークン推移: 時系列グラフ
- ユーザー別コード変更行数・アクティブ時間: 作業量の可視化
各ユーザーは user_email ラベルで識別されます。
.env の以下を有効化するだけで Google Workspace SSO が使える:
GF_AUTH_GOOGLE_ENABLED=true
GF_AUTH_GOOGLE_CLIENT_ID=<GCP OAuth クライアント ID>
GF_AUTH_GOOGLE_CLIENT_SECRET=<シークレット>
GF_AUTH_GOOGLE_ALLOWED_DOMAINS=yourcompany.comその後 .\manage.ps1 deploy で反映。
