本番のエラーログに長いスタックトレースがびっしり出て、どこを見ればいいのか一瞬手が止まりつつも、落ち着いて自分たちのコードの行を探しはじめた一人運用の保守担当者

スタックトレースの読み方|どこで落ちたかを最短で特定する手順

「なんかエラーで落ちてます」と言われてログを開いたら、見慣れない英語の行が画面いっぱいに、何十行も並んでいる。at ...File "..."Caused by ...——どれも似たような行に見えて、どこから読めばいいのか分からない。とりあえず一番上をコピーして検索してみるけれど、いまいちピンとこない。そうこうしているうちに、「まだ直らない?」の催促だけが増えていく——。

そんな経験、ありませんか。

スタックトレース(例外が発生するまでの、プログラムの呼び出しの足あと)は、長いだけで身構えてしまいますが、全部を読む必要はありません。大事なのは、その長い行の中から「本当に見るべき数行」を拾い出して、どこで・なぜ落ちたのかにたどり着くこと。この記事では、スタックトレースを最短で読み解くための順番を、言語ごとの「発生箇所は上か下か」の違いも含めて、一人運用の目線で整理します。まずは「どこに自分たちのコードがあるか」を探すところから、一緒に見ていきましょう。

結論:長いスタックトレースは、①例外の種類とメッセージ(一番大事な「何が起きたか」の一文)を読む ②自分たちのコードの行を探す(フレームワークやライブラリの行は飛ばし、自社のファイルパスが出てくる一番深いところを見る)③Caused by などの「本当の原因」をたどる(表に出た例外の裏に、根っこの例外が隠れていることが多い)④再現条件につなげる(どの入力・どのタイミングでそこを通るかを考える)——の順で進めます。まずは①の「何が起きたか」の一文を見つけるところから。

言語やフレームワーク、ログの設定によって、行の並び方や表記は変わります。ここで示すのは「どんな言語でも通用する読み方の軸」です。実際の対処は、本番へ反映する前に検証環境と公式情報で確認してください。

そもそもスタックトレースは何を表しているか

長いスタックトレースから「例外の種類とメッセージ」「自分たちのコードの行」「本当の原因」の三つを拾って読む順番を示した図
全部を読まず、「種類とメッセージ → 自社コードの行 → 本当の原因」の順に拾う

読み方の前に、スタックトレースが何を写したものかだけ、押さえておきます。ここが分かると、長い行の意味が急に整理されます。

プログラムは、ある関数(処理のまとまり)が別の関数を呼び、それがまた別の関数を呼ぶ……という入れ子で動いています。エラーが起きた瞬間、その「今どこを通ってきたか」の足あと——呼び出しの積み重なり(スタック)を一覧にしたものが、スタックトレースです。

つまり、at ...File "..." の一行一行は、「この関数が、この行で、次の関数を呼んだ」という通り道の記録です。ずらっと並んでいるのは、エラーが深いところで起きたぶん、そこにたどり着くまでの道のりが長かった、というだけのこと。だから、全部を読む必要はなく、「自分たちのコードが通った場所」と「本当に落ちた一点」だけを拾えばいいわけです。

スタックトレースの「スタック」=関数の呼び出しが積み重なった状態のこと。エレベーターで例えると、1階から乗って各階に寄りながら上がっていった履歴のようなもの。エラーは、いちばん奥まで進んだ先で起きています。

まず「例外の種類とメッセージ」を読む

長いトレースの中で、いちばん情報量が多い一行があります。例外(エラー)の種類と、その説明メッセージです。ここを最初に読むと、「そもそも何が起きたのか」の当たりが一気につきます。

多くの言語で、この一行はだいたいこんな形をしています。

例外の種類: 具体的な説明メッセージ

例(言語ごとに表記は違いますが、考え方は同じ):

NullPointerException: Cannot invoke "User.getName()" because "user" is null
TypeError: 'NoneType' object is not subscriptable
Error: connect ECONNREFUSED 127.0.0.1:5432
PDOException: SQLSTATE[HY000] [2002] Connection refused

ここで読み取りたいのは、次の2つです。

この一文を読むだけで、「あ、DBにつながっていないのかも」「どこかで値が空のまま使われたな」と、調べる方向が定まります。まずここ、と決めておくだけで、長いトレースへの身構えは、ずいぶん軽くなります。

発生箇所は「上」か「下」か——自分たちのコードを探す

Pythonは一番下、Javaやそれ以外の多くの言語は一番上に近い側が発生箇所という、言語ごとの読む向きの違いを示した図
発生箇所が上か下かは言語で違う。迷ったら「自社コードが出る一番深い行」を見る

例外の種類が分かったら、次は「どこで落ちたか」です。ここで一つ、つまずきやすいポイントがあります。「実際に落ちた場所」が、トレースの上にあるか下にあるかは、言語によって逆なのです。

言語ごとの向きを毎回覚えていなくても大丈夫な、どの言語でも効く探し方があります。それは、「自分たちのコードのファイルパスが出てくる行」を探すこと。

トレースの大半は、フレームワークやライブラリ(vendor/site-packages/node_modules/org.springframework... など)の中を通った記録で、そこは基本的に「通り道」にすぎません。あなたが直せるのは、自社のソースが置かれた場所app/src/、自社ドメインのパッケージ名など)です。だから、

  1. まず自社のファイルパスが出てくる行にだけ目印をつける
  2. その中で、いちばん深い(例外の発生に近い側の)行を、最初の容疑者とする

とすれば、上か下かで迷っても、見るべき数行に自力でたどり着けます。「ライブラリの奥で落ちているように見えても、そこへ渡した値や呼び出し方に原因があることが多い」——だから、自分たちのコードが最後に関わった行が、いちばん調べ甲斐のある場所になります。

「一番目立つ例外」が真犯人とは限らない——Caused by を追う

ここが、スタックトレースでいちばん引っかかりやすいところです。表に出ている例外の裏に、本当の原因になった別の例外が隠れていることがよくあります。

Java でいう Caused by: がその代表です。一つのトレースの中に、

...(表向きの例外)...
Caused by: ...(本当の原因の例外)...
Caused by: ...(さらにその原因)...

と、Caused by が続けて出ることがあります。これは、「Aという処理が失敗した。なぜなら、その内側でBが失敗したから。さらにBは、Cが失敗したから」という原因のつながりを表しています。

このとき見たいのは、いちばん最後(根っこ)の Caused by です。表向きの例外(たとえば「データの取得に失敗しました」)だけを見て検索しても解決しないのは、根っこ(たとえば「DBに接続できなかった」)を見落としているから、というのはよくあるパターンです。

Caused by という言葉が出ない言語でも、考え方は同じです。

一番上(または一番目立つ場所)の例外は、あくまで最終的に表に出た結果。真犯人は、その奥にいることがある——そう思って一段深く見るだけで、見当違いの調査を減らせます。

影響:読む順番が決まっていると、何が変わるか

放置して毎回その場の勘で読んでいると、同じ種類のエラーでも、対応時間も結論もバラバラになりがちです。逆に言えば、「まず種類とメッセージ、次に自社の行、最後に根っこの原因」と順番を一度決めておけば、初めて見るトレースでも、落ち着いて糸口を手繰れます。

明日やること:手元のエラーで「読む順番」を1回なぞる

  1. 直近で出た本物のエラーログ(テスト環境や過去の障害記録でよい)を一つ開き、例外の種類と説明メッセージの一行がどれかを、指でなぞって特定してみる。
  2. その同じトレースで、自社のファイルパスが出ている行にだけ印をつけ、その中の「いちばん深い行」を見つけてみる。使っている言語で発生箇所が上か下かも、あわせて確認しておく。
  3. Caused by や「上の例外が原因」といった連鎖の表示があるかを探し、あれば根っこ(最後の原因)まで下りて読む。
  4. 余力があれば、よく落ちるポイントについて、「この例外が出たら、まずこの行を見る」という一言メモを、運用ドキュメントや対応履歴に一行だけ残しておく。

ここまでで15〜20分ほど。一度この順番で読み通しておくと、次に本番でトレースが出たとき、画面いっぱいの行に飲まれずに、見るべき数行へ手が伸びるようになります。

スタックトレース読み解きチェックリスト

最低ライン(優先順位つき:これだけで当たりがつく) 1) 種類とメッセージを読む:例外の「種類」と、後半の「説明メッセージ」から、何が起きたかの当たりをつける 2) 自社コードの行を探す:ライブラリ・フレームワークの行は飛ばし、自社のファイルパスが出る「一番深い行」を最初の容疑者にする 3) 根っこの原因を追う:Caused by や「上の例外が原因」があれば、連鎖の一番最後まで下りて本当の原因を見る

余力が出たら拡張

免除条件(省略可)

確認項目

よければ、こちらも

スタックトレースを読めることは、「どこで落ちたか」を最短で突き止める力です。その先の「なぜ落ちたか(再現・原因特定)」や、後から追えるようにログを仕込む工夫、エラーメッセージそのものの読み解きも、あわせて型にしておくと、調査がぐっと楽になります。

長かったスタックトレースから見るべき数行を拾えるようになり、落ち着いてエラーの糸口をつかんだことに静かに安心している保守運用の担当者

長いスタックトレースは、最初はどこから読めばいいのか分からず、それだけで気持ちが重くなるものです。でも、「種類とメッセージを読む」「自社の行を探す」「根っこの原因を追う」と順番を決めておくだけで、あの画面いっぱいの行も、ずいぶん怖くなくなります。 今日は、手元にあるエラーログを一つ開いて、例外の種類の一行を探してみるだけで十分です。全部を読まなくていい、と分かった時点で、もう調査は前に進んでいます。

ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。

関連用語