MENU

ログの見方入門|エラー調査で見るべきポイントと手順

ログの見方入門|エラー調査で見るべきポイントと手順

ログが読めると、エラー調査はかなり速くなります。見るべきなのは大量の行全体ではなく、発生時刻、重要度、どの処理で起きたか、直前直後の流れです。

たとえば「画面で 500 エラーが出た」「バッチが失敗した」「特定ユーザーだけ処理が落ちる」といった場面では、まず時刻を決め、対象サービスを絞り、同じ処理にひもづく行だけを追うのが基本です。上から順に全部読むやり方では、必要な情報にたどり着く前に時間を失いやすくなります。

  • 何ができるか: ログの基本的な読み方、調査の順番、journalctl・Nginx・Python ログの見方をまとめて把握できます
  • どんな場面で使うか: Web サービスの 500 エラー、定期実行ジョブの失敗、サーバー側の不具合切り分けで役立ちます
  • 想定読者: ログ調査に慣れていない初心者から、実務初級レベルの担当者
  • 前提環境: Linux の systemd 環境、Nginx、Python 3 系のアプリログを例に説明します
目次

先に結論

ログ調査で最初にやるべきことは、「いつ」「どの処理で」「誰に起きたか」を固定することです。

エラー文だけ先に探すと、関係ない過去ログや別ユーザーの失敗まで拾ってしまいます。先に軸を決めると、見る範囲が一気に狭まります。

ここがポイント: ログは「上から全部読む」ものではなく、「時刻・対象・関連キーで絞ってから前後を見る」ものです。

ログで最低限見るべき項目

見慣れないログでも、まず次の項目を拾えば意味が見えやすくなります。

  • 時刻: いつ発生したか。画面の操作時刻や監視アラート時刻と突き合わせる基準になります
  • レベル: ERRORWARNINGINFODEBUG など。重要度の当たりを付けるために使います
  • 発生元: アプリ名、サービス名、モジュール名、ファイル名、URL など。どこで起きたかを示します
  • メッセージ本文: 何が失敗したか。例外名、失敗理由、対象 ID が入ることがあります
  • 関連キー: リクエスト ID、ユーザー ID、ジョブ ID、PID など。同じ処理を横断して追うための手がかりです

たとえば次のような 1 行があれば、読む順番はかなり決まります。

2026-04-21 10:14:32 ERROR payment.api request_id=8f31 user_id=204 timeout while calling /charge

この 1 行からでも、次のことが分かります。

  • 発生時刻は 2026-04-21 10:14:32
  • 重要度は ERROR
  • 発生元は payment.api
  • 同じ処理を追う鍵は request_id=8f31
  • 問題は決済 API 呼び出しのタイムアウト

ここで本当に見るべきなのは、この 1 行そのものよりも、同じ request_id の直前直後に何が出ているかです。

エラー調査の基本手順

見方に慣れていないうちは、毎回同じ順番で確認するとブレにくくなります。

1. 事象を一文で固定する

最初に、調べる対象を短く言い切ります。

  • 例: 「4月21日 10:14 ごろ、決済 API で 500 が出た」
  • 例: 「定期バッチが 6:00 実行分だけ失敗した」
  • 例: 「A さんの CSV 取込だけエラーになる」

この一文が曖昧だと、後の検索条件も曖昧になります。

2. 時刻範囲を狭くする

ログはまず時間で絞ります。障害発生時刻の前後 1 分から 5 分くらいを起点にするのが実務では扱いやすい範囲です。

時間で絞る理由は単純で、同じエラーメッセージが別のタイミングにも出ていることが珍しくないからです。時間を決めない検索は、古い失敗と今の失敗を混ぜやすくなります。

3. レベルで当たりを付ける

次に ERRORWARNING を見ます。ただし、ERROR の 1 行だけで原因を決めないことが重要です。

  • ERROR: 処理失敗や例外
  • WARNING: 失敗の前触れ、再試行、設定不整合
  • INFO: 通常の進行ログ。処理の流れをつなぐのに使います
  • DEBUG: 詳細調査向け。開発時や一時的な深掘りで有効です

失敗の原因は、ERROR ではなく、その少し前の WARNINGINFO に出ていることがよくあります。

4. 同じ処理を関連キーで追う

次のようなキーがあれば、必ず使います。

  • request_id
  • trace_id
  • job_id
  • user_id
  • PID
  • サービス名やユニット名

同じ時刻帯に複数ユーザーの処理が流れている環境では、関連キーなしで読むと混線します。特に API やバッチでは、1 件の失敗を他の正常処理が埋もれさせがちです。

5. 直前直後を見る

原因調査では、エラー行の前後を見る癖が重要です。

  • 直前: 入力値、接続先、再試行、認証、外部 API 呼び出し
  • 直後: ロールバック、終了コード、補助的な例外、二次障害

「最後に出たエラー」が本当の原因とは限りません。最初の失敗が連鎖して、あとから別のエラーが大量に出ることもあります。

6. 再現条件と改善点を分けてメモする

ログを読んでいる途中で、原因候補と対策候補が頭の中で混ざりやすくなります。次の 2 つを分けて残すと整理しやすくなります。

  • 再現条件: いつ、どの入力で、どの操作をすると起きるか
  • 改善点: タイムアウト延長、入力チェック追加、ログ項目追加など

journalctl で systemd サービスのログを見る

Linux サーバーで systemd を使っているなら、まず journalctl を押さえると調査が進みやすくなります。公式マニュアルでも、時間、ユニット、優先度で絞り込めます。

よく使う確認コマンド

journalctl -u myapp.service --since "2026-04-21 10:10:00" --until "2026-04-21 10:20:00"

特定サービスの指定時刻帯だけを見る例です。

journalctl -u myapp.service -p err --since "2026-04-21 10:10:00"

err 以上の重要度に絞る例です。journalctl の優先度は emerg から debug までの syslog レベルに対応しています。

journalctl -f -u myapp.service

リアルタイム監視です。再現操作をしながら確認するときに使います。

どこを見るべきか

journalctl では、次の観点で読むと迷いにくくなります。

  • ユニット名: -u で対象サービスを固定する
  • 時間: --since--until で混線を防ぐ
  • 優先度: -p err-p warning で当たりを付ける
  • 出力追跡: -f で再現時の変化を見る

アプリの失敗だと思っていたら、実際にはサービス再起動や依存先停止が先に起きていた、というケースもあります。まずサービス単位で切るのは、その切り分けに向いています。

Nginx ログは access と error を分けて読む

Web サービスでは、Nginx の access_logerror_log を混ぜずに見るのが基本です。役割が違うからです。

  • access_log: どのリクエストが来て、どう返したかを確認する
  • error_log: サーバー側で何が失敗したかを確認する

Nginx の公式ドキュメントでは、access_log は指定したフォーマットでリクエストログを書き出せます。

access log で確認したい項目

よくある combined 形式では、次の情報が追いやすくなります。

  • リクエスト時刻
  • メソッドとパス
  • ステータスコード
  • 送信バイト数
  • リファラー
  • ユーザーエージェント

例:

192.0.2.10 - - [21/Apr/2026:10:14:32 +0900] "POST /charge HTTP/1.1" 500 612 "https://example.com/pay" "Mozilla/5.0"

ここでは POST /charge に対して 500 が返っています。HTTP ステータスの定義では、500 はサーバーが予期しない条件に遭遇したことを示す一般的なサーバーエラーです。

error log で確認したい項目

error_log では、接続失敗、アップストリームの応答不良、設定ミスなどが見つかります。

例:

2026/04/21 10:14:32 [error] 2145#2145: *881 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.0.2.10, server: example.com, request: "POST /charge HTTP/1.1", upstream: "http://127.0.0.1:8000/charge"

この行で大事なのは、単に「タイムアウトした」ではありません。

  • どの要求か: POST /charge
  • どの接続先か: http://127.0.0.1:8000/charge
  • どの段階で止まったか: レスポンスヘッダー読取中
  • 誰の要求か: client: 192.0.2.10

つまり、ブラウザの問題ではなく、Nginx の先にいるアプリケーション応答が遅い可能性が高いと読めます。

Python アプリログは「最低限の項目」を最初から入れる

アプリログが読みづらい原因の多くは、調査側の読み方よりも、出している項目が足りないことです。Python の logging では、時刻、ロガー名、レベル、メッセージを簡単にそろえられます。

最小構成の例

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s request_id=%(request_id)s %(message)s",
)

logger = logging.getLogger("payment.api")
logger.error("charge failed", extra={"request_id": "8f31"})

出力例:

2026-04-21 10:14:32,120 ERROR payment.api request_id=8f31 charge failed

この形にしておくと、調査時に次の点が揃います。

  • いつ起きたか
  • どのモジュールか
  • どの重要度か
  • 同じ処理を追えるか

逆に、本文だけのログは後で困ります。

charge failed

これでは時刻も対象処理も分からず、複数件の失敗が混ざった瞬間に追跡できません。

例外を出すときの注意

Python のログでは、単に「失敗した」と書くより、何の処理が、何に対して失敗したかを残すほうが重要です。

悪い例:

logger.error("error")

改善例:

logger.error("failed to charge order_id=%s", order_id)

ログは読んだ瞬間に検索条件へ変換できる文であるほど、実務では強くなります。

入力例と調査の進め方

ここでは、Web アプリで 500 エラーが出た場面を想定して、ログをどうつなぐかを整理します。

入力例

  • 発生時刻: 2026-04-21 10:14 ごろ
  • 症状: 決済画面で送信後に 500 エラー
  • 対象 URL: /charge
  • 対象サービス: myapp.service

確認の順番

  1. Nginx の access_log/charge500 を探す
  2. 同じ時刻の error_log で upstream や timeout を確認する
  3. journalctl -u myapp.service --since ... でアプリ側ログを見る
  4. 可能なら request_id や注文 ID でアプリログを絞る
  5. 直前に DB 接続失敗、外部 API タイムアウト、例外スタックがないか確認する

出力の読み分け

  • access_log500 がある
  • 利用者にエラーが返った事実を示します
  • error_logupstream timed out がある
  • Nginx 自身ではなく、上流アプリ応答が遅い可能性が見えます
  • アプリログに database connection refused がある
  • 真の原因はアプリ内部、さらにその先の DB 接続失敗だと絞れます

このように、利用者に見えた失敗、Web サーバーが見た失敗、アプリが見た失敗を順に重ねると、原因まで届きやすくなります。

よくある失敗と改善例

初心者がはまりやすい点は似ています。先に知っておくと無駄な遠回りを減らせます。

エラー行だけ見て終わる

  • NG: 最後の ERROR 1 行だけ見て原因と決める
  • 改善: その前後 10 行から 50 行、同一キーの流れまで追う

時刻を合わせない

  • NG: ログ全体からキーワード検索だけする
  • 改善: まず発生時刻を 1 分から 5 分単位で切る

access log と error log を混同する

  • NG: 500 が出たら access log だけで原因を探す
  • 改善: access log で事実確認、error log とアプリログで原因確認に分ける

重要な項目をログに出していない

  • NG: something went wrong のような曖昧なメッセージだけ残す
  • 改善: request_id、対象 ID、処理名、接続先を入れる

DEBUG を常時大量出力する

  • NG: 平常時から詳細ログを出し続け、必要な行が埋もれる
  • 改善: 普段は INFOWARNING 中心、深掘り時だけ一時的に DEBUG を有効化する

関連ツールと使い分け

ログ確認は 1 つの方法に固定しなくて構いません。目的ごとに使い分けるほうが実務向きです。

  • journalctl
  • systemd 管理サービスの調査に向く。時間、ユニット、優先度で絞りやすい
  • Nginx のログファイル
  • HTTP リクエスト単位で追いやすい。500404、特定パスの確認に強い
  • アプリケーションログ
  • 業務 ID や入力値に近い文脈が取れる。原因の最終特定に必要になりやすい
  • 集約ログ基盤
  • 本記事では詳細に触れませんが、複数サーバーや複数サービス横断で調べるなら有効です

小規模環境なら、まずは journalctl とアプリログの整備だけでも調査効率はかなり変わります。

最後に見るべきチェックポイント

ログ調査で迷ったら、次の順に戻ると立て直しやすくなります。

  • 事象を一文で言えるか
  • 発生時刻を固定したか
  • 対象サービスや URL を絞ったか
  • ERROR の前後を見たか
  • 同じ request_idjob_id を追ったか
  • 利用者視点の失敗と、サーバー内部の失敗を分けて読んだか

ログは量が多いほど難しく見えます。ただ、見る順番が決まれば、調査は急に進めやすくなります。次に 500 エラーやバッチ失敗に当たったら、まず「時刻」「対象」「関連キー」の 3 つから切ってみてください。

参照リンク

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次