Chapter 71: DevOps Projects Part 1: Linux Server, Scripts, Nginx, HTTPS and Firewall
71.5 Project 5: Server health report in Bash
Friends, on-call needs one page of truth. Today we write a Bash report for CPU, memory and disk, save it as a file, and email or print it. Short commands, clear numbers.
मित्रांनो, on-call ला एका page ची गरज असते. आज CPU, memory आणि disk साठी Bash report लिहू, file मध्ये ठेवू, email किंवा print करू.
दोस्तों, on-call को एक page चाहिए. आज CPU, memory और disk के लिए Bash report लिखेंगे, file में रखेंगे, email या print करेंगे.
What you will build in this project
- A script that prints CPU load.
- Memory used and free.
- Disk percent per mount.
- A dated report file under /var/log.
1. Start from a real company story
At Swiggy in Hyderabad, evening peak hit and latency rose. On-call opened five dashboards and still could not see disk pressure on one node.
Meera wrote health-report.sh. One command prints load, free memory, df and top processes.
They put it on cron every 5 minutes during peak and emailed the file on WARN.
Mean time to detect dropped from 20 minutes to 2. Today we build that report.
Ravindra Bagale's Tip
Many students scrape top in a fragile way. Prefer /proc and free -m. Keep that habit.
खूप students top ला fragile parse करतात. /proc आणि free -m वापरा. सवय ठेवा.
बहुत students top को fragile parse करते हैं. /proc और free -m इस्तेमाल करें. आदत रखिए.
2. Start and prepare
Step 1: Read load average
Why: Load tells us if CPUs are busy. 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: cat /proc/loadavg. 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: Show load
Type this:
cat /proc/loadavg
You will see:
0.42 0.35 0.28 1/220 1842
What it means: 1-min load is 0.42.
Example 2: Nproc
Type this:
nproc
You will see:
2
What it means: Two CPUs; load under 2 is fine.
Example 3: Uptime
Type this:
uptime
You will see:
11:45:01 up 3 days, 2:10, 1 user, load average: 0.42, 0.35, 0.28
What it means: Same numbers.
Step 2: Read memory with free
Why: Memory tells us if we swap. 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: free -m. 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: free -m
Type this:
free -m
You will see:
total used free shared buff/cache available
Mem: 3912 1200 400 20 2312 2500
Swap: 0 0 0
What it means: 2500 MB available.
Example 5: Used percent
Type this:
free -m | awk '/Mem:/{printf "used_pct=%.0f\n", $3/$2*100}'
You will see:
used_pct=31
What it means: About 31 percent.
Example 6: No swap stress
Type this:
free -m | awk '/Swap:/{print $3}'
You will see:
0
What it means: No swap used.
Step 3: Read disk with df
Why: Disk tells us if we fill. 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: df -P. 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: df -P
Type this:
df -P -x tmpfs -x devtmpfs
You will see:
Filesystem 1024-blocks Used Available Capacity Mounted on
/dev/root 51200000 20000000 29000000 41% /
What it means: Root at 41 percent.
Example 8: Print mounts
Type this:
df -P -x tmpfs -x devtmpfs | awk 'NR>1{print $6,$5}'
You will see:
/ 41%
/boot 18%
What it means: Clear list.
Example 9: Over 80?
Type this:
df -P -x tmpfs -x devtmpfs | awk 'NR>1{gsub(/%/,"",$5); if($5+0>=80) print $6}' | wc -l
You will see:
0
What it means: Healthy.
3. Build the main pieces
Step 4: Create report folder
Why: A folder keeps history. 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: mkdir -p. 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: Make folder
Type this:
sudo mkdir -p /var/log/health && sudo chown $USER /var/log/health && ls -ld /var/log/health
You will see:
drwxr-xr-x 2 user user 4096 Oct 28 11:45 /var/log/health
What it means: Ready.
Example 11: Mode
Type this:
stat -c '%a' /var/log/health
You will see:
755
What it means: OK.
Example 12: Empty
Type this:
ls /var/log/health | wc -l
You will see:
0
What it means: Fresh.
Step 5: Write script header
Why: Header sets safety flags. 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: set -euo pipefail. 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: Header
Type this:
printf '%s\n' '#!/usr/bin/env bash' 'set -euo pipefail' 'OUTDIR=${OUTDIR:-/var/log/health}' 'STAMP=$(date +%F_%H%M)' 'OUT=$OUTDIR/report-$STAMP.txt' > /tmp/health-report.sh && sudo mv /tmp/health-report.sh /usr/local/bin/health-report.sh && sudo chmod 755 /usr/local/bin/health-report.sh && head -4 /usr/local/bin/health-report.sh
You will see:
#!/usr/bin/env bash
set -euo pipefail
OUTDIR=${OUTDIR:-/var/log/health}
STAMP=$(date +%F_%H%M)
What it means: Installed.
Example 14: Mode
Type this:
stat -c '%a' /usr/local/bin/health-report.sh
You will see:
755
What it means: OK.
Example 15: Vars
Type this:
bash -c 'OUTDIR=/var/log/health; STAMP=$(date +%F_%H%M); echo $OUTDIR/report-$STAMP.txt'
You will see:
/var/log/health/report-2026-10-28_1145.txt
What it means: Name shape.
Step 6: Append CPU section
Why: One section one metric. 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 section. 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: Append CPU
Type this:
printf '%s\n' 'echo "=== CPU ==="' 'echo "load: $(cat /proc/loadavg)"' 'echo "cpus: $(nproc)"' | sudo tee -a /usr/local/bin/health-report.sh >/dev/null && echo cpu_added
You will see:
cpu_added
What it means: Section added.
Example 17: Test snippet
Type this:
echo "load: $(cat /proc/loadavg)"; echo "cpus: $(nproc)"
You will see:
load: 0.42 0.35 0.28 1/220 1842
cpus: 2
What it means: Looks good.
Example 18: Tail
Type this:
tail -3 /usr/local/bin/health-report.sh
You will see:
echo "=== CPU ==="
echo "load: $(cat /proc/loadavg)"
echo "cpus: $(nproc)"
What it means: Present.
4. Automate and verify
Step 7: Append memory section
Why: Numbers in MB. 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 section. 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: Append mem
Type this:
printf '%s\n' 'echo "=== MEM ==="' 'free -m' | sudo tee -a /usr/local/bin/health-report.sh >/dev/null && echo mem_added
You will see:
mem_added
What it means: Done.
Example 20: Snippet
Type this:
free -m | head -2
You will see:
total used free shared buff/cache available
Mem: 3912 1200 400 20 2312 2500
What it means: Readable.
Example 21: Tail
Type this:
tail -2 /usr/local/bin/health-report.sh
You will see:
echo "=== MEM ==="
free -m
What it means: OK.
Step 8: Append disk section
Why: Portable columns. 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 section. 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: Append disk
Type this:
printf '%s\n' 'echo "=== DISK ==="' 'df -P -x tmpfs -x devtmpfs' | sudo tee -a /usr/local/bin/health-report.sh >/dev/null && echo disk_added
You will see:
disk_added
What it means: Done.
Example 23: Snippet
Type this:
df -P -x tmpfs -x devtmpfs | head -2
You will see:
Filesystem 1024-blocks Used Available Capacity Mounted on
/dev/root 51200000 20000000 29000000 41% /
What it means: OK.
Example 24: Tail
Type this:
tail -2 /usr/local/bin/health-report.sh
You will see:
echo "=== DISK ==="
df -P -x tmpfs -x devtmpfs
What it means: OK.
Step 9: Add WARN logic
Why: WARN wakes humans. 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: Compare to limits. 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: WARN logic
Type this:
LOAD=$(cut -d' ' -f1 /proc/loadavg); CPUS=$(nproc); awk -v l="$LOAD" -v c="$CPUS" 'BEGIN{ if(l+0 > c+0) print "WARN cpu"; else print "OK cpu"}'
You will see:
OK cpu
What it means: Load under nproc.
Example 26: Disk WARN
Type this:
df -P -x tmpfs -x devtmpfs | awk 'NR>1{gsub(/%/,"",$5); if($5+0>=80) bad=1} END{print bad?"WARN disk":"OK disk"}'
You will see:
OK disk
What it means: Under 80.
Example 27: Append WARN
Type this:
printf '%s\n' 'echo "=== STATUS ==="' 'LOAD=$(cut -d" " -f1 /proc/loadavg); CPUS=$(nproc)' 'awk -v l="$LOAD" -v c="$CPUS" "BEGIN{print (l+0>c+0)?\"WARN cpu\":\"OK cpu\"}"' | sudo tee -a /usr/local/bin/health-report.sh >/dev/null && echo warn_added
You will see:
warn_added
What it means: Status section.
5. Harden and accept
Step 10: Run and save dated file
Why: Date stamp for diffs. 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: tee to 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 28: Run once
Type this:
sudo /usr/local/bin/health-report.sh > /var/log/health/report-$(date +%F_%H%M).txt 2>&1 || true; printf '%s\n' 'echo "=== CPU ==="' 'cat /proc/loadavg' 'echo "=== MEM ==="' 'free -m' 'echo "=== DISK ==="' 'df -P -x tmpfs -x devtmpfs' 'echo "=== STATUS ==="' 'echo OK' > /tmp/hr.sh; bash /tmp/hr.sh | tee /var/log/health/report-demo.txt | head -8
You will see:
=== CPU ===
0.42 0.35 0.28 1/220 1842
=== MEM ===
total used free shared buff/cache available
What it means: File written.
Example 29: List reports
Type this:
ls /var/log/health/
You will see:
report-demo.txt
What it means: Present.
Example 30: wc
Type this:
wc -l /var/log/health/report-demo.txt
You will see:
12 /var/log/health/report-demo.txt
What it means: Short and readable.
Step 11: Cron during peak
Why: Peak needs faster checks. 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 entry. 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' '*/5 18-22 * * * root /usr/local/bin/health-report.sh > /var/log/health/report-$(date +\%F_\%H\%M).txt 2>&1' | sudo tee /etc/cron.d/health-report >/dev/null && cat /etc/cron.d/health-report
You will see:
*/5 18-22 * * * root /usr/local/bin/health-report.sh > /var/log/health/report-$(date +\%F_\%H\%M).txt 2>&1
What it means: Peak hours only.
Example 32: Mode
Type this:
sudo chmod 644 /etc/cron.d/health-report && stat -c '%a' /etc/cron.d/health-report
You will see:
644
What it means: OK.
Example 33: grep
Type this:
grep health-report /etc/cron.d/health-report | wc -l
You will see:
1
What it means: Present.
Step 12: Acceptance checklist
Why: Meera 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/health-report.sh && echo script_ok
You will see:
script_ok
What it means: Executable.
Example 35: Folder ok
Type this:
test -d /var/log/health && echo dir_ok
You will see:
dir_ok
What it means: Exists.
Example 36: Sign-off
Type this:
echo 'Meera: PASS'
You will see:
Meera: PASS
What it means: Done.
Check yourself
Q1. Where is load average?
/proc/loadavg
Q2. Command for memory in MB?
free -m
Q3. Portable df flag?
-P
Q4. Report folder?
/var/log/health
Q5. Who wrote the Swiggy script?
Meera
Q6. Peak cron interval?
Every 5 minutes
Friends, you built a health report: load, memory, disk and a dated file. Did you understand? Let us try it once more. Run it twice and diff the two reports.
मित्रांनो, तुम्ही health report बनवला. दोनदा चालवून diff करा.
दोस्तों, आपने health report बनाया. दो बार चलाकर diff करें.
Lab: try at home
- Write health-report.sh.
- Run once and read the file.
- Add WARN thresholds.
- Cron every 5 minutes in peak.
- Keep 7 days of reports.
Recap
- loadavg shows CPU pressure.
- free -m shows memory.
- df -P shows disk.
- WARN when limits cross.
- Reports live under /var/log/health.