自動化が止まったときに気づくためのエラーログ設計

自動化が止まったときに気づくためのエラーログ設計 定期実行と通知

自動化でいちばん怖いのは、止まることではありません。

止まったことに気づかないまま、数ヶ月が過ぎることです。

私はこれを実際にやりました。毎月動くはずの集計が、設定した日から一度も動いていなかったのです。気づいたのは3ヶ月後でした。

手で動かせば正常に動く。だから壊れているとは思わない。ただ、自動では動いていなかった。

この経験から作り直した、記録の設計をまとめます。


なぜ気づけなかったのか

原因は単純です。「動いていない」という情報が、どこにも出ていなかったからです。

当時の作りはこうでした。

  • 成功したら、結果のファイルが更新される
  • 失敗したら、何も起きない

この設計だと、失敗は「何も起きない」という形で表現されます。 ところが「何も起きない」は、忙しいときの日常と区別がつきません。

沈黙を、正常の合図にしてはいけません。
沈黙は「正常」と「死んでいる」の両方を意味してしまいます。


記録は3層に分ける

今は、目的の違う3つの記録を残しています。1つのファイルに全部書くと、どれも読まなくなります。

層 中身 いつ読むか
① 実行ログ 1回1行。成功・失敗と時刻だけ 生きているかの確認
② 詳細ログ 処理の出力そのもの 失敗の原因を調べるとき
③ 結果ファイル 集計の中身 普段の業務で使う

①がいちばん重要です。 そして、いちばん省略されがちです。


① 実行ログ:1回1行だけ

「いつ、何が、どうなったか」を1行ずつ足していくだけのファイルです。

[2026-06-15 08:00] 着地予想を実行 → 成功(着地予想_2026-06.txt)
[2026-07-15 08:00] 着地予想を実行 → 成功(着地予想_2026-07.txt)
[2026-08-15 08:00] 着地予想を実行 → 失敗(データの取り込みで停止)
[2026-08-15 09:12] 着地予想を実行 → 成功(着地予想_2026-08.txt)

書き足すのは1行です。

echo "[$(date '+%Y-%m-%d %H:%M')] 着地予想を実行 → 成功" \
  >> "$HOME/scripts/keiri/実行ログ.txt"

ポイントは、成功も必ず書くことです。

成功を書いておくと、このファイルを開いた瞬間に「最後に動いたのはいつか」が分かります。失敗だけ記録する設計では、これが分かりません。

私が3ヶ月気づかなかったのは、まさにここです。失敗の記録がない=正常、だと思い込んでいました。 実際は、記録する処理まで到達していなかっただけでした。


成功と失敗を、正しく判定する

「成功」と書くなら、本当に成功したかを確かめてから書かなければ意味がありません。

よくある失敗は、最後まで到達したことを成功とみなしてしまう作りです。

# ❌ これは成功の判定になっていない
python 集計.py
echo "成功" >> 実行ログ.txt

これだと、集計が途中でエラーになっても「成功」と書かれます。

# ⭕ 結果を見てから書く
if python 集計.py; then
  echo "[$(date '+%Y-%m-%d %H:%M')] 集計 → 成功" >> 実行ログ.txt
else
  echo "[$(date '+%Y-%m-%d %H:%M')] 集計 → 失敗(終了コード $?)" >> 実行ログ.txt
  exit 1
fi

さらに、出力されたはずのファイルが本当にできているかも見ます。

if [ ! -s "$OUT" ]; then
  echo "[$(date '+%Y-%m-%d %H:%M')] 集計 → 失敗(結果が空)" >> 実行ログ.txt
  exit 1
fi

-s は「ファイルがあり、中身が空でない」という意味です。通信の失敗でエラー画面が保存され、それを集計して「売上0円」が出る——という事故を防げます。


② 詳細ログ:定期実行の設定側で残す

プログラムが画面に出す内容は、定期実行の設定でファイルに落とせます。macOSのlaunchdなら、この2行です。

<key>StandardOutPath</key>
<string>/Users/ユーザー名/scripts/keiri/logs/out.log</string>
<key>StandardErrorPath</key>
<string>/Users/ユーザー名/scripts/keiri/logs/err.log</string>

これを書いていないと、失敗の理由がどこにも残りません。 手で動かせば画面に出るのに、自動実行では消えてしまいます。

設定の書き方は launchdが動かない・終了コード127の原因と対処 にまとめています。


③ 気づく仕組みを外に出す

記録を残しても、読みに行かなければ気づけません。 ログファイルは、意識して開かない限り開かれません。

そこで、結果のほうから届くようにします。

LINE=$(tail -1 "$HOME/scripts/keiri/実行ログ.txt")

osascript -e "display notification \"${LINE}\" \
  with title \"経理の自動集計\" sound name \"Glass\""

月1回程度なら、成功時も通知して構いません。

むしろ成功通知があることで、「そういえば今月来ていない」と気づけます。 人は届いたものより、届かなかったもののほうが気づきにくい——という前提で設計しておくと安全です。


それでも気づかない場合の最後の砦

通知も見落とすことはあります。私は月1回、実行ログの最終行だけを見る習慣にしています。

tail -3 ~/scripts/keiri/実行ログ.txt

3行だけ見れば済みます。日付が古ければ、その時点で止まっています。

これを月次の予定に入れてしまうのが確実です。 仕組みで気づけない部分は、素直に習慣で埋めたほうが早いと考えています。


ログを増やしすぎない

逆方向の失敗もあります。詳しく記録しすぎると、読めなくなります。

やりがち 結果
処理の各段階を全部記録する 1回で数百行。異常が埋もれる
1つのファイルに全部書く 肥大化して開けなくなる
失敗だけ記録する 沈黙の意味が2通りになる

実行ログは1回1行。 これを守れば、1年動かしても12行から数十行にしかなりません。開いた瞬間に全体が把握できます。


まとめ

  • 怖いのは止まることではなく、止まったことに気づかないこと
  • 沈黙を正常の合図にしない。「正常」と「死んでいる」が区別できなくなる
  • 記録は3層に分ける。実行ログ(1回1行)/詳細ログ/結果ファイル
  • 成功も必ず記録する。「最後に動いたのはいつか」が分かる
  • 成功判定は終了コードと、結果ファイルが空でないことの両方で行う
  • 定期実行の設定で出力とエラーの記録先を必ず指定する
  • 仕組みで拾いきれない分は、月1回ログの最終行を見る習慣で埋める

自動化した仕組みは、放っておけば静かに壊れます。壊れたときに音が出るように作っておくことが、運用の本体です。

コメント

タイトルとURLをコピーしました