Build an uptime monitor that alerts you

A small service that checks your websites every minute, records response times, and emails you when a site goes down and when it comes back.

18 ש׳ beginner PythonrequestsSQLitecron or a workeremail

1 Friday evening: what "down" means

Decide per site:

  • the URL to check (a health endpoint such as /api/health is better than the homepage),
  • the expected status (200) and optionally a word that must appear in the page,
  • the timeout (5 s) and how many failures in a row count as down (2, to avoid false alarms).

Done when: you have a sites.yaml with 2–5 real sites.

- name: Main site
  url: https://www.example.com/api/health
  expect: 200
- name: Shop
  url: https://shop.example.com/
  expect: 200
  contains: "Add to cart"

2 Saturday morning: the check

python -m venv .venv && source .venv/bin/activate
pip install requests pyyaml
# check.py
import time, requests

def check(site, timeout=5):
    started = time.perf_counter()
    try:
        r = requests.get(site["url"], timeout=timeout, headers={"User-Agent": "uptime-monitor/1.0"})
        ok = r.status_code == site.get("expect", 200) and site.get("contains", "") in r.text
        status = r.status_code
    except requests.RequestException as e:
        ok, status = False, type(e).__name__
    return ok, status, round((time.perf_counter() - started) * 1000)

Store every result in SQLite (site, checked_at, ok, status, ms).

Done when: running python check.py prints one line per site with its status and milliseconds.

3 Saturday afternoon: state changes and alerts

Only alert when the state changes, or you will get an email every minute:

def update_state(db, site, ok):
    row = db.execute("SELECT state, fails FROM state WHERE site=?", (site,)).fetchone() or ("up", 0)
    state, fails = row
    fails = 0 if ok else fails + 1
    new_state = "down" if fails >= 2 else "up" if ok else state
    db.execute("REPLACE INTO state(site, state, fails) VALUES (?,?,?)", (site, new_state, fails))
    return state != new_state, new_state

Send an email (Resend or SMTP) on up → down with the error, and on down → up with how long it was down.

Done when: stopping a test site sends one "down" email, and starting it again sends one "back up" email.

4 Sunday morning: run it every minute

On a Linux server:

crontab -e
* * * * * cd /home/me/uptime && .venv/bin/python check.py >> check.log 2>&1

Or on Render as a Cron Job service with the same command. Keep secrets (email API key) in environment variables, never in the file.

Done when: the log grows by one line per site every minute for an hour.

5 Sunday afternoon: a status page

Add a tiny Flask page that reads the database: each site with a green/red dot, uptime % for the last 24 h and 30 days, and the average response time. Prune results older than 90 days once a day.

Done when: you can send the status page link to a client and it answers "is my site up?" without you.

סיימתם את הפרויקט? שלחו את הקישורים לבדיקה. שליחה לבדיקה (50 נקודות)

עוד מדריכים