A monitor that lives on your server cannot tell you that your server is down.
Everything else in this guide is useful. That sentence is the reason you still need one check you do not host, and it is better to say it in the first paragraph than to bury it under a feature list.
So run your own checks for the ninety-five per cent — the app that returns a 500 at 03:14, the certificate nobody renewed, the page that renders but shows an empty product list — and let one free external checker watch the log server itself.
The payoff for hosting the rest: when a check fails, the logs from that minute are already on the same disk, in the same tool, one query away.
Central Logging wakes every minute and runs whichever monitors are due. Each monitor has its own interval: 1, 2, 5 or 10 minutes.
Each check is a plain GET. It records:
Each monitor has its own timeout: 5, 10, 30 or 60 seconds. The default is 10. A check with no response in that time counts as down.
History is kept for 30 days.
Go to Website Monitors and add a monitor. The form asks for a URL and how often to check. The default is every minute. The name is optional and falls back to the host name.
Open More options on the same form before you save. The timeout is there, and so is the keyword. The keyword is the part that earns its keep.
Central Logging alerts on three things:
A down alert needs two failed checks in a row. One slow response does not page you. At the one-minute interval, the alert arrives a minute or two after the site goes down. A 5xx alert names the status, for example returned HTTP 503 Service Unavailable. You get a recovery alert when the site answers again.
Now the gap. A 4xx counts as up. A 404 from a deleted page, a 403 from a misconfigured proxy and a 401 all pass. So does a 200 that serves an empty page, a maintenance page or a login page to a logged-in user. The server answered, so the check passes.
Before the 2026-11-06 release, a 500 did not alert either. If you set up monitors earlier and added keywords to catch 500s, keep them. They still catch everything in the paragraph above.
Pick a string that appears on a healthy page and appears nowhere on a broken one, then alert on its absence:
URL: https://app.example.com/
Keyword: Sign in
Alert when: Alert if it is missing
The match runs against the raw response body and ignores case unless you tick Match upper and lower case exactly. HTML markup works, which is what makes it precise:
Keyword: <span id="db-status">ok</span>
Alert when: Alert if it is missing
Choose the string carefully. A word in your nav bar tells you the web server is up. A string that only renders when the database answered tells you the application is up. The second one is the monitor worth having.
Two things to avoid:
Your log server going down takes its own monitoring with it. There are two honest answers.
A free external checker. One monitor, pointed at your Central Logging instance. Every hosted checker has a free tier that covers a single check comfortably. That one external check plus your own monitors covers more than most small teams have today.
A second box you already own. If you run a VPS somewhere else, give it a cron job that curls your log server and pings a cron monitor — hosted anywhere but on the box being watched.
Do not skip this step and tell yourself the monitors have it covered. They do not.
The TLS check reads the certificate on every HTTPS request it makes anyway, so it costs nothing. An alert goes out when a certificate expires within seven days, throttled to once a day.
Seven days is plenty for anything renewing automatically, and it is a useful backstop when a Let’s Encrypt renewal has been quietly failing for a month. It is tight for a certificate you buy and install by hand. If that is your situation, add a monitor for the same host and treat the first warning as a deadline, not a heads-up.
The certificate expiry is shown on the monitors list, so you can see the whole estate without waiting to be told.
This is the part a hosted checker cannot do for you.
The alert tells you the time. The logs from that minute are on the same server:
SELECT timestamp, msg FROM logs
WHERE timestamp BETWEEN CAST(strftime('%s', '2026-08-10 03:04:00') AS INTEGER)
AND CAST(strftime('%s', '2026-08-10 03:24:00') AS INTEGER)
ORDER BY timestamp
Ten minutes either side of the alert. Read what the application was saying while the check was failing.
If the source ships JSON, narrow it to the errors and guard the extract, because one plain-text line in the source makes json_extract fail the whole query:
SELECT timestamp, json_extract(msg, '$.message') AS message
FROM logs
WHERE timestamp > CAST(strftime('%s', 'now', '-1 hour') AS INTEGER)
AND json_valid(msg)
AND json_extract(msg, '$.level') = 'error'
ORDER BY timestamp DESC
More on that in querying logs with SQL.
Monitor alerts use the same notification channel as everything else. Tick Send alerts to this channel on the one you want, and check the Alerts page — the channel that receives alerts is labelled there.
GET only. No POST, no custom headers, no authentication. Public endpoints and health checks, not APIs behind a token.If external verification is the whole point of the exercise, use a hosted checker — see the Uptime Robot alternative and Better Stack alternative pages for that comparison in full.
Add the monitor with a URL and a keyword. Without a keyword you hear about a server that stopped answering or answered with a 5xx. You do not hear about the 404, the empty page or the login screen. Those failures look healthy to a status check.
Give one check to someone else: the one that watches your log server.
Then, when a monitor fires, stay in the same tool. The logs from the minute it broke are already there.
💌 Get notified on new features and updates