CASE · 中程度 · monitoring-gap
検証済み運営者の一次記録定期ジョブが13回連続で失敗し、5日間誰も気づかなかった
定期実行される翻訳パイプラインが、13回連続で終了コード1のまま失敗し続けていたが、5日間誰も気づかなかった。
約2分で読めます
- 発生日
- 分類
- monitoring-gap
- 影響範囲
- uptime, data
- 検知
- manual-log-review
- タグ
- #launchd #macos #monitoring #silent-failure
CH 1
原因
launchdは失敗を自分から教えてくれない。終了コードを見張る仕組みが無ければ「たぶん動いている」という思い込みしか残らない。さらに悪いことに、一部のジョブは前提条件が揃わないと exit 0 で黙って抜ける設計になっており、終了コードだけでは正常終了と見分けがつかない。
CH 2
結果
5日間、そのジョブはただ動いていなかった。それを誰も知らなかった。
CH 3
対策
定期ジョブを薄い監視レイヤーで包み、毎回の終了コードと最後の出力行を記録する。IDLE閾値はジョブごとに『そのジョブにとっての正常』を基準に設定する。完了後ずっとアイドルが正常なジョブと、毎晩動くはずが黙って空振りしうるジョブでは、必要な閾値が違う。
何が起きたか
誰も終了コードを見ていなかった。研究メモを翻訳し直すmacOSのlaunchdジョブが、
5日間にわたって静かに失敗し続けていた——13回連続、すべて終了コード1、
アラートは一件も出ない。
派手に壊れたわけではない。ただ仕事をしなくなり、それを誰にも伝えなかっただけだった。
現場の混乱
証拠は素朴なログファイルの中にあった——retranslate.logに、13回連続の
exit=1が5日間気づかれずに記録され続けていた。同じ頃、独立したもう一件の
同種の記録も残っていた。約2週間前にパスが変更されたことに気づかないまま、
バックアップスクリプトが毎晩失敗し続けていた——ただしこちらは違う理由で
サイレントだった。前提条件が揃わないと exit 0(成功)で抜ける設計だったのだ。
無関係な2つのジョブが、同じ死角にはまっていた——それぞれが報告していた 内容を、誰も読んでいなかった。
原因
自律的な定期ジョブは自分から文句を言わない。終了コードを誰も読んでいなければ、 「まだ動いている」のか「1週間死んでいる」のか外からは区別がつかない。 一部のジョブはこれをさらに悪化させる設計になっている——前提条件が揃わないと exit 0(成功)で抜けるため、非ゼロの終了コードを見張るだけでは不十分で、 そのジョブにとっての「健全な沈黙」が何かを知っておく必要がある。
対策
現在は最小限のカーネルが定期ジョブのうち6本を「preflight→本体(無改造)→記録」の
3段構成で包み、終了コードと出力の最終行を小さなデータベースに記録している。
各ジョブは実際の挙動に合わせて個別のIDLE閾値を持つ。完了後ずっとアイドルが
正常なジョブはIDLE_THRESHOLD=off、毎晩動くはずが黙って空振りしうるジョブは、
その沈黙自体を異常として検知できる厳しい閾値を設定する。
出典
- 運営者自身が起こした事故の一次記録です。外部に公開された元記事はありません。
この記録をチームに回す