最終更新:

ログ収集の仕組み — 「注文できなかった」を記録からたどる


同じIDで追い、記録を調査につなげる

まざった記録を、IDで探すreq-demoINFO:注文開始req-otherINFO:注文完了req-demoERROR:在庫不足req-demoの2行を読む開始 → 在庫不足の記録根本原因は、追加の調査へ調べるまでの4つの役割① 記録アプリの出来事② 収集出力を取り込む③ 保存期間・権限を決める④ 検索時刻・サービス・ID
左は架空の練習用ログ、右はログを扱う役割です。レベルや形式は道具によって違い、記録していない出来事まで分かるわけではありません。
⏱ 学習時間の目安 読むだけで概要をつかみ、手元で1つの例を確認
📚 前提知識 会話と図だけでも読めます。コードを試す場合は本文の環境を用意してください。
✅ このガイドで学べること
  • 身近な例で仕組みを説明できる
  • 例の入力と結果を比べ、成立条件を確認する
ひよこ ひよこ
「注文できなかった」と言われたら、何を見るの?
ペンギン先生 ペンギン先生
まずその注文処理のログを探そう。ログは、アプリが残した出来事の記録だよ。開始、成功、失敗といった情報があれば、何が起きたかを調べる手掛かりになるんだ。
ひよこ ひよこ
時刻だけで探せばいい?
ペンギン先生 ペンギン先生
時刻に加えて、同じリクエストを示すIDがあると探しやすいよ。下の例ではreq-demoというIDで絞り、「注文開始」と「在庫不足」の2件を見るんだ。別の注文の記録と混ざらず読めるね。
ひよこ ひよこ
ログは普通の文章でもいいの?
ペンギン先生 ペンギン先生
人が読む文も使えるよ。JSONなどで時刻、重要度、サービス、IDを項目として分ける構造化ログなら、道具で絞り込みやすくなる。形式より、調べたい情報を一貫して残すことが先だね。
ひよこ ひよこ
INFOやERRORは何を表すの?
ペンギン先生 ペンギン先生
出来事の重要度だよ。名前や段階は道具によって異なる。例えばPython標準のloggingにはDEBUG・INFO・WARNING・ERROR・CRITICALがある。「すべてのログが必ず5段階」ではないんだ。
ひよこ ひよこ
何でも残せば困らない?
ペンギン先生 ペンギン先生
パスワードやアクセストークンなどは残さないようにしよう。量が増えると保存費用や検索の負担も増す。必要な調査項目を決め、個人情報は必要性と扱いを確認するんだ。
ひよこ ひよこ
何台ものサーバーのログはどう集めるの?
ペンギン先生 ペンギン先生
収集する係がファイルや標準出力から取り込み、保存先へ送り、検索できるようにするよ。まずは小さな構成で十分な場合もある。途中にキューを置くかどうかは、量や障害時の扱いで決めるんだ。
ひよこ ひよこ
集めたら原因が全部分かる?
ペンギン先生 ペンギン先生
記録していない出来事は分からないし、同時に起きたことが原因とは限らないよ。収集の遅れや欠落も確認し、必要ならメトリクスやトレースと突き合わせる。ログは手掛かりであって、答えが自動でそろうわけではないんだ。
ひよこ ひよこ
ログはいつまで残すの?
ペンギン先生 ペンギン先生
調査目的、契約や法令、費用で決めるよ。どんな監査ログも一律7年ではない。閲覧できる人、保存期間、削除方法まで決めよう。「何のための記録か」を先に考えると整理しやすいね。

まずは、同じ注文の2件を見つける

次は架空の注文サービスの練習用ログです。1行に1つのJSONを置き、orders-demo.jsonlとしてUTF-8で保存してください。時刻末尾のZはUTCを表しています。

{"time":"2026-10-09T10:00:00Z","level":"INFO","request_id":"req-demo","event":"order_started"}
{"time":"2026-10-09T10:00:01Z","level":"INFO","request_id":"req-other","event":"order_completed"}
{"time":"2026-10-09T10:00:02Z","level":"ERROR","request_id":"req-demo","event":"stock_unavailable"}

req-demoだけを読むと、注文開始のあと、在庫を用意できなかったという記録が見つかります。間に別のリクエストの成功があるので、時刻の順だけで一続きの注文だと判断しないことがポイントです。

Python 3が使える場合は、同じフォルダーにfind-order.pyを保存し、そのフォルダーでpython find-order.pyを実行してみましょう。環境によってはpython3を使います。

import json
from pathlib import Path

log_file = Path(__file__).with_name(
    'orders-demo.jsonl'
)
text = log_file.read_text(encoding='utf-8')
for line in text.splitlines():
    event = json.loads(line)
    if event['request_id'] == 'req-demo':
        print(
            event['level'], event['event']
        )

結果は次の2行です。IDをreq-otherに変えると、別の注文の成功だけが出ます。

INFO order_started
ERROR stock_unavailable

これは練習用の固定データで、実際の注文システムではありません。stock_unavailableがなぜ起きたかは、在庫や通信の状態など追加の調査が必要です。ログに書かれた失敗理由と、根本原因は区別しましょう。

集める仕組みは「記録 → 収集 → 保存 → 検索」

  1. アプリが、必要な出来事を記録します。
  2. 収集する係が、その出力を読み取ります。
  3. 保存先へ送り、必要な期間保管します。
  4. 調べたい時刻・サービス・IDで検索します。

小さなアプリではまずファイルを読むだけでも始められます。複数台になったら収集ツールやマネージドサービスを検討します。キューやバッファーを必ず別サービスとして挟むわけではありません。送信に失敗したときの再試行、重複、欠落と、収集側の健康状態も確認してください。

何を入れるか、何を入れないか

項目役立つ場面
時刻とタイムゾーン前後関係や他サービスとの照合
レベル・出来事の名前失敗や特定の処理の検索
サービス名どのアプリの記録かの区別
リクエストID同じ処理の関連記録を追う

パスワード、アクセストークン、秘密鍵、接続文字列などをそのまま記録しないようにします。個人情報も調査目的に必要な範囲を確認し、除去やマスキングなどを検討します。JSONは文字列を手で連結せず、ライブラリーで正しくエンコードしてください。入力の改行などが、別のログ行として解釈される問題にも注意します。

Pythonの標準loggingと他の道具ではレベル名が違う場合があります。DEBUGだから必ず開発だけ、INFOだから何を出してもよい、という決め方はせず、調査目的と量、機密性で出力を設計します。

もう少し詳しく:メトリクス・トレース・保管

メトリクスは件数や応答時間などの数値、トレースは処理がサービス間を通った経路を調べる手段です。OpenTelemetryのログモデルではTraceIdなどを使って関連付けできます。ただし、練習用のreq-demoは単なる独自IDで、W3CのTraceId形式ではありません。

リクエストごとのIDを、Prometheusのメトリクスのラベルへ無制限に入れると、時系列が増えすぎます。ログで探すIDと、メトリクスで集計する分類は同じ設計にしないようにしましょう。

ログローテーションは、サイズや日付でファイルを切り替える仕組みです。別の保管先へアーカイブすることや、何年残すかという保持方針とは分けて考えます。ログの閲覧権限や通信経路、改ざんへの対策も、記録の用途に合わせて決めてください。

覚え方と次の一歩

「ログ」って出てきたら「あとから出来事をたどるための記録」と思えばだいたいOK!

まず同じIDの記録を探し、その次にPrometheus入門で数値の観測、ログの用語解説で基本を整理できます。

参考資料