Ravindra BagaleCourses & study guides मराठी

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.

What you will build in this project

  1. A script that prints CPU load.
  2. Memory used and free.
  3. Disk percent per mount.
  4. 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.

Collect CPU load/proc/loadavgCollect memoryfree -mCollect diskdf -PWrite dated reportWARN if limits cross
Picture 1: from blind on-call to one report

Ravindra Bagale's Tip

Many students scrape top in a fragile way. Prefer /proc and free -m. Keep that habit.

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.

Lab: try at home

  1. Write health-report.sh.
  2. Run once and read the file.
  3. Add WARN thresholds.
  4. Cron every 5 minutes in peak.
  5. 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.