「修正した」と「反映された」は別物。デプロイ後に必ず見る3つの数字
「コード直してmasterにマージした。テストも通ってる。これで復旧」
そう思って閉じた翌朝、また同じエラーが飛んできた経験はないか。
うちで実際にあった。X投稿の自動化が4日間で20回連続失敗してたのに、ログには「クロスポスト成功」と書いてあった。
ログを信じすぎるな
silent failureの怖いところは、修正コードを入れた後も「成功」メッセージが出続けることだ。
旧コードでも新コードでも、同じ成功ログが書かれる仕組みになってると、人間は「直った」と勘違いする。
実際にやらないといけないのは2つ。
**動いてるプロセスのPIDと起動時刻を確認する**
**その時刻が、修正コミットの時刻より新しいか比較する**
これだけ。コミット時刻より古い起動時刻なら、masterにマージしようがpushしようが、まだ旧コードで動いてる。「マージ=反映」ではない。再起動するまで世界は何も変わってない。
「成功ログ」の代わりに見るもの
ログ確認だけで完了報告するクセを捨てる。代わりに見るのはこの3つ。
プロセスの起動時刻:再起動できてるか
DBの状態変化:本来更新されるべきレコードが更新されてるか
外部の最終状態:投稿系ならX/Qiita側のタイムラインを目視
外部に出ていく系の修正は、最後の「目視」を絶対サボらない。これを省略した瞬間、4日後にまた同じエラーで起こされる。
safety guardは別レイヤーで張る
うちの sns-hub では schedule の status='running' が15件滞留してた。本来失敗時に handle_failure が呼ばれて status を遷移させるはずが、何かの拍子で抜けてた。
ログが消えてて根因特定は無理。でも放置するわけにいかない。
そこで `check_pending_schedules` の冒頭に safety guard を追加した。stale な running を検知したら強制で failed に終端する。これで再発時は自動で回収される。
根因の特定と、再発防止は別レイヤーで対処する。完璧に原因を突き止めるまで動かないより、ガードを1枚足して回し続けるほうが現実的なケースは多い。
まとめ
ログの「成功」を信じない。プロセスのPIDと起動時刻を見る
masterマージ済み≠コード反映済み。再起動の確認を入れる
根因不明でも safety guard で回収できればOK。完璧主義より運用継続
「修正した」のあと、何を見て「反映された」と判断してるか。一度書き出してみると、自分のチェックリストの穴が見える。