A script that checks a list of websites every 60 seconds, logs response times, alerts you when a site goes down, and generates an uptime report.
Use requests.get() with a timeout to check if a site is up and measure response time.
import requests, time
def check_site(url):
try:
start = time.time()
r = requests.get(url, timeout=10, allow_redirects=True)
elapsed = round((time.time() - start) * 1000) # ms
return {'url': url, 'status': r.status_code, 'ms': elapsed, 'up': r.status_code < 400}
except requests.exceptions.Timeout:
return {'url': url, 'status': 'TIMEOUT', 'ms': None, 'up': False}
except requests.exceptions.ConnectionError:
return {'url': url, 'status': 'DOWN', 'ms': None, 'up': False}
print(check_site('https://google.com'))
{'url': 'https://google.com', 'status': 200, 'ms': 143, 'up': True}Loop through all sites every 60 seconds and log results.
import json, datetime
SITES = [
'https://google.com',
'https://github.com',
'https://itexperttraining.com',
]
INTERVAL = 60 # seconds between checks
def monitor():
print(f"Monitoring {len(SITES)} sites. Press Ctrl+C to stop.\n")
while True:
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"[{timestamp}]")
for url in SITES:
result = check_site(url)
icon = '✅' if result['up'] else '🔴'
ms = f"{result['ms']}ms" if result['ms'] else str(result['status'])
print(f" {icon} {url} — {ms}")
log_result(result, timestamp)
print()
time.sleep(INTERVAL)
def log_result(result, timestamp):
with open('uptime_log.jsonl', 'a') as f:
f.write(json.dumps({**result, 'time': timestamp}) + '\n')
monitor()
[2026-08-09 14:30:00] ✅ https://google.com — 143ms ✅ https://github.com — 287ms 🔴 https://itexperttraining.com — TIMEOUT
Read the log file and calculate uptime percentage and average response time for each site.
def report():
from collections import defaultdict
stats = defaultdict(lambda: {'up': 0, 'down': 0, 'times': []})
with open('uptime_log.jsonl') as f:
for line in f:
r = json.loads(line)
key = r['url']
if r['up']:
stats[key]['up'] += 1
if r['ms']: stats[key]['times'].append(r['ms'])
else:
stats[key]['down'] += 1
print(f"\n{'URL':<40} {'Uptime':>8} {'Avg ms':>8} {'Checks':>7}")
print('-' * 66)
for url, s in stats.items():
total = s['up'] + s['down']
uptime = s['up'] / total * 100 if total else 0
avg_ms = round(sum(s['times']) / len(s['times'])) if s['times'] else '-'
status = '✅' if uptime == 100 else ('⚠️' if uptime > 90 else '🔴')
print(f"{status} {url:<38} {uptime:>7.1f}% {str(avg_ms):>7}ms {total:>6}")
report()
URL Uptime Avg ms Checks ────────────────────────────────────────────────────────────────── ✅ https://google.com 100.0% 141ms 24 ✅ https://github.com 99.6% 289ms 24 ⚠️ https://itexperttraining.com 91.7% 523ms 24
Your monitor runs as a background service and produces audit-ready logs. Add it to Windows Task Scheduler or a Linux cron job to start automatically at boot.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.