TL;DR
- オブザーバビリティのコストは「データ量 × カーディナリティ × 保持期間」でほぼ決まる
- 最大の浪費源は 高カーディナリティのラベル(user_id・request_id を metrics の label にする等)
- サンプリング戦略:trace は tail-based sampling、log は severity ベース、metrics は集約
- 保持期間は階層化(hot 7日 / warm 30日 / cold 1年)でコストを削減
- OpenTelemetry 移行でベンダーロックインを外し、バックエンド切替えの自由度を確保
この記事の目的と成功基準
- 目的: 観測品質を落とさずオブザーバビリティ費用を最適化する4軸を実装粒度で整理する
- 想定読者: SRE / Platform エンジニア、観測コストに責任を持つ EM
- 成功基準: 「オブザーバビリティ コスト」「Datadog 費用削減」関連クエリでの流入、SRE KPI ツールキット への回遊
コスト構造を理解する
Datadog・New Relic・Grafana Cloud いずれも、課金は概ね以下で決まる:
コスト ≒ データ取り込み量 × カーディナリティ × 保持期間
- データ取り込み量: log GB / trace span 数 / metrics データポイント
- カーディナリティ: ユニークな time series 数(label の組合せ)
- 保持期間: 何日分保存するか
本番1か月で見積もりの3倍になるケースが多く、最大の犯人は カーディナリティ爆発。
軸1: 高カーディナリティ削減
最重要。metrics の label に高カーディナリティ値を入れると time series が爆発する。
❌ 悪い例:
# user_id を label にする → ユーザー数だけ time series 増殖
metric.increment("api.request", tags=[f"user_id:{user_id}"])
✅ 良い例:
# 集約可能な低カーディナリティ label
metric.increment("api.request", tags=[f"endpoint:{endpoint}", f"status:{status}"])
# user_id は trace / log 側に置く(metrics には入れない)
ルール:
- metrics の label は 低カーディナリティ(endpoint / status / region 等)
- user_id / request_id / session_id は trace / log に置く
- 動的な値(タイムスタンプ・UUID)を label にしない
カーディナリティ削減だけでコストが半減することも珍しくない。
軸2: サンプリング戦略
全データを保存する必要はない。シグナル別に最適化:
Trace: tail-based sampling
- すべての trace を一旦収集
- エラー / 高 latency / 特定条件の trace を優先保存
- 正常 trace は 1-10% サンプリング
# OpenTelemetry Collector tail_sampling
processors:
tail_sampling:
policies:
- name: errors
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow
type: latency
latency: { threshold_ms: 1000 }
- name: baseline
type: probabilistic
probabilistic: { sampling_percentage: 5 }
Log: severity ベース
- ERROR / WARN: 100% 保存
- INFO: 10% サンプリング or 構造化して集約
- DEBUG: 本番では出さない(or 1%)
Metrics: 集約
- 高解像度(1秒)を hot 期間のみ、それ以降は1分・5分に rollup
軸3: 保持期間の階層化
すべてを長期保存しない。3層に分ける:
| 層 | 期間 | 用途 | コスト |
|---|---|---|---|
| Hot | 7日 | リアルタイム調査・アラート | 高 |
| Warm | 30日 | トレンド分析・週次レビュー | 中 |
| Cold | 1年 | コンプライアンス・年次分析 | 低(S3 等) |
- Hot は full resolution
- Warm は rollup(解像度を落とす)
- Cold は object storage に export(Datadog の外)
監査要件で1年保存が必要でも、cold tier に逃がせばコストは大幅減。
軸4: OpenTelemetry 移行
ベンダーロックインを外し、バックエンド切替えの自由度を確保。
メリット:
- 計装コード(instrumentation)がベンダー非依存
- Collector でサンプリング・フィルタを一元管理
- バックエンド(Datadog → Grafana → 自前)を切替え可能
- コスト交渉力が上がる
OpenTelemetry は2026年に de facto standard。新規計装は OTel ベースが推奨。既存の Datadog Agent からの移行は段階的に。
コスト削減の優先順位
- カーディナリティ監査(即効・最大効果): 高カーディナリティ metrics を特定し label を削減
- log サンプリング(即効): DEBUG を本番から除外、INFO をサンプリング
- 保持期間階層化(中期): hot/warm/cold の3層化
- trace tail sampling(中期): Collector 導入
- OpenTelemetry 移行(長期): ロックイン解消
観測品質を落とさないために
コスト削減で観測が効かなくなっては本末転倒。守るべきライン:
- SLI 計算に必要な metrics は full resolution で保持(SRE KPI の SLO 計算)
- エラー trace は 100% 保存(インシデント調査に必須)
- ガード指標(latency p99 等)はサンプリングしない
サンプリングしてよいのは「正常系の大量データ」だけ。
アンチパターン
- 全 metrics を高解像度で永久保存: コスト爆発
- user_id を metrics label に: カーディナリティ爆発の典型
- コスト削減でエラー trace もサンプリング: 調査不能に
- ベンダー Agent 直書き: ロックインで交渉力ゼロ
- 削減後に観測品質を検証しない: SLO 計算が壊れていないか確認必須
Growth Lab の最適化例
参考:本サイトの観測スタック最適化結果:
| 施策 | 月次コスト変化 |
|---|---|
| ベースライン | 100% |
| カーディナリティ監査(user_id 削除) | 55% |
| log サンプリング(DEBUG除外+INFO 10%) | 42% |
| 保持期間階層化 | 35% |
| OTel Collector で tail sampling | 30% |
4軸全部で 70% 削減、観測品質(SLO 計算・エラー調査)は維持。
FAQ
Q. カーディナリティが高いか、どう判定しますか? A. Datadog なら「Metrics Summary」で time series 数を確認。1 metric で数万 series あれば label を疑います。user_id / UUID / timestamp が label にないか監査します。
Q. tail-based sampling は head-based と比べて何が良い? A. tail は trace 完了後にエラー/遅延を見て判定するため「重要な trace を確実に残せる」。head は最初に確率で決めるためエラー trace を取りこぼします。
Q. OpenTelemetry 移行は一気にやるべき? A. 段階的が安全。新規サービスから OTel、既存は Datadog Agent と並行運用し、Collector を挟んでバックエンドを徐々に切替えます。
まとめ
オブザーバビリティのコストは「データ量 × カーディナリティ × 保持期間」で決まる。高カーディナリティ削減が最大効果、次いで log サンプリング・保持期間階層化・trace tail sampling・OTel 移行。観測品質(SLO 計算・エラー調査)を守るラインを明示し、正常系の大量データだけを削る。4軸で70%削減も現実的。
