月に数回だけ、夜間バッチが止まる。
毎回ではありません。大半の日は正常に終わるのに、ある条件が重なったときだけ処理が途中で止まります。ログを見ても、最初は原因らしいものが見つかりませんでした。
原因不明の不具合を調べていると、何時間調べても前へ進んでいないように思えることがあります。私も、夜中までログを追い、古い仕様書をめくりながら、原因が見つからない時間を何度も経験しました。
この記事では、5年前の仕様まで調べて原因にたどり着いた経験から、調査が進まないときに何を確認し、どう作業を続けたのかを書いていきます。
月に数回だけ止まる夜間バッチ
調査したのは、金融系システムの夜間バッチでした。
通常は問題なく終了します。
でも不思議なことに、月に数回だけ、処理が途中で止まることがありました。
毎回発生する不具合なら、同じ操作を繰り返しながら原因を追えます。でも今回のように発生頻度が低いと、再現させるだけでも時間がかかります。
最初は、実行時刻やサーバーの負荷、データ件数などを疑いました。
ログを追加し、条件を変えて実行し、結果を確認する。違えば、また別の可能性を考える。その繰り返しです。
数回試して原因が分からないと、
「見ている場所が違うのではないか」と不安になります。いや、実際に違っていることもあります。
ただ、そこで思いつくままに調査範囲を広げると、今度は何を確認したのか分からなくなります。
原因が見つからないときほど、
調査範囲を広げる前に、分かったことと分からないことを分ける必要があります。
5年前の仕様書まで戻った理由
調査を続けるうちに、
特定の入力データが含まれるときだけ停止する可能性が見えてきました。
ただし、そのデータが入っていれば必ず止まるわけではありません。正常に終わるケースもありました。
「同じように見えるデータの何が違うのか」
そこから、正常終了したデータと停止したデータを並べ、項目ごとに違いを確認しました。
文字数、空欄、日付、コード値。
最初はどれも決定的な違いには見えません。
何度見ても分からず、日付が変わってからもログとデータを行き来していました。正直、途中から画面の文字が頭に入ってこなくなります。
それでも、過去の改修履歴を調べていると、
対象の項目が5年ほど前に追加されていたことが分かりました。
現在の仕様書だけを見ると、その項目は必須に見えます。しかし、追加当時の資料まで戻ると、移行期間中だけ空欄を許す設計になっていました。
古いデータの一部には、その当時の条件が残っていたのです。
最終的な原因は、特定の入力パターンでNULLチェックをすり抜ける条件分岐でした。
コードだけを見れば、一行の問題です。
ただ、その一行がなぜ必要だったのかは、現在の資料だけでは分かりませんでした。5年前の仕様変更と古いデータの扱いを確認して、ようやく処理が止まる流れがつながったのです。
原因より先に再現条件を探した
不具合が起きると、すぐに
「どのコードが悪いのか」を探したくなります。
私も最初は、停止した周辺の処理ばかり見ていました。しかし、コードを読み続けても原因候補が増えるだけで、なかなか絞れません。
調査が動き始めたのは、
原因を当てようとするのをやめて、「どんなときに起きるのか」を整理してからでした。
実際には、次のような違いを記録しました。
- 停止したときの入力データ
- 正常終了したときの入力データ
- 実行した日時と環境
- 処理が止まる直前のログ
- 同じ条件で再実行した結果
ここで大切だったのは、
異常なケースだけでなく、正常だったケースも残したことです。
たとえば、特定の項目が空欄でも正常に終わるケースがあれば、「空欄だけが原因ではない」と分かります。原因にはたどり着いていなくても、可能性を一つ消せています。
不具合調査では、原因を見つけた回数ではなく、
原因ではない条件をどれだけ確認できたかも前進です。
不具合調査も、一度で正解を当てられるとは限りません。外れた仮説も無駄ではなく、「この条件は原因ではない」と分かれば、次に調べなくてよい範囲が一つ増えます。
原因を直接見つけられなくても、可能性を一つずつ消していくことは調査の前進です。
深夜の調査で事実だけを書き出した
夜中まで調査が続くと、考えがだんだん雑になります。
同じログを何度も開いたり、
さっき確認した条件をもう一度試したりすることもあります。
「何か見落としている気がする」
そう思うほど、調査範囲を広げたくなります。
しかし、疲れている状態で思いつきの確認を増やしても、結果が整理できません。
そこで私は、いったん原因の予想を書くのをやめ、確認できた事実だけを残すことにしました。
たとえば、次のような短い記録です。
| 記録する内容 | 実際に残すこと |
|---|---|
| 発生条件 | どの入力、時刻、環境で止まったか |
| 正常条件 | 似たデータでも止まらなかった条件 |
| 試した内容 | ログ追加、設定変更、再実行の結果 |
| 未確認事項 | まだ見ていない処理やデータ |
| 次に試すこと | 次回の調査で確認する仮説 |
きれいな報告書を作る必要はありません。
私の場合は、箇条書きや表に短く残す程度でした。
それでも、「どこまで確認したか」が見えるだけで、同じ調査を繰り返しにくくなります。
また、翌日に別のメンバーが見ても、
調査を最初からやり直さずに済みました。
気持ちが折れそうなときにも、この記録は役に立ちます。
原因が見つからないと、何時間作業しても何も進んでいないように思えます。しかし、「この条件は除外できた」「ここまでは正常だった」と書かれていれば、少なくとも昨日と同じ場所にはいません。
一人で抱えるほど調査が遅くなった
以前の私は、不具合調査を最初から最後まで一人で進めようとすることがありました。
ログを読む。コードを調べる。再現手順を作る。修正案を考える。テストする。
一人で把握したほうが早いと思っていたのです。でも原因不明の不具合では、この進め方がかえって遅くなることがあります。
ログを調べている間はテストが止まり、
コードを読んでいる間は再現条件の確認が止まります。すべての作業が順番待ちになるためです。
ある調査では、途中から役割を分けました。
私は再現条件の整理に集中し、改修担当には該当コードの確認を依頼しました。テスト担当には、私がまとめた条件をもとに、別の入力パターンを試してもらいました。
- 私は、どの条件で発生するかを絞る
- 改修担当は、該当する条件分岐を確認する
- テスト担当は、見落としそうな組み合わせを試す
この形に変えると、調査と検証を同時に進められるようになりました。
ただし、単に人数を増やせばよいわけではありません。
「原因不明なので見てください」と渡しても、相手もどこから始めればよいか分かりません。私が共有したのは、調査途中の長い説明ではなく、発生条件と未確認事項をまとめた短いメモでした。
何が分かっていて、何を調べてほしいのか。
そこまで整理して初めて、分業が機能します。
不具合調査でも、同じ作業を複数人で繰り返すだけでは効率は上がりません。再現条件を整理する人、コードを見る人、別の入力パターンを試す人と役割を分けた方が、調査を並行して進められます。
自分が全部解決することより、次の人が動ける形にして渡すほうが早い場合があります。
調査が止まったときに確認すること
原因が分からない状態が続くと、つい新しい仮説ばかり考えたくなります。
ただ、仮説を増やす前に、私は次の点を確認するようにしています。
再現条件を言葉にできるか
「たまに止まる」だけでは、まだ調査の入口です。
どのデータ、どの時刻、どの環境で起きたのか。
完全に再現できなくても、共通点を言葉にできれば調査範囲を狭められます。
正常なケースと比べたか
異常なデータだけを見続けると、
そのデータのすべてが怪しく見えてきます。
正常に動いたケースと並べることで、本当に違う部分が見えやすくなります。
同じ確認を繰り返していないか
長時間の調査では、
自分でも気づかないうちに同じことを試します。
記録があれば、「これはすでに確認済み」と判断でき、その時間を別の調査に使えます。
古い仕様や改修履歴を見たか
現在のコードが理解できても、
なぜその処理になったのかまでは分からない場合があります。
古いデータや例外処理が関係していそうなら、現在の仕様だけでなく、導入当時の資料や改修履歴まで戻る必要があります。
一人で抱えすぎていないか
長く調べている人ほど、
無意識に前提を固定してしまいます。
別の人に状況を説明すると、
「なぜそこを原因だと思ったのか」と聞かれ、自分の思い込みに気づくことがあります。
まとめ
原因不明の不具合調査では、原因が見つからない時間が長く続きます。
私が担当した夜間バッチも、最終的な原因は一行の条件分岐でした。しかし、そこへたどり着くには、正常ケースとの比較、何度もの仮説検証、5年前の仕様書の確認が必要でした。
大きなひらめきで解決したわけではありません。
分かったことを記録し、原因ではない可能性を一つずつ消し、必要なところで役割を分けた結果です。
調査が進んでいないように見える日でも、再現条件が一つ分かったなら前進しています。関係のない処理を一つ外せたなら、それも前進です。
原因を早く当てようとするより、次に調べる範囲を少し狭くする。私は今でも原因不明の不具合に出会うと、まずそこから始めています。


コメント