Tarkibga o'tish

Loglarni tahlil qilish

Linux loglari va Tizim loglari va dmesg maqolalarida log'lar qayerda turishi va qanday yig'ilishi ko'rib chiqildi. Keyingi qadam — bu xom ma’lumotdan amaliy xulosa chiqarish. Bitta log faylini ko'z bilan ko'zdan kechirish oson; kuniga bir necha million qator yozadigan production serverni esa hech kim qatorma-qator o'qimaydi. Bu maqola Fayl va matn qidirish hamda Matnni qayta yozish: sed va awk maqolalarida ko'rilgan vositalarni aynan log tahliliga qo'llaydi va vositalar to'plamiga journalctl ning tuzilgan chiqish formatlarini qo'shadi.

Laboratoriya ma’lumotlari

Quyidagi buyruqlar haqiqiy production log'iga o'xshaydigan, lekin to'liq sizning nazoratingizda qoladigan sinov faylini yaratadi:

mkdir -p ~/lab/logs && cd ~/lab/logs
cat > app.log <<'EOF'
2026-07-24 09:12:01 INFO  ip=10.0.0.5 path=/api/login status=200 duration=42ms
2026-07-24 09:12:03 ERROR ip=10.0.0.9 path=/api/orders status=500 duration=1381ms
2026-07-24 09:12:05 INFO  ip=10.0.0.5 path=/api/orders status=200 duration=88ms
2026-07-24 09:12:07 ERROR ip=10.0.0.9 path=/api/orders status=500 duration=1290ms
2026-07-24 09:12:10 WARN  ip=10.0.0.7 path=/api/login status=401 duration=15ms
2026-07-24 09:12:12 ERROR ip=10.0.0.9 path=/api/orders status=500 duration=1455ms
2026-07-24 09:12:20 INFO  ip=10.0.0.5 path=/api/profile status=200 duration=30ms
EOF

Quyidagi har bir buyruq shu ~/lab/logs/app.log fayli ustida ishlaydi va faqat o'qiydi — hech qanday real tizimga ta’sir qilmaydi.

grep bilan kerakli hodisalarni ajratib olish

grep ERROR app.log
2026-07-24 09:12:03 ERROR ip=10.0.0.9 path=/api/orders status=500 duration=1381ms
2026-07-24 09:12:07 ERROR ip=10.0.0.9 path=/api/orders status=500 duration=1290ms
2026-07-24 09:12:12 ERROR ip=10.0.0.9 path=/api/orders status=500 duration=1455ms

Bir vaqtda bir nechta shart bo'yicha qidirish uchun kengaytirilgan muntazam ifodalardan (-E) foydalaning:

grep -E 'ERROR|WARN' app.log

Mosliklarni sanash:

grep -c ERROR app.log
3

Atrofdagi kontekstni — xato qatoridan oldin va keyin nima bo'lganini ko'rish:

grep -B1 -A1 ERROR app.log

-B1 moslikdan bitta oldingi, -A1 esa bitta keyingi qatorni ko'rsatadi — hodisaning atrofidagi kontekstni tushunish uchun foydali.

Aylantirilgan va siqilgan log'lardan qidirish

Real hodisalar kamdan-kam hollarda joriy fayl ichida qoladi. Linux loglari maqolasida ko'rsatilganidek, logrotate eski log'larni syslog.1 ga qayta nomlaydi va undan keyingi hammasini syslog.2.gz, syslog.3.gz va hokazo ko'rinishda siqadi — oddiy grep esa .gz faylni o'qiy olmaydi. z prefiksli variantlar faylni o'qish jarayonida ochadi:

zgrep ERROR /var/log/syslog.2.gz
zcat /var/log/syslog.3.gz | awk '/ERROR/ { print }'

Aylantirilgan to'plamning hammasini — joriy fayl va har bir arxivni — bir o'tishda ko'rib chiqish uchun zgrep glob’ni to'g'ridan-to'g'ri qabul qiladi va oddiy hamda siqilgan fayllarni birga o'qiydi:

zgrep -h 'status=500' /var/log/syslog*

Buni unutish klassik xato: grep ERROR /var/log/syslog oxirgi rotation’dan oldingi hech narsani topmaydi va kerakli dalil bitta .gz fayl narida turgan bo'lsa ham, indamay to'liq bo'lmagan manzara beradi.

awk bilan ustunli ma’lumotlarni ajratib olish

Har bir ERROR qatoridan faqat ip= qiymatini ajratib olish:

grep ERROR app.log | awk -F'ip=' '{print $2}' | awk '{print $1}'
10.0.0.9
10.0.0.9
10.0.0.9

Bu ikki bosqichli yondashuv tushunarli, lekin awk ning o'zi xuddi shu ishni bitta buyruqda bajara oladi:

awk '/ERROR/ { for (i=1; i<=NF; i++) if ($i ~ /^ip=/) print $i }' app.log

Qaysi IP manzil eng ko'p xato keltirib chiqarganini topish — amalda eng keng tarqalgan andozalardan biri:

grep ERROR app.log | grep -oE 'ip=[0-9.]+' | sort | uniq -c | sort -rn
3 ip=10.0.0.9

Zanjir quyidagicha ishlaydi: grep -oE faqat mos kelgan bo'lakni (ip=...) ajratib oladi, sort bir xil qiymatlarni birga guruhlaydi, uniq -c har biri necha marta takrorlanishini sanaydi, oxirgi sort -rn esa natijani eng ko'p sondan eng kamiga qarab tartiblaydi — eng ko'p uchraydigan qiymat birinchi bo'ladi.

Javob vaqtini (duration) tahlil qilish — masalan, eng sekin uchta so'rovni topish:

grep -oE 'duration=[0-9]+ms' app.log | grep -oE '[0-9]+' | sort -rn | head -n 3
1455
1381
1290

Tip

awk da ichki sort yo'q, shuning uchun sonli tartiblash odatda qiymatlarni awk bilan ajratib olib, ishni sort -n bilan yakunlash orqali bajariladi — ikki vositani zanjirga ulash vaqtinchalik yechim emas, standart andoza.

journalctl ni tuzilgan ko'rinishda olish

Oddiy matn ustidagi grep/awk zanjiri log formatini oldindan bilishni talab qiladi. journalctl yozuvlari esa allaqachon tuzilgan va ularni JSON ko'rinishida olish mumkin:

journalctl -u ssh.service -n 3 --output=json-pretty
{
    "__CURSOR" : "s=8f2a...",
    "_SYSTEMD_UNIT" : "ssh.service",
    "PRIORITY" : "6",
    "MESSAGE" : "Accepted publickey for ali from 10.0.0.5 port 51422",
    "__REALTIME_TIMESTAMP" : "1753349532000000"
}

Bu format skript orqali qayta ishlash uchun qulay, chunki maydonlar (MESSAGE, PRIORITY, _SYSTEMD_UNIT) oldindan ma’lum va ularga format o'zgarishlaridan xavotirlanmasdan murojaat qilish mumkin. Agar jq o'rnatilgan bo'lsa, masalan:

journalctl -u ssh.service -n 50 --output=json | jq -r 'select(.PRIORITY|tonumber <= 3) | .MESSAGE'

Bu faqat err darajasidagi yoki undan jiddiyroq (PRIORITY <= 3, Tizim loglari va dmesg maqolasidagi jadvalga mos) yozuvlarning xabar matnini chiqaradi.

Bir nechta manbani vaqt bo'yicha bog'lash

Real muammoni aniqlash ko'pincha bittadan ko'p manbani talab qiladi. Masalan, ilova xatosi (app.log dagi ERROR) bo'lsa, aynan o'sha lahzada tizimda yana nima bo'layotganini bilish foydali:

journalctl --since "2026-07-24 09:12:00" --until "2026-07-24 09:12:15" --no-pager

Bu journalctl maqolasida ko'rilgan --since/--until filtrini aynan xato yuz bergan oraliqqa qo'llaydi. Agar shu oraliqda xotira bosimi yoki xizmatning qayta ishga tushishi haqida systemd xabari chiqsa, u ilova xatosining haqiqiy sababini tushuntirib berishi mumkin — bunday resurslarga bog'liq vaziyatlar Resurslar bo'yicha troubleshooting maqolasida chuqurroq ko'rib chiqiladi.

Amaliy vaziyat: qaysi endpoint eng ko'p muammo tug'dirmoqda

awk '$3 ~ /ERROR|WARN/ { for (i=1;i<=NF;i++) if ($i ~ /^path=/) print $i }' app.log \
    | sort | uniq -c | sort -rn
3 path=/api/orders
1 path=/api/login

Talqin: /api/orders uchta ERROR yozuvi bilan, /api/login esa bitta WARN bilan qayd qilingan — demak, e’tibor avval /api/orders ga qaratilishi kerak. Bu xulosani ko'r-ko'rona qabul qilish o'rniga avtomatik hisoblangan sonni manba fayl bilan solishtirib tekshirishga arziydi:

grep 'path=/api/orders' app.log

Bu tekshirish qadami avtomatik hisobni xom log bilan tasdiqlaydi — professional tahlilda hech qachon tashlab ketilmasligi kerak bo'lgan qadam.

Intervyuda

Intervyuda ko'p beriladigan sinov savoli: "grep/awk zanjiringiz qatorlarni indamay tushirib qoldirmayotgani yoki ikki marta sanamayotganini qayerdan bilasiz?" To'g'ri javob shuki, mustaqil vositalardan qurilgan har qanday pipeline noto'g'ri formatdagi kirishda — yetishmayotgan maydon, ekranlanmagan belgi, kodlash muammosi — kutilmagan xatti-harakat qilishi mumkin. Aynan shu sababli yuqoridagi tekshirish qadami (hisoblangan sonni xom manba ustida grep bilan qayta tekshirish) ixtiyoriy pardoz emas; u asosida harakat qilish mumkin bo'lgan son bilan shunchaki ishonarli ko'rinadigan son o'rtasidagi farq.

Keng tarqalgan xatolar

Regex maxsus belgilarini ekranlamaslik

grep '10.0.0.9' da nuqta (.) muntazam ifodada oddiy nuqta emas, "istalgan belgi" degani. Aniq IP manzilni qidirish uchun grep -F '10.0.0.9' (literal qidiruv) yoki grep '10\.0\.0\.9' (ekranlangan) dan foydalaning — aks holda 10a0b0c9 kabi qator mos kelmasligi kerak bo'lgan joyda mos kelib qolishi mumkin.

Hisoblangan statistikani manba bilan tekshirmaslik

Sintaksisi to'g'ri, lekin ustun yoki filtri noto'g'ri bo'lgan sort | uniq -c zanjiri noto'g'ri, ammo ishonchli ko'rinadigan son berishi mumkin. Muhim xulosa asosida harakat qilishdan oldin uni xom log bilan kamida bir marta solishtirib tekshiring.

journalctl ning oddiy matn formatini tahlil uchun barqaror deb hisoblash

journalctl ning sukut bo'yicha (matn) chiqishi versiyalar o'rtasida formatlashda biroz o'zgarishi mumkin. Skript tayanadigan har qanday narsa uchun --output=json yoki --output=cat kabi aniq formatlar oddiy matnni awk/sed bilan tahlil qilishdan ancha ishonchliroq.

Mashqlar

  1. Yuqoridagi laboratoriya faylida grep yordamida status=500 bo'lgan barcha qatorlarni ajratib oling va ularni -c bilan sanang.
  2. awk yordamida har bir qatordan duration qiymatini ajratib oling va o'rtachasini hisoblang (awk ichida sum/count o'zgaruvchi andozasidan foydalanib).
  3. journalctl -u ssh.service -n 20 --output=json-pretty ni ishga tushiring va kamida to'rtta maydonni (MESSAGE, PRIORITY, _PID, __REALTIME_TIMESTAMP) toping.
  4. O'zingiz vaziyat o'ylab toping (masalan, "qaysi foydalanuvchi eng ko'p 401 xato keltirib chiqargan") va uni yuqoridagi laboratoriya fayli ustida grep/awk zanjiri bilan hal qiling.

Mashqni bajardim deyish uchun: 1-mashqda hisoblagan soningiz xom faylni mustaqil o'qib olgan qatorlar soniga mos kelishi kerak — agar mos kelmasa, ma’lumotlar emas, filtr sharti noto'g'ri.

Manbalar

  • man7.org: grep(1): https://man7.org/linux/man-pages/man1/grep.1.html
  • GNU Awk User’s Guide: https://www.gnu.org/software/gawk/manual/gawk.html
  • man7.org: journalctl(1) — --output formatlari: https://man7.org/linux/man-pages/man1/journalctl.1.html
  • jq qo'llanmasi: https://jqlang.org/manual/