Monitor WordPress scheduled tasks.
A real cron in place of WP-Cron, and one curl after it. Five minutes, start to finish.
Before you start
You need a heartbeat in Upglory with its period and grace set to match the crontab line below, and WP-CLI on the host. The heartbeat's page shows the ping address. WP-Cron is not a clock: it runs on a page view, so on a quiet site a daily task can be a day late and nothing looks wrong.
Settings that match this schedule
- Period15 minutesThe crontab schedule above, not the WordPress task's own interval.
- Grace10 minutesA shared host's cron drifts. Ten minutes covers the drift without hiding a real stop.
- ChannelsemailInherited from the workspace default. Change it on this heartbeat if it matters less than the others.
The line
Turn WP-Cron off, drive it from a real cron, and ping from the same line.
// wp-config.php
define('DISABLE_WP_CRON', true);
# crontab, every 15 minutes
*/15 * * * * cd /var/www/example.com \
&& wp cron event run --due-now --quiet \
&& curl -fsS -m 10 https://ping.upglory.io/abc123 > /dev/null wp cron event run --due-now runs whatever is due and exits, so the ping only follows a run that worked. If you have no WP-CLI, curl the site's wp-cron.php instead and ping after it; the shape is the same. Watch a shared host's cron: some of them run only every fifteen minutes, which sets the shortest period you can honestly promise.
Measure the run time
Ping /start before the run. The ping after it then records how long the due tasks took, which is how you see one of them getting slower.
*/15 * * * * curl -fsS -m 10 https://ping.upglory.io/abc123/start > /dev/null; wp --path=/var/www/example.com cron event run --due-now --quiet && curl -fsS -m 10 https://ping.upglory.io/abc123 > /dev/null
Report a failure
When WP-CLI exits with an error, say so at once instead of waiting for the grace window to run out.
*/15 * * * * wp --path=/var/www/example.com cron event run --due-now --quiet && curl -fsS -m 10 https://ping.upglory.io/abc123 > /dev/null || curl -fsS -m 10 https://ping.upglory.io/abc123/fail > /dev/null
Test it
Use Send a test ping on the heartbeat's page, or run the crontab line by hand on the host. Nothing alerts until the first ping arrives, so a job you have not deployed yet never raises an alarm.
What you will see if it stops
Twenty-five minutes after the last successful run, the heartbeat turns down. The usual causes, in the order they happen: the host disabled the cron entry, a plugin update broke WP-CLI, or the site ran out of disk.
last ping 10:00, ran 12 s
Email told at 10:25