Chapter 71: DevOps Projects Part 1: Linux Server, Scripts, Nginx, HTTPS and Firewall
71.10 Project 10: Python script that checks website uptime
Friends, a site can die while you sleep. Today we write a small Python checker that hits a URL, records status and latency, and exits non-zero on failure for cron.
मित्रांनो, site तुम्ही झोपताना मरू शकते. आज Python checker लिहू जो URL hit करेल, status आणि latency नोंदवेल, fail वर non-zero exit.
दोस्तों, site आपके सोते समय मर सकती है. आज Python checker लिखेंगे जो URL hit करे, status और latency लिखे, fail पर non-zero exit.
What you will build in this project
- A Python script using urllib or requests.
- Latency and status code logged.
- Non-zero exit on failure.
- Cron every minute with a log.
1. Start from a real company story
At Practo in Bengaluru, the patient booking page returned 502 for 14 minutes at dawn. No one knew until WhatsApp blew up.
Lost bookings that morning were about ₹3.2 lakh.
Diya wrote check_uptime.py: GET the URL, warn above 800 ms, exit 1 on non-200, cron every minute.
Today we build that checker.
Ravindra Bagale's Tip
Many students ignore TLS errors. In prod, fail on bad certs. In lab you may use a flag. Know the difference.
खूप students TLS errors दुर्लक्षित करतात. Prod मध्ये bad cert वर fail. Lab मध्ये flag. फरक जाणा.
बहुत students TLS errors नज़रअंदाज़ करते हैं. Prod में bad cert पर fail. Lab में flag. फ़र्क जानिए.
2. Start and prepare
Step 1: Create script file
Why: File lives under /usr/local/bin. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf script. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 1: Write file
Type this:
printf '%s\n' '#!/usr/bin/env python3' 'import sys, time, urllib.request' > /tmp/check_uptime.py && wc -l /tmp/check_uptime.py
You will see:
2 /tmp/check_uptime.py
What it means: Start.
Example 2: Install
Type this:
sudo mv /tmp/check_uptime.py /usr/local/bin/check_uptime.py && sudo chmod 755 /usr/local/bin/check_uptime.py && head -2 /usr/local/bin/check_uptime.py
You will see:
#!/usr/bin/env python3
import sys, time, urllib.request
What it means: Installed.
Example 3: Mode
Type this:
stat -c '%a' /usr/local/bin/check_uptime.py
You will see:
755
What it means: OK.
Step 2: Import urllib
Why: stdlib first. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: import urllib.request. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 4: Import test
Type this:
python3 -c 'import urllib.request; print("ok")'
You will see:
ok
What it means: stdlib ready.
Example 5: No pip needed
Type this:
python3 -c 'import urllib.request,sys,time; print(sys.version.split()[0])'
You will see:
3.12.3
What it means: Version.
Example 6: Docs note
Type this:
echo 'urllib.request.urlopen'
You will see:
urllib.request.urlopen
What it means: Call we use.
Step 3: Do one GET
Why: urlopen fetches. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: urlopen. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 7: One GET
Type this:
python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1/", timeout=5); print(r.status)'
You will see:
200
What it means: Works if Nginx up.
Example 8: Read body len
Type this:
python3 -c 'import urllib.request; b=urllib.request.urlopen("http://127.0.0.1/", timeout=5).read(); print(len(b))'
You will see:
612
What it means: Bytes.
Example 9: Timeout arg
Type this:
echo 'timeout=5 protects the script'
You will see:
timeout=5 protects the script
What it means: Important.
3. Build the main pieces
Step 4: Measure latency
Why: time.time around call. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: delta ms. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 10: Latency
Type this:
python3 -c 'import time,urllib.request; t=time.time(); urllib.request.urlopen("http://127.0.0.1/", timeout=5); print(int((time.time()-t)*1000),"ms")'
You will see:
12 ms
What it means: Fast local.
Example 11: Repeat
Type this:
python3 -c 'import time,urllib.request; t=time.time(); urllib.request.urlopen("http://127.0.0.1/", timeout=5); print(int((time.time()-t)*1000))'
You will see:
9
What it means: Stable.
Example 12: Unit
Type this:
echo 'store milliseconds as int'
You will see:
store milliseconds as int
What it means: Easy logs.
Step 5: Log a line
Why: Append to log. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: print or file. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 13: Log line shape
Type this:
python3 -c 'import time; print(time.strftime("%Y-%m-%dT%H:%M:%S"), 200, 12)'
You will see:
2026-10-28T12:10:01 200 12
What it means: date code ms.
Example 14: Append demo
Type this:
printf '%s\n' '2026-10-28T12:10:01 200 12' | sudo tee -a /var/log/uptime-check.log >/dev/null && tail -1 /var/log/uptime-check.log
You will see:
2026-10-28T12:10:01 200 12
What it means: Logged.
Example 15: wc log
Type this:
wc -l /var/log/uptime-check.log
You will see:
1 /var/log/uptime-check.log
What it means: Growing.
Step 6: Exit codes
Why: 0 ok, 1 bad. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: sys.exit. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 16: exit 0
Type this:
python3 -c 'import sys; sys.exit(0)'; echo $?
You will see:
0
What it means: Healthy.
Example 17: exit 1
Type this:
python3 -c 'import sys; sys.exit(1)'; echo $?
You will see:
1
What it means: Fail.
Example 18: Rule
Type this:
echo 'non-200 or exception -> exit 1'
You will see:
non-200 or exception -> exit 1
What it means: Cron sees it.
4. Automate and verify
Step 7: Threshold WARN
Why: Slow is not always down. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: if ms>800. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 19: WARN slow
Type this:
python3 -c 'ms=900; print("WARN slow" if ms>800 else "OK")'
You will see:
WARN slow
What it means: Threshold.
Example 20: OK fast
Type this:
python3 -c 'ms=50; print("WARN slow" if ms>800 else "OK")'
You will see:
OK
What it means: Under.
Example 21: Both ideas
Type this:
echo 'WARN still exit 0; DOWN exit 1'
You will see:
WARN still exit 0; DOWN exit 1
What it means: Severity split.
Step 8: CLI args
Why: URL from argv. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: argparse. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 22: Full script
Type this:
printf '%s\n' '#!/usr/bin/env python3' 'import sys, time, urllib.request' 'url = sys.argv[1] if len(sys.argv)>1 else "http://127.0.0.1/"' 't=time.time()' 'try:' ' r=urllib.request.urlopen(url, timeout=5)' ' ms=int((time.time()-t)*1000)' ' print(time.strftime("%Y-%m-%dT%H:%M:%S"), r.status, ms)' ' sys.exit(0 if r.status==200 else 1)' 'except Exception as e:' ' ms=int((time.time()-t)*1000)' ' print(time.strftime("%Y-%m-%dT%H:%M:%S"), "ERR", ms, e)' ' sys.exit(1)' | sudo tee /usr/local/bin/check_uptime.py >/dev/null && sudo chmod 755 /usr/local/bin/check_uptime.py && echo wrote
You will see:
wrote
What it means: Complete.
Example 23: Help run
Type this:
/usr/local/bin/check_uptime.py http://127.0.0.1/
You will see:
2026-10-28T12:11:00 200 11
What it means: Healthy line.
Example 24: argv
Type this:
/usr/local/bin/check_uptime.py http://127.0.0.1/docs/ || true
You will see:
2026-10-28T12:11:01 200 10
What it means: Path OK.
Step 9: Run healthy
Why: Expect 200. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: run. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 25: Healthy exit
Type this:
/usr/local/bin/check_uptime.py http://127.0.0.1/; echo exit:$?
You will see:
2026-10-28T12:11:02 200 10
exit:0
What it means: Pass.
Example 26: Log it
Type this:
/usr/local/bin/check_uptime.py http://127.0.0.1/ | sudo tee -a /var/log/uptime-check.log >/dev/null && tail -1 /var/log/uptime-check.log
You will see:
2026-10-28T12:11:03 200 9
What it means: Appended.
Example 27: grep 200
Type this:
grep ' 200 ' /var/log/uptime-check.log | wc -l
You will see:
3
What it means: History.
5. Harden and accept
Step 10: Force fail
Why: Stop Nginx briefly. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: systemctl stop. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 28: Force fail
Type this:
sudo systemctl stop nginx; /usr/local/bin/check_uptime.py http://127.0.0.1/; echo exit:$?; sudo systemctl start nginx
You will see:
2026-10-28T12:11:10 ERR 5 <urlopen error ...>
exit:1
What it means: Caught.
Example 29: Nginx back
Type this:
systemctl is-active nginx
You will see:
active
What it means: Restored.
Example 30: Healthy again
Type this:
/usr/local/bin/check_uptime.py http://127.0.0.1/; echo exit:$?
You will see:
2026-10-28T12:11:12 200 8
exit:0
What it means: OK.
Step 11: Cron install
Why: crontab or cron.d. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: cron.d. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 31: cron.d
Type this:
printf '%s\n' '* * * * * root /usr/local/bin/check_uptime.py http://127.0.0.1/ >> /var/log/uptime-check.log 2>&1' | sudo tee /etc/cron.d/uptime-check >/dev/null && cat /etc/cron.d/uptime-check
You will see:
* * * * * root /usr/local/bin/check_uptime.py http://127.0.0.1/ >> /var/log/uptime-check.log 2>&1
What it means: Every minute.
Example 32: Mode
Type this:
sudo chmod 644 /etc/cron.d/uptime-check && stat -c '%a' /etc/cron.d/uptime-check
You will see:
644
What it means: Required.
Example 33: grep
Type this:
grep check_uptime /etc/cron.d/uptime-check
You will see:
* * * * * root /usr/local/bin/check_uptime.py http://127.0.0.1/ >> /var/log/uptime-check.log 2>&1
What it means: Present.
Step 12: Acceptance checklist
Why: Diya signs off when these pass. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 34: script ok
Type this:
test -x /usr/local/bin/check_uptime.py && echo script_ok
You will see:
script_ok
What it means: Executable.
Example 35: cron ok
Type this:
test -f /etc/cron.d/uptime-check && echo cron_ok
You will see:
cron_ok
What it means: Scheduled.
Example 36: Sign-off
Type this:
echo 'Diya: PASS'
You will see:
Diya: PASS
What it means: Done.
Check yourself
Q1. Healthy HTTP code?
200
Q2. Exit code on failure?
1
Q3. Who wrote Practo checker?
Diya
Q4. Slow threshold Diya used?
800 ms
Q5. Library without pip?
urllib
Q6. Cron period?
Every minute
Friends, you built a Python uptime checker with cron. Did you understand? Let us try it once more. Point it at a practice URL and force a fail by stopping Nginx briefly.
मित्रांनो, तुम्ही Python uptime checker cron सह बनवला. Practice URL वर ठेवून Nginx बंद करून fail बघ.
दोस्तों, आपने Python uptime checker cron के साथ बनाया. Practice URL पर रख Nginx बंद कर fail देखें.
Lab: try at home
- Write check_uptime.py.
- Run against http://127.0.0.1/.
- Break the site and see exit 1.
- Add cron every minute.
- Keep a week of logs.
Recap
- urllib can avoid extra deps.
- Log status and latency.
- exit 1 fails the cron loudly.
- Thresholds catch slow pages.
- Cron every minute is enough for many sites.
Lab
- Finish all ten projects on one Ubuntu practice box.
- Keep each project script under /usr/local/bin with mode 755.
- Never store secrets in the script body.
- After each project, write one paragraph: what broke and how you fixed it.
- Reboot once and confirm cron, Nginx and fail2ban still run.
Practice task
Pick the disk alert and the uptime checker. Wire both to the same on-call practice mailbox and prove both fire.
Ravindra Bagale's Tip
Do the projects in order on one practice Ubuntu box. Keep a notebook of the commands that worked. Never use world-writable modes.
एक practice Ubuntu box वर projects क्रमाने करा. काम केलेल्या commands ची notebook ठेवा. World-writable modes कधीच वापरू नका.
एक practice Ubuntu box पर projects क्रम से करें. काम आए commands की notebook रखें. World-writable modes कभी इस्तेमाल न करें.
In short
- Named users and SSH keys beat shared root passwords.
- df -P and logrotate keep disks healthy.
- Backups need verify, not only upload.
- One Nginx can host many sites and balance many apps.
- TLS and fail2ban are baseline, not optional.