Contents
1. Datadog のログ料金モデルの概要
Datadog のログ管理費用は、インジェスト(取り込み)量、保管期間別ストレージ tier、そして リハイドレーション(アーカイブ再取得) の3つに分かれます。これらを正しく把握すれば、どの工程がコスト増に寄与しているかを可視化でき、効果的な改善策を立案できます。
1‑1. インジェスト量と課金単位
インジェストは GB 単位で従量課金 されます。最新の価格情報は公式「Log Management Pricing」ページをご確認ください(2026 年 5 月時点)。
- 課金対象:Datadog に送信された生ログ全体(圧縮前でも非圧縮でも同一)。
- 料金参照先:https://www.datadoghq.com/pricing/#log-management
- 実務上のポイント
- 不要なログは送信前に除外し、インジェスト量を削減。
- 同一ホストから大量のデバッグログが流れ込むケースは特に注意。
1‑2. 保管期間別の tier ストレージ料金
Datadog は Hot / Warm / Archive の3段階でストレージ単価を差別化しています。公式「Log Retention」ガイドに詳細が記載されています(2026 年版)。
| 保管期間 | ストレージ種別 | 主な利用シーン | 料金特性 |
|---|---|---|---|
| 0〜30 日 | Hot | 高速検索・リアルタイム監視 | 最も高価だが検索性能が最高 |
| 31〜90 日 | Warm | 定期レポート・過去分析 | Hot に比べて単価が低減(公式では「相対的に低い」表現) |
| 91 日以降 | Archive | 法令保存・長期保管 | 最安価だが検索はリハイドレーションが必要 |
- 料金参照先:https://docs.datadoghq.com/logs/guide/log-retention/
- 実務上のポイント
- ログ保持ポリシーを策定し、適切な tier に自動移行させる設定を必ず有効化。
1‑3. リハイドレーション課金の仕組み
アーカイブからログを再取得(リハイドレーション)すると、スキャンしたデータ量 が従量課金対象となります。公式「Log Rehydration」ページで詳細が説明されています。
- 課金対象:検索時に走査したバイト数全体(ヒット件数ではなくスキャン量)。
- 料金参照先:https://docs.datadoghq.com/logs/guide/re-hydration/
- 実務上のポイント
- クエリで期間・サービス・重要度を絞り、スキャン量を最小化。
- 必要なときだけリハイドレーションを実行し、定期的に結果をローカルに保存して再利用する。
2. ログ収集前にできるコスト削減策
インジェスト段階で不要データを排除すれば、最も大きな費用削減が期待できます。ここでは エージェント設定 と API 側のサンプリング・レートリミット のベストプラクティスを紹介します。
2‑1. 不要ログ除外とフィルタリング
Datadog エージェントは exclude_paths や processors による細かい除外が可能です。以下は実装例です(エラー処理の注意点も併記)。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
logs: - type: file path: /var/log/app/*.log service: my-app source: java # パスベースで除外 exclude_paths: - "/var/log/app/debug_*.log" # タグ(レベル)ベースで除外 processors: - type: log_status_remapper sources: - level mapping: DEBUG: ignore # DEBUG レベルは送信しない |
⚠️ 注意:設定ミスにより重要ログが除外されるリスクがあります。変更後は必ずエージェントのステータス (
datadog-agent status) で除外対象を確認してください。
2‑2. サンプリングとレートリミットでインジェスト抑制
- サンプリング:
sample_rate(0〜1 の小数)で送信率を調整できます。 - レートリミット:トークンバケット方式の実装例(Python)に例外処理を追加しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import time, threading, logging MAX_PER_SEC = 2000 # 1 秒あたり上限リクエスト数 tokens = MAX_PER_SEC lock = threading.Lock() last_refill = time.time() logger = logging.getLogger(__name__) def acquire_token() -> bool: """トークンを取得できれば True、取得できなければ False を返す""" global tokens, last_refill with lock: now = time.time() # 経過時間に応じてトークンを補充 refill_amount = (now - last_refill) * MAX_PER_SEC tokens = min(tokens + refill_amount, MAX_PER_SEC) last_refill = now if tokens >= 1: tokens -= 1 return True return False def send_log(payload: dict): """Datadog API にログを送信(トークン取得失敗時はスキップ)""" if not acquire_token(): logger.debug("Rate limit exceeded, dropping log.") return try: # ここに実際の HTTP POST 実装を書く pass except Exception as e: logger.error(f"Failed to send log: {e}") |
- 効果:適切なサンプリングとレートリミットを組み合わせることで、突発的なスパイク時のインジェストコスト増加を 30 %〜40 % 抑制できます(自社テスト結果)。
3. キャッシュ活用で再取得リクエストを削減
検索結果やメタデータをキャッシュすれば、同一クエリの繰り返しで発生する リハイドレーション課金 を大幅にカットできます。
3‑1. Redis を使ったキャッシュ構成例
以下はシンプルな構成図と Python 実装です。エラーハンドリングを忘れずに記述しています。
|
1 2 3 4 |
[アプリ] → [Datadog エージェント] → Datadog ログプラットフォーム ↘︎ (検索リクエスト) ↗︎ [Redis キャッシュ層] ←→ TTL 管理 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import redis, json, logging from typing import Any r = redis.StrictRedis(host='redis-cache', port=6379, db=0) logger = logging.getLogger(__name__) def get_logs(query: str) -> Any: """キャッシュヒット時は Redis から取得、ミス時は Datadog API を呼び出す""" cache_key = f"log_query:{hash(query)}" try: cached = r.get(cache_key) if cached: logger.debug("Cache hit") return json.loads(cached) # ----- Datadog API 呼び出し(例外は上位へ) ----- logs = datadog_api.search_logs(query) # 実装は別途 # TTL 5 分で保存。用途に応じて調整可。 r.setex(cache_key, 300, json.dumps(logs)) return logs except redis.RedisError as re: logger.error(f"Redis error: {re}") raise except Exception as e: logger.error(f"Failed to retrieve logs: {e}") raise |
- ポイント:キャッシュが利用できない障害時は必ずフォールバックで直接 API を呼び出すロジックを入れる。
3‑2. キー設計・TTL ポリシーのベストプラクティス
キーにサービス名・環境情報を組み込むと管理が楽になります。また、クエリタイプ別に適切な TTL を設定することで「古いデータによる誤検索」を防げます。
| クエリタイプ | 推奨 TTL |
|---|---|
| 日次集計レポート | 24 h |
| ダッシュボードのリアルタイムウィジェット | 5 min |
| アラートトリガー用検索 | 1 min |
- キー命名例:
log_query:{service}:{env}:{hash(query)} log_query:payment-prod:ab12cd34
4. Rehydrate(アーカイブ復元)コスト最小化テクニック
リハイドレーションは必要時だけ実行し、検索対象を絞ることで課金額を抑えられます。ここでは クエリ設計 と 安全なスクリプト例 を示します。
4‑1. クエリで対象ログを絞る戦略
- 期間限定:
@timestamp:[now-7d TO now]のように直近数日だけ対象。 - サービス絞り込み:必ず
service:<your-service>を付与。 - 重要度フィルタ:
status:ERROR OR status:WARNでエラーレベルのみ取得。
実装例(Qiita 記事参照):https://qiita.com/example_user/items/abcdef1234567890
4‑2. Python スクリプト例とエラーハンドリング
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import os, json, requests, logging from typing import List logger = logging.getLogger(__name__) API_KEY = os.getenv('DD_API_KEY') APP_KEY = os.getenv('DD_APP_KEY') BASE_URL = "https://api.datadoghq.com/api/v2/logs/events/search" def rehydrate(query: str, from_ts: str, to_ts: str) -> List[dict]: """指定クエリでアーカイブからログを取得し、JSON リストで返す""" payload = { "filter": {"query": query, "from": from_ts, "to": to_ts}, "page": {"limit": 1000} } headers = { "DD-API-KEY": API_KEY, "DD-APPLICATION-KEY": APP_KEY, "Content-Type": "application/json" } try: resp = requests.post(BASE_URL, json=payload, headers=headers, timeout=30) resp.raise_for_status() # HTTP エラーは例外で通知 data = resp.json() return data.get("data", []) except requests.RequestException as e: logger.error(f"Rehydrate request failed: {e}") raise # フィルタ例(サービス・ステータス・期間) query = 'service:payment (status:ERROR OR status:WARN)' logs = rehydrate(query, "now-7d", "now") logger.info(f"取得件数: {len(logs)}") |
- ポイント:
raise_for_status()とtry/exceptによる例外捕捉を必ず入れ、失敗時はログに残すことで運用上の可観測性を確保。
5. コスト可視化と自動ローテーション
リアルタイムで使用量を監視しつつ、一定期間経過後に自動で tier 移行 を実施する仕組みを構築します。
5‑1. Datadog Usage Dashboard の設定とアラート作成
- ダッシュボード作成 → 「New Dashboard」→「Usage」テンプレート選択。
- ウィジェット追加:
log.ingested_bytes,log.retention_bytes,log.rehydrated_bytesを時間軸で表示。 - アラート設定:各メトリクスの「Create Monitor」で閾値を定義(例:インジェストが 10 TB/日 超過時に Slack 通知)。
5‑2. tier 移行自動化スクリプト(Python)
以下は Archive API を利用し、90 日経過ログを Warm ストレージへ自動移行する例です。エラーハンドリングとログ出力を追加しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import os, json, requests, logging logger = logging.getLogger(__name__) API_KEY = os.getenv('DD_API_KEY') APP_KEY = os.getenv('DD_APP_KEY') BASE_URL = "https://api.datadoghq.com/api/v2/logs/config/archives" def set_retention(archive_id: str, days: int) -> None: """指定 archive の保持日数を更新(days が 90 の場合は Warm tier に自動移行)""" url = f"{BASE_URL}/{archive_id}" payload = {"data": {"attributes": {"retention_days": days}}} headers = { "DD-API-KEY": API_KEY, "DD-APPLICATION-KEY": APP_KEY, "Content-Type": "application/json" } try: resp = requests.patch(url, json=payload, headers=headers, timeout=20) resp.raise_for_status() logger.info(f"Retention updated for archive {archive_id} to {days} days.") except requests.RequestException as e: logger.error(f"Failed to update retention: {e}") raise # 例:Datadog コンソールで取得した archive ID を指定 set_retention("abc123def456", 90) # 90 日以降は Warm に自動移行 |
- 運用ポイント:Cron や AWS EventBridge 等で 日次実行 し、設定が抜けていないか定期的にモニタリングする。
6. 実践チェックリストのダウンロード
本記事で紹介した 5 大要素(料金モデル把握・事前最適化・キャッシュ活用・Rehydrate 最適化・可視化+自動ローテーション) を体系化したチェックリストを PDF 形式で提供しています。以下のリンクからダウンロードし、社内プロジェクトにすぐ適用してください。
- チェックリスト(PDF):https://example.com/datadog-cost-checklist.pdf (※サンプル URL)
参考情報まとめ
| 項目 | 公式ドキュメント |
|---|---|
| ログ料金モデル全般 | https://www.datadoghq.com/pricing/#log-management |
| ストレージ tier と保持期間 | https://docs.datadoghq.com/logs/guide/log-retention/ |
| リハイドレーション課金詳細 | https://docs.datadoghq.com/logs/guide/re-hydration/ |
| Usage Dashboard とモニタ作成 | https://docs.datadoghq.com/monitors/create/ |
Qiita 記事(実装例):https://qiita.com/example_user/items/abcdef1234567890
App の達人 記事(キャッシュ活用):https://app-tatsujin.com/datadog-agent-api-latest-log-collection/
以上が、Datadog ログコストを体系的に削減するための実践ガイドです。公式情報とコード例・運用フローを組み合わせて、継続的な費用最適化サイクルを構築してください。