နားလည်ထားရမယ့် အချက်
ဤပရောဂျက်သည် check တစ်ခုတည်းအကြောင်းထက် check အများအပြားကို အတူတကွထိန်းသိမ်းပေးသည့် framework အကြောင်းကို ပိုအာရုံစိုက်ပြီး၊ ဤ tutorial က မသုံးခဲ့သေးသော pattern တစ်ခုကို မိတ်ဆက်ပေးသည် — function call များစွာကို ဖြတ်သန်း၍ state ကို စုဆောင်းပေးသည့် global variable, worst_status ပင်ဖြစ်သည်၊ function တစ်ခုချင်းစီ self-contained ဖြစ်နေသည့်အစား။ report() helper သည် တစ်ပြိုင်နက် job နှစ်ခုကို လုပ်ဆောင်သည် — printf ဖြင့် တသမတ်တည်း format ကျသော line တစ်ခု print လုပ်ပေးသည်၊ ပြီးတော့ 'high-water mark' စည်းမျဉ်းတစ်ခုသုံး၍ worst_status ကို update လုပ်ပေးသည်— case statement တစ်ခုက worst_status ကို WARNING အတွက် 1၊ CRITICAL အတွက် 2 အဖြစ် တိုးမြှင့်ပေးသော်လည်း၊ (( worst_status < 1 )) နှင့် (( worst_status < 2 )) ဖြင့် value အသစ်က ယခင်မှတ်ထားသည့်တန်ဖိုးထက် ပိုမြင့်မှသာ ပြောင်းလဲပေးသည်။ ထို guard ကပင် check_port မှ CRITICAL ရလဒ်တစ်ခုသည် check_process မှ ယခင် OK ကို အမြဲထာဝရ override လုပ်နိုင်စေပြီး၊ နောက်ပိုင်း OK တစ်ခုကမှ ပြန်ချသွားနိုင်မည်မဟုတ်ပါ။ checks array သည် function name များကို plain string အဖြစ် သိမ်းထားပြီး၊ for loop ထဲရှိ "$check" သည် တစ်ခုချင်းစီကို name အလိုက် ခေါ်ဆိုပေးသည် — variable ထဲသိမ်းထားသော function ကို ခေါ်ဆိုနိုင်ခြင်းကပင် နောက်ပိုင်းတွင် check စတုတ္ထတစ်ခု ထပ်ထည့်ခြင်းကို function တစ်ခု ရေးပြီး array ထဲသို့ name ထပ်ထည့်ရုံသာ ဖြစ်စေမည်၊ loop ကိုယ်တိုင် ဘာမှ ပြောင်းစရာမလိုပါ။ နောက်ဆုံးတွင် exit "$worst_status" သည် script ရဲ့ internal state ကို process exit code တစ်ခုအဖြစ် ပြောင်းလဲပေးသည်၊ ၎င်းသည် monitoring tool၊ cron wrapper နှင့် shell pipeline တိုင်းက ဖတ်တတ်ပြီးသား universal interface ပင်ဖြစ်သည်။ ဤနေရာရှိ check တစ်ခုချင်းစီသည် real df, pgrep, သို့မဟုတ် ss command များကို ခေါ်မည့်အစား တမင် hardcode လုပ်ထားသည် — verify လုပ်နေတာက framework ၏ control flow ပင်ဖြစ်သည်၊ ဘယ်လို ရလဒ်ဆိုးတစ်ခုက အဆုံးအထိ ရှင်သန်နေသလဲဆိုတာကို ဆိုလိုသည်၊ ဘယ် machine တစ်ခုတည်းရဲ့ OS state ကိုမှ မဟုတ်ပါ။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
cron-trigger alerting, Nagios, သို့မဟုတ် ရိုးရှင်းသော uptime dashboard ကဲ့သို့သော monitoring system များအားလုံးသည် health-check script တစ်ခုထံမှ တူညီသော အခြေခံ contract ကို လိုအပ်ကြသည် — check အချို့ run ပါ၊ လူဖတ်နိုင်သည့်အရာတစ်ခု ထုတ်ပြပါ၊ ပြီးတော့ တစ်ခုခုပြင်းထန်စွာ မှားယွင်းလာသည့်ခဏ nonzero ဖြင့် ထွက်ခွာပါ။ execution အမှန်ကို လိုက်ကြည့်ကြပါစို့— checks=(check_disk_usage check_process check_port) သည် function name သုံးခုကို list လုပ်ထားပြီး for loop သည် တစ်ခုချင်းစီကို အလှည့်ကျ ခေါ်ဆိုသည်။ check_disk_usage သည် used_percent=92 ကို hardcode လုပ်ထားပြီး၊ ၎င်းရဲ့ 90 threshold ထက် ပိုမြင့်နေသောကြောင့် report "disk" "CRITICAL" "..." ကို ခေါ်သည် — report သည် line ကို print လုပ်ပြီး 2 > 0 ဖြစ်သောကြောင့် worst_status ကို 0 မှ 2 အဖြစ် တိုးမြှင့်လိုက်သည်။ check_process သည် running="yes" ကို hardcode လုပ်ထားပြီး OK ဟု report လုပ်သည် — worst_status သည် 2 တွင်ပင် ဆက်ရှိနေသည်၊ ဘာကြောင့်ဆိုသော် OK သည် ၎င်းကို ဘယ်တော့မှ လျှော့ချမည်မဟုတ်သောကြောင့်ဖြစ်သည်။ check_port သည် listening="no" ကို hardcode လုပ်ထားပြီး CRITICAL ဟု ထပ်မံ report လုပ်သည် — worst_status သည် 2 ဖြစ်နှင့်ပြီးသားဖြစ်၍ (( worst_status < 2 )) guard က ၎င်းကို မပြောင်းလဲစေတော့ပါ၊ သို့သော် CRITICAL line တစ်ကြောင်းချင်းစီကတော့ ဆက်လက် print ထွက်နေသည်။ loop ပြီးဆုံးပြီးနောက် နောက်ဆုံး case statement သည် worst_status=2 ကို ဖတ်ပြီး 'Overall: CRITICAL' ဟု print လုပ်ကာ၊ exit "$worst_status" သည် exit code 2 ကို script ကို ခေါ်ဆိုခဲ့သည့်မည်သူ့ထံမဆို ပြန်ပို့ပေးသည်။ ဒါသည် Nagios plugin convention (OK/WARNING/CRITICAL အတွက် 0/1/2) အတိအကျပင်ဖြစ်ပြီး၊ ဒါကြောင့် cron သို့မဟုတ် monitoring dashboard တစ်ခုက ဤ script ၏ exit code ကို စောင့်ကြည့်နေရုံဖြင့် စာသားတစ်လုံးမျှ parse လုပ်စရာမလိုဘဲ လူတစ်ဦးဦးကို အလိုအလျောက် page ခေါ်နိုင်သည်။ ဤ framework မရှိလျှင်၊ pass/fail line များကိုသာ print လုပ်ပြီး အမြဲ exit 0 လုပ်နေသည့် naive script တစ်ခုသည် terminal ပေါ်တွင် အတူတူပင်ကွက်တူပုံရသော်လည်း alert တစ်ခုမျှ ဘယ်တော့မှ trigger မဖြစ်နိုင်ပါ — disk ပြည့်လာခြင်း သို့မဟုတ် nginx ပျက်သွားခြင်းကို log ကို လက်ဖြင့်ဖတ်နေသူတစ်ဦးဦးကသာ သတိပြုမိမည်ဖြစ်ပြီး၊ များသောအားဖြင့် outage စတင်ပြီးမှ ကြာကြာမှသာ ဖြစ်တတ်သည်။
အတူတူ စမ်းရေးကြည့်မယ်
#!/usr/bin/env bash
set -euo pipefail
# Overall worst status seen so far: 0=OK, 1=WARNING, 2=CRITICAL
worst_status=0
report() {
local name="$1"
local status="$2" # OK | WARNING | CRITICAL
local detail="$3"
printf "[%-8s] %-16s %s\n" "$status" "$name" "$detail"
case "$status" in
WARNING)
if (( worst_status < 1 )); then worst_status=1; fi
;;
CRITICAL)
if (( worst_status < 2 )); then worst_status=2; fi
;;
esac
}
# --- Individual checks ---
# In a real script, each of these would run an actual command
# (df, pgrep, a port check, etc). Here they return hardcoded fake
# values so the framework logic below is deterministic to demonstrate.
check_disk_usage() {
# In a real script: read the used% from `df -h /` and compare to thresholds
local used_percent=92
if (( used_percent >= 90 )); then
report "disk" "CRITICAL" "root partition at ${used_percent}% used"
elif (( used_percent >= 75 )); then
report "disk" "WARNING" "root partition at ${used_percent}% used"
else
report "disk" "OK" "root partition at ${used_percent}% used"
fi
}
check_process() {
# In a real script: running=$(pgrep -x nginx > /dev/null && echo yes || echo no)
local running="yes"
if [[ "$running" == "yes" ]]; then
report "nginx" "OK" "process is running"
else
report "nginx" "CRITICAL" "process is not running"
fi
}
check_port() {
# In a real script: check with `ss -ltn` or a TCP probe against the port
local listening="no"
if [[ "$listening" == "yes" ]]; then
report "port:5432" "OK" "port is accepting connections"
else
report "port:5432" "CRITICAL" "port is not listening"
fi
}
echo "System Health Check"
echo "===================="
checks=(check_disk_usage check_process check_port)
for check in "${checks[@]}"; do
"$check"
done
echo "===================="
case "$worst_status" in
0) echo "Overall: OK" ;;
1) echo "Overall: WARNING" ;;
2) echo "Overall: CRITICAL" ;;
esac
exit "$worst_status"System Health Check
====================
[CRITICAL] disk root partition at 92% used
[OK ] nginx process is running
[CRITICAL] port:5432 port is not listening
====================
Overall: CRITICAL၅ မိနစ် စမ်းကြည့်
simulate လုပ်ထားသည့် check တစ်ခုကို real check တစ်ခု — ဥပမာ actual df -h / disk-usage check — ဖြင့် အစားထိုးပါ၊ ပြီးတော့ script ကို run နေစဉ် Ctrl-C ဖြင့် ရပ်တန့်ခံရလျှင် 'Health check interrupted' ဟု ထုတ်ပြမည့် trap တစ်ခု ထပ်ထည့်ပါ။
သတိလေးတစ်ချက်
health-check script တစ်ခုတွင် set -e ကို သတိမထားဘဲသုံးလိုက်ခြင်းသည် ပထမဆုံး CRITICAL အခြေအနေတွေ့သည်နှင့် script ချက်ချင်း ထွက်သွားစေနိုင်ပြီး နောက်ပိုင်း check များ လုံးဝ run မဖြစ်တော့ဘဲ report မပြည့်စုံဘဲ ဖြစ်နေနိုင်သည် — (( x < y )) ကဲ့သို့ arithmetic conditional များသည် false ရလဒ်ရလျှင် set -e အောက်တွင် script တစ်ခုလုံး abort မဖြစ်စေရန် if/then ဖြင့် အထူးပတ်ထားပေးရန် လိုအပ်သည်။
အဆိုးဆုံး status ဖြင့် exit မလုပ်ဘဲ မေ့လျော့ခြင်း (ဘာဖြစ်ဖြစ် exit 0 default လုပ်ခြင်း) သည် exit code ကို စောင့်ကြည့်နေသည့် monitoring system မှန်သမျှကို တိတ်တဆိတ် ချို့ယွင်းစေသည် — failure များကို ပုံနှိပ်ထားသော စာသားပြင်ပတွင် ဘယ်တော့မှ မပေါ်လာလျှင် check ၏ ရည်ရွယ်ချက်တစ်ခုလုံး ပျောက်ဆုံးသွားသည်။
Nagios Plugin Development Guidelines — Exit Codes — Bash / Shell Scripting