နားလည်ထားရမယ့် အချက်
ဤပရောဂျက်သည် သီးခြားရိုးရှင်းသော Unix tool အသေးလေးများစွာကို ပေါင်းစပ်လိုက်သောအခါ တစ်ခုချင်းစီထက် ပိုမိုအားကောင်းလာပုံကို ပြသည်— ဒါသည် ဤ tutorial တစ်ခုလုံးက တည်ဆောက်ပေးလာခဲ့သော အဓိက skill ပင်ဖြစ်သည်။ အခန်းရှေ့ပိုင်းများမှ concept လေးခုကို ပေါင်းစပ်ထားသည်။ ပထမ၊ function များ — count_level() နှင့် top_error_messages() တို့သည် ထပ်ခါထပ်ခါရေးရမည့် logic ကို wrap ပေးထားပြီး၊ level ဒါမှမဟုတ် N မည်သို့ပင်ဖြစ်စေ body ကို ပြန်ရေးစရာမလိုဘဲ local parameter များနှင့်ချိတ်ဆက် အသုံးပြုနိုင်သည်။ ဒုတိယ၊ array — LEVELS သည် log level သုံးခုကို list တစ်ခုတည်းအဖြစ် ထားရှိပြီး၊ for loop ဖြင့် လှည့်ပတ်ခြင်းသည် နောက်ပိုင်း level စတုတ္ထတစ်ခု ထပ်ထည့်ရန် line တစ်ကြောင်းသာ ပြောင်းရန်လိုအပ်စေမည်၊ block တစ်ခုလုံးကို copy-paste လုပ်ရန်မလိုတော့ပါ။ တတိယ၊ grep -c "$level" "$LOG_FILE" သည် ကိုက်ညီသောလိုင်းများကို ထုတ်ပြစရာမလိုဘဲ ရေတွက်ပေးသည် — grep output ကို wc -l ထဲ pipe ချထည့်ရသည်ထက် ပိုစျေးသက်ပြီး ရိုးရှင်းသည်။ စတုတ္ထ၊ အရေးအကြီးဆုံးဖြစ်သော sort | uniq -c | sort -nr pipeline — sed သည် timestamp နှင့် level prefix ကို ဖယ်ရှားပေးပြီး message စာသားချည်း ကျန်စေသည်၊ ပထမ sort က တူညီသော message များကို ကပ်လျက်ဖြစ်အောင် စုစည်းပေးသည် (uniq သည် ကပ်လျက်ရှိသောလိုင်းများကိုသာ collapse လုပ်ပေးနိုင်သောကြောင့် ဤအဆင့်ကို ကျော်လို့မရပါ)၊ uniq -c က အုပ်စုတစ်ခုချင်းစီကို ရေတွက်ပေးသည်၊ ပြီးတော့ ဒုတိယ sort -nr သည် ရလဒ်များကို အများဆုံးမှ အနည်းဆုံးသို့ ကိန်းသင်္ချာအရ စီပေးသဖြင့် အများဆုံးကြုံရသည့် failure ကို ဦးစွာပေါ်စေသည်။ head -n "$n" က ထို rank list ကို top N ခုသာ ကျန်စေအောင် ဖြတ်ချသည်။ ဤ component လေးခုစီသည် သီးခြားစီအနေနှင့် အသစ်တစ်ခုမျှ မဟုတ်ပါ — ဤနေရာ၌ အသစ်ဖြစ်နေသည်မှာ ၎င်းတို့ကို script တစ်ခုတည်းထဲတွင် chain ချိတ်ဆက်ကာ raw, unstructured စာသားကို structured, ranked report တစ်ခုအဖြစ် ပြောင်းလဲပေးနိုင်ခြင်းပင်ဖြစ်ပြီး၊ ဤ pattern ကို real ops နှင့် data work များတွင် အမြဲသုံးလေ့ရှိသည်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Ops နှင့် backend အင်ဂျင်နီယာများသည် တစ်ခုခုမှားယွင်းသွားပြီးနောက် ရိုးရှင်းသော မေးခွန်းနှစ်ခုကို ဖြေဆိုရန် — ဘယ်လောက်ဆိုးသလဲ၊ ဘာအများဆုံးပျက်ခဲ့သလဲ — log file များကို စိုက်ကြည့်နေရသည့် အချိန်အများကြီး ကုန်ဆုံးလေ့ရှိသည်။ ဤ script ဘာလုပ်သည်ကို တစ်ဆင့်ချင်း လိုက်ကြည့်ကြပါစို့— ပထမဦးဆုံး heredoc ဖြင့် sample.log အသေးလေးကို ရေးသားပြီး example ကို self-contained ဖြစ်စေကာ ထပ်ခါထပ်ခါ run လို့ရအောင် ပြုလုပ်ထားသည်၊ ထို့နောက် LOG_FILE၊ TOP_N နှင့် LEVELS array တို့ကို ထိပ်ဆုံးတွင် configuration အနေနှင့် သတ်မှတ်ထားသည်။ total_lines ကို wc -l < "$LOG_FILE" ဖြင့် ရယူသည် — wc -l "$LOG_FILE" ပုံစံအစား redirect ပုံစံသုံးခြင်းဖြင့် output ထဲတွင် file name ပါမလာစေဘဲ total_lines ကို ကိန်းအသန့်တစ်ခုအဖြစ် ရရှိစေသည်။ ထို့နောက် for loop သည် level တစ်ခုချင်းစီအတွက် count_level ကို ခေါ်ပြီး printf ဖြင့် တန်းမတ်သော column အဖြစ် ထုတ်ပြသည်။ နောက်ဆုံးတွင် top_error_messages သည် ERROR လိုင်းများကိုသာ filter လုပ်ပြီး၊ message စာသားမတိုင်မီရှိသမျှကို sed ဖြင့် ဖယ်ရှားကာ၊ sort/uniq/sort/head pipeline ကို run ၍ sample data ထဲမှ အဖြစ်များဆုံး failure နှစ်ခု — 'Database connection failed' (၄ ကြိမ်) နှင့် 'Disk write failed' (၂ ကြိမ်) — ကို ထုတ်ပြသည်။ production တွင်ဆိုလျှင် ဤသည်က on-call အင်ဂျင်နီယာတစ်ဦး incident တစ်ခုအတွင်း လိုင်းထောင်ချီကို လက်ဖြင့် ဆွဲကြည့်နေရခြင်း (သို့မဟုတ် ပိုဆိုးသည်က ခန့်မှန်းနေရခြင်း) နှင့် command တစ်ခုတည်း run ၍ 'ဘာအမှန်တကယ်ပျက်နေသလဲ' ကို ချက်ချင်းသိရခြင်း ကြားက ကွာခြားချက်ပင်ဖြစ်သည်။ ဤ script အတူတူကိုပင် real log တစ်ခုကို ညွှန်းပြီး cron ဖြင့် schedule ချထားလိုက်လျှင် တစ်ကြိမ်တည်း စုံစမ်းစစ်ဆေးမည့် tool အစား နေ့စဉ် သို့မဟုတ် နာရီအလိုက် summary report တစ်ခုအဖြစ် ပြောင်းလဲသွားနိုင်သည်။
အတူတူ စမ်းရေးကြည့်မယ်
#!/usr/bin/env bash
set -euo pipefail
# Create a small sample log file so this example is fully self-contained
cat > sample.log <<EOF
2026-01-01 10:00:01 INFO Server started
2026-01-01 10:00:05 INFO User login: alice
2026-01-01 10:01:12 WARN High memory usage
2026-01-01 10:02:33 ERROR Database connection failed
2026-01-01 10:02:34 ERROR Database connection failed
2026-01-01 10:03:10 INFO User login: bob
2026-01-01 10:04:00 ERROR Disk write failed
2026-01-01 10:05:22 WARN High memory usage
2026-01-01 10:06:45 ERROR Database connection failed
2026-01-01 10:07:00 INFO User logout: alice
2026-01-01 10:08:15 ERROR Disk write failed
2026-01-01 10:09:59 ERROR Database connection failed
EOF
LOG_FILE="sample.log"
TOP_N=3
LEVELS=("INFO" "WARN" "ERROR")
count_level() {
local level="$1"
grep -c "$level" "$LOG_FILE"
}
top_error_messages() {
local n="$1"
grep "ERROR" "$LOG_FILE" | sed -E 's/^[0-9-]+ [0-9:]+ ERROR //' | sort | uniq -c | sort -nr | head -n "$n"
}
total_lines=$(wc -l < "$LOG_FILE")
echo "Log Analysis Report for $LOG_FILE"
echo "=================================="
echo "Total lines: $total_lines"
for level in "${LEVELS[@]}"; do
printf "%-5s entries: %s\n" "$level" "$(count_level "$level")"
done
echo ""
echo "Top $TOP_N most frequent error messages:"
top_error_messages "$TOP_N"Log Analysis Report for sample.log
==================================
Total lines: 12
INFO entries: 4
WARN entries: 2
ERROR entries: 6
Top 3 most frequent error messages:
4 Database connection failed
2 Disk write failed၅ မိနစ် စမ်းကြည့်
sort/uniq pattern အတူတူကိုပင် သုံး၍ အများဆုံးကြုံရသော WARN message ကိုပါ ထုတ်ပြစေရန် script ကို တိုးချဲ့ပါ၊ ထို့အပြင် caller က report တစ်ခုလုံးကို log level တစ်ခုတည်းအတွက်သာ filter လုပ်နိုင်စေမည့် --level flag ကိုပါ ထည့်သွင်းပါ။
သတိလေးတစ်ချက်
grep -c "ERROR" ကို anchor မလုပ်ဘဲသုံးလျှင် message တစ်ခုအတွင်းရှိ စကားလုံးတစ်ခုနှင့်ပါ ကိုက်ညီနိုင်ပြီး count အမှားများ ဖြစ်နိုင်သည် — awk ကဲ့သို့ field-based match တစ်ခုသည် ပိုမိုတိကျသည်။
uniq -c သည် ကပ်လျက်ရှိသော ထပ်နေသည့်လိုင်းများကိုသာ ပေါင်းစည်းပေးသည်ကို မေ့လျော့တတ်သည် — input ကို အရင် sort မလုပ်ပါက ကပ်လျက်မရှိသည့် message တူများကို သီးခြားအုပ်စုအဖြစ် ရေတွက်သွားနိုင်သည်။
GNU Coreutils Manual — uniq — Bash / Shell Scripting