DEV Community

qing
qing

Posted on

Build a Website Health Checker with Python

Build a Website Health Checker with Python

You’ve got a broken link at 2 AM, your users are furious, and you’re the only one who knows why. What if a simple Python script could have warned you 15 minutes earlier? That’s exactly what a Website Health Checker does: it periodically pings your URLs, checks status codes and response times, and alerts you before your customers even notice a problem. Let’s build one today.

Why You Need a Website Health Checker

Broken links, slow responses, and downtime don’t just hurt user experience—they tank SEO, erode trust, and can cost real money. Tools like Pingdom or Datadog exist, but they’re either expensive or require setup time. A custom Python script gives you:

  • Full control over what you monitor (status codes, latency, specific headers)
  • Zero cost beyond your own compute
  • Immediate actionability: you can customize alerts to Slack, email, or even a terminal beep

And the best part? You can write a working version in under 30 minutes.

Setting Up Your Environment

First, make sure you have Python 3.7+ installed:

python --version
Enter fullscreen mode Exit fullscreen mode

If you’re missing it, grab the latest from python.org.

Next, install the two libraries we’ll use:

pip install requests schedule
Enter fullscreen mode Exit fullscreen mode
  • requests: makes HTTP calls and parses responses
  • schedule: handles recurring tasks without complex threading

Create a file called health_check.py in your project folder.

Building the Core Checker

Here’s a minimal but production-ready script that checks a single URL every 15 seconds:

import requests
import schedule
import time

URL = "https://93days.me"  # Replace with your target

def check_website():
    try:
        response = requests.get(URL, timeout=5)
        status_code = response.status_code
        response_time = response.elapsed.total_seconds()

        is_healthy = status_code == 200 and response_time < 3.0

        if is_healthy:
            print(f"{URL} | Status: {status_code} | Time: {response_time:.2f}s")
        else:
            print(f"{URL} | Status: {status_code} | Time: {response_time:.2f}s | ALERT!")

    except requests.exceptions.RequestException as e:
        print(f"🚨 {URL} | Request failed: {e} | ALERT!")

# Schedule the check every 15 seconds
schedule.every(15).seconds.do(check_website)

print("🔍 Website Health Checker started. Monitoring every 15 seconds...")
while True:
    schedule.run_pending()
    time.sleep(1)
Enter fullscreen mode Exit fullscreen mode

Save it, then run:

python health_check.py
Enter fullscreen mode Exit fullscreen mode

You’ll see real-time output like:

✅ https://93days.me | Status: 200 | Time: 0.87s
❌ https://broken-link.com | Status: 404 | Time: 1.23s | ALERT!
Enter fullscreen mode Exit fullscreen mode

Scaling to Multiple URLs

Monitoring one site is useful, but most teams have dozens. Let’s make it read from a websites.txt file:

# websites.txt
https://93days.me
https://api.example.com
https://blog.yoursite.com
Enter fullscreen mode Exit fullscreen mode

Update your script:

def load_urls(filename="websites.txt"):
    with open(filename) as f:
        return [line.strip() for line in f if line.strip()]

urls = load_urls()

def check_all_websites():
    for url in urls:
        check_website(url)  # (reuse the function from above, but pass url as arg)
Enter fullscreen mode Exit fullscreen mode

Now your checker monitors every URL in the file, reporting each one’s health in real time.

Adding Alerts That Actually Work

Printing to the console is fine for demos, but you need alerts when you’re asleep. Here’s a quick Slack integration using requests:

import requests

SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

def send_slack_alert(message):
    payload = {"text": message}
    requests.post(SLACK_WEBHOOK, json=payload)
Enter fullscreen mode Exit fullscreen mode

Call send_slack_alert() inside your if not is_healthy: block. You’ll get instant notifications in Slack when a site goes down.

For email, use Python’s built-in smtplib:

import smtplib
from email.message import EmailMessage

def send_email_alert(subject, body):
    msg = EmailMessage()
    msg["From"] = "you@example.com"
    msg["To"] = "ops@example.com"
    msg["Subject"] = subject
    msg.set_content(body)

    with smtplib.SMTP("smtp.example.com", 587) as server:
        server.starttls()
        server.login("you@example.com", "your_password")
        server.send_message(msg)
Enter fullscreen mode Exit fullscreen mode

Making It Run Automatically

You don’t want to keep the terminal open forever. Two options:

Option 1: System Cron (Linux/macOS)

Edit your crontab:

crontab -e
Enter fullscreen mode Exit fullscreen mode

Add this line to run every hour:

0 * * * * cd /path/to/project && python health_check.py >> /var/log/health.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Option 2: Python’s schedule + systemd (Production)

Create a systemd service file:

[Unit]
Description=Website Health Checker

[Service]
ExecStart=/usr/bin/python3 /path/to/project/health_check.py
WorkingDirectory=/path/to/project
Restart=always

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Then enable it:

sudo systemctl enable health-checker.service
sudo systemctl start health-checker.service
Enter fullscreen mode Exit fullscreen mode

Now your checker runs forever, even after reboot.

What to Monitor Beyond Status Codes

A 200 OK doesn’t mean everything’s fine. Enhance your checker with:

  • Response time thresholds: Alert if > 3 seconds
  • Specific headers: Check for Content-Security-Policy or X-Frame-Options
  • SSL certificate expiry: Use certifi or ssl to validate certs
  • DNS resolution time: Measure how long it takes to resolve the domain

Example header check:

if "Content-Security-Policy" not in response.headers:
    print("⚠️  Missing CSP header!")
Enter fullscreen mode Exit fullscreen mode

Testing Your Checker

Before deploying, simulate failures:

  1. Point your script to a known broken URL (e.g., http://definitely-not-a-real-site.com)
  2. Use curl to test endpoints manually
  3. Temporarily increase response time with time.sleep() in a mock endpoint
  4. Verify Slack/email alerts fire correctly

This ensures your alerts won’t miss real issues.

Conclusion: Your First Line of Defense

You now have a fully functional Website Health Checker that monitors status codes, response times, and sends alerts when things go wrong. It’s lightweight, customizable, and runs on any machine with Python.

Your next steps:

  1. Replace URL with your critical endpoints
  2. Add your Slack webhook or email config
  3. Set up cron or systemd to run it automatically
  4. Expand checks to include headers, SSL, and DNS

Don’t wait for a 2 AM outage to realize your site is down. Build this checker today, and you’ll be the first to know when something breaks—before your users do.

🚀 Go ahead: clone the script, drop in your URLs, and run it. Then share your setup on Dev.to and tag me—I’d love to see what you build!


If you found this helpful, consider buying me a coffee ☕ — it keeps these articles coming!

Also check out my AI tools collection: AI 次元世界 — free AI tools for developers.

Top comments (0)