Logging — イベントを記録する
🐱 この章の目次
構造化ログの必要性
従来のプレーンテキストログは grep で検索できますが、フィールド単位のフィルタリングが困難です。
構造化ログ(Structured Logging) は、各フィールドを key-value で出力する形式であり、機械的な解析と集約を可能にします。
『インフラ大全』第 17 章でも述べられているとおり、ログは「後から検索される前提」で設計すべきです。
Python での実装
structlog を使うと、コンテキスト情報を自動付与した JSON ログを簡単に出力できます。
import structlog
structlog.configure(
processors=[
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.JSONRenderer(),
]
)
log = structlog.get_logger()
log.info("order_created", order_id="abc-123", amount=4980)
出力は以下のような JSON になります。
{"event": "order_created", "order_id": "abc-123", "amount": 4980, "timestamp": "2026-08-10T09:00:00Z"}
ログレベルの使い分け
ログレベル は重要度によってフィルタリングするための仕組みです。
| レベル | 用途 |
|---|---|
| DEBUG | 開発時の詳細情報 |
| INFO | 正常な業務イベント |
| WARNING | 潜在的な問題の兆候 |
| ERROR | 処理失敗(復旧可能) |
| CRITICAL | サービス継続不可 |
本番環境では INFO 以上を出力し、必要に応じて動的にレベルを変更できる設計が望ましいです。
Correlation ID でログをつなぐ
Correlation ID(相関 ID)は、1 つのリクエストに紐づくすべてのログを横断的に検索するための識別子です。 trace_id をそのまま Correlation ID として利用すれば、ログとトレースを自然に紐づけられます。
ログ集約: Loki と OpenSearch
Grafana Loki はログにフルインデックスを作らず、ラベルだけでインデックスする軽量な集約基盤です。
Prometheus と同じラベルモデルを使うため、メトリクスと同じ {service="order"} で絞り込めます。
一方、全文検索が必要な場合は OpenSearch(Elasticsearch 互換)が適しています。
ログとメトリクスの使い分け
- 「何回起きたか」「傾向はどうか」→ メトリクス
- 「そのとき何が起きたか」「具体的なペイロードは何か」→ ログ
高トラフィック環境で全リクエストをログに残すとストレージコストが膨大になるため、サンプリングやログレベルで量を制御します。