cronジョブ監視
スケジュール済みタスクの停止を即座に把握できます。バックアップ、キューワーカー、ETLジョブ、時刻ごとの同期など、すべてを静かに監視します。
スケジュール済みタスクの問題
cronの厄介な特徴は、停止しても何も知らせてくれないことです。ウェブアプリケーションは引き続きリクエストをさばき、トップページも正常に見え、モニタリングもグリーンのままですが、サーバーのどこかでナイトバックアップが2週間動いていない、queue workerがデプロイ後に停止し、未処理ジョブが積み重なっている。権限の問題で毎時の同期が静かにデータを失っている。こうしたことはダウンストリーム側で問題が顕在化した時、つまり最も必要な時にようやく発覚します。データチームはエクスポートを、サポートはメールキューを、運用はバックアップを要望――その時にはもう手遅れなのです。
標準的なアップタイムモニタリングでは検知できません。なぜならpingできるものがないからです。cronはHTTPエンドポイントを公開せず、ポートも開かず、サーバーも立ち上げません。実行して終了。それきり。もし動かなくなっても、探し始めるまで不在のシグナルはありません。
逆パターン:ハートビートモニタリング
ハートビートモニタリング(「デッドマンズスイッチ」や「cron監視」とも呼ばれます)は、この流れを逆転させます。こちらがあなたのサービスを監視するのではなく、あなたのサービスがこちらに通知を送ります。cronに1行追加――生成されたユニークなURLにcurlを送信――そのURLにハートビートが送られるたびにタイムスタンプを記録します。私たちはこのpingが届かないことを監視しています。もし決められた間隔(とマージン)以内にURLにアクセスがなければ、実行漏れとしてアラートを発します。
仕組みはシンプルで信頼性が高く、言語を問いません。HTTPリクエストを発行できるものなら何でも統合できます。Bashのcurl、Pythonのrequests、Nodeのfetch、PHPのcurl_init、WindowsのタスクスケジューラならInvoke-WebRequest、GitHub Actions、Kubernetes CronJobs、Lambdaのスケジュールイベント――何でもOK。SDKもエージェントもデーモンのインストールも不要です。
設定方法
DiagnoSEO アップタイムモニタリングで「モニターを追加」をクリックし、「Heartbeat / cron」タイプを選択してください。ツールがユニークなトークン付きURLを生成します―例えば https://app.diagnoseo.com/tools/uptime-monitoring/hb.php?t=abc123xyz9 のようなものです。ジョブの実行頻度(分単位)に合わせて「インターバル」と、「どれだけ遅れても許容するか」の「マージン」を設定します。保存してください。
あとは、cronを編集してジョブが正常終了するたびにURLへpingするようにします。環境によって次の3つのスタイルがよく使われます:
# Bash cron - 正常時のみping
0 3 * * * /usr/bin/backup.sh && curl -fsS https://app.diagnoseo.com/tools/uptime-monitoring/hb.php?t=abc123xyz9 > /dev/null
# または部分的な成功もOKにする場合
0 3 * * * /usr/bin/backup.sh; curl -fsS https://app.diagnoseo.com/tools/uptime-monitoring/hb.php?t=abc123xyz9 > /dev/null
# Python
import requests
def main():
do_the_work()
requests.get('https://app.diagnoseo.com/tools/uptime-monitoring/hb.php?t=abc123xyz9', timeout=5)
# GitHub Actions
- name: Notify heartbeat
if: success()
run: curl -fsS https://app.diagnoseo.com/tools/uptime-monitoring/hb.php?t=abc123xyz9
以降、すべての正常なジョブ完了時にpingが記録され、私たちはそのタイムスタンプを保持します。インターバル + マージン 分以内にpingがなければインシデントが発生し、有効化されているすべてのチャンネル(Email、Telegram、Slack、Discord、SMS)で通知が送信されます。
インターバルとマージンの選び方
インターバルはジョブのスケジュールと合致するよう正確に設定します。例えば午前3:00のナイトバックアップならインターバルは1440分(24時間)。1時間ごとの同期なら60分、5分ごとにポーリングするワーカーなら5分、という具合です。
マージンは自然発生するジッター(ずれ)を吸収する役割です。cronは毎秒ぴったりに動くわけではなく、キューイングや前回のジョブ終了待ち、一時的なエラーによるバックオフもあります。24時間ジョブで1時間のマージンを取れば、アラート遅延なく十分なバッファができます。5分ごとワーカーなら2分のマージンを付けることで、30秒程度の一時停止による誤検知せず、本当に死んだ場合のみ素早く検知可能です。目安として、おおよそインターバルの10~50%をマージンとして設定するとよいでしょう。
おすすめのパターン
- 成功時のみping。bashなら
&&を使いましょう。失敗したジョブではpingしません。私たちがpingの欠落を検知し、アラートします。 - ループ毎にping。長時間稼働するワーカーの場合、各作業ユニットごとにループ内でpingを送ってください。そうすることで、途中でハングした場合も即座に検知できます。
- 論理的なジョブごとに1つのハートビート。スクリプト単位ではなく、例えば3つのスクリプトをまとめて1本の夜間パイプラインとしているなら、チェーン最後で1回ping。これにより「パイプライン全体が正常か」という明確なシグナルが得られます。
- ログと組み合わせる。ハートビートは「ジョブが起動した」ことを示します。アプリケーションログは「実際に何をしたか」を示します。両方合わせて、監視の全体像となります。
ハートビートが途絶えた場合どうなるか
期限を過ぎた時点でインシデントが発生します。ダッシュボードでは該当モニターが赤く表示され、「X分間ハートビートが受信されていません」というエラーが出ます。アラートは有効なすべてのチャンネルに配送。新しいハートビートが届けばモニターは自動復旧し、「稼働中」に戻り、インシデントもクローズされます(リカバリアラートを有効にしていれば「復旧しました」通知も届きます)。
その他のモニター同様の扱いで、ヒートマップ、アップタイム率、履歴、タグ、検索、エクスポートも対応済み。ハートビートモニターはダッシュボード上でHTTP、ping、ポート、APIと並んでソート・フィルタ可能な、単なる追加の1行にすぎません。
チェックリスト
モニターを追加 → タイプをHeartbeatに → 生成されたURLをコピー → cron/ワーカー/スケジューラーに追加 → インターバルとマージンを設定 → 保存 → 完了。これで、スケジュールタスクが停止すれば即座に検知可能。長期的に見て、モニタリングを行う上で最も重要な意思決定の一つになります。
よくある質問
-
逆向きのモニタリング――あらかじめ設定したジョブが正常に起動した際に、当社のURLにpingを送信します。決められた窓の間にpingが届かなければアラート。失敗してもエラーが出ず、従来型のアップタイムアラートにも検出されない「静かな障害」に有効です。
-
cronコマンド末尾に
curl -fsS <heartbeat_url>を追加してください。もし直前のコマンドが失敗すると、curlは実行されず、ハートビートも送信されません。別の方法として、開始時と終了時でそれぞれ異なるURLにpingして、「開始」「完了」を区別することもできます。 -
通常の実行時間の2~3倍が目安です。例えば毎日のバックアップが30分かかるなら、グレースを90分に設定すると遅延にも柔軟に対応できます。実行時間が不定なジョブでは広めに設定し、ダッシュボードで異常値を可視化しましょう。
-
はい――例えば1時間ごとならインターバルを60分、グレースは15分など適切に設定します。モニターは少なくとも75分以内ごとにpingを期待します。より短い(5分ごと)ジョブにも対応しており、インターバル設定を合わせればOKです。
-
はい。Lambda関数の最後でハートビートURLにHTTPリクエストを追加してください。モニターはcronハートビートと全く同じ扱いで、アラート・グレースも同一です。CloudWatchアラームでは検知できない「静かな障害」の監視にもおすすめです。
UptimeRobot · Pingdom · BetterStack · Oh Dear · Site24x7 · StatusCake · Sentry · Uptrends · Cronitor · New Relic