Maqolalar 7 daqiqa 215 ko‘rish
«Sayt yotibdi!» — journalctl bilan sababni besh daqiqada topish
Xizmat yiqilganda taxmin bilan emas, loglar bilan ishlanadi. journalctl'ning kundalik ishda kerak bo'ladigan qismini o'rganamiz: to'g'ri savol berish, vaqt bo'yicha toraytirish, yashirin restart-halqalarni ushlash va jurnal diskni yeb qo'ymasligini ta'minlash.
Mundarija
Qo'ng'iroq keladi: "sayt ochilmayapti". Shu daqiqada ikki xil yo'l bor. Birinchisi — taxmin qilish: restart berib ko'ramiz, balki o'tib ketar. Ikkinchisi — jurnalga qarash va nima bo'lganini bilib harakat qilish. Birinchi yo'l ba'zan tezroq tuyuladi, lekin sabab topilmagani uchun muammo ertaga yana qaytadi. Bu maqola ikkinchi yo'l haqida.
Seriya davomida hamma xizmatni systemd ostiga olib, loglarni stdout'ga yozdirib keldik — endi shu intizom o'z mevasini beradi: hamma narsaning jurnali bitta joyda, bitta tool bilan o'qiladi.
Boshlanish nuqtasi: status va oxirgi satrlar#
Muammo bo'lganda birinchi buyruq har doim bitta:
systemctl status mysite-web
Bu yerda uch narsani birdan ko'rasiz: xizmat holati (active, failed,
activating auto-restart...), qachondan beri shu holatda ekani va —
eng foydalisi — jurnaldan oxirgi o'nta satr. Ko'p hollarda sabab shu o'nta
satrning ichida yozib turadi: import xatosi, band port, topilmagan fayl.
Yetmasa, jurnalning o'zini ochamiz:
journalctl -u mysite-web -e # -e: oxiridan boshlab ko'rsat
journalctl -u mysite-web -f # -f: jonli oqim (yangi satrlar tushib turadi)
Jurnalni o'qish huquqi
1-qismda yaratgan deploy
foydalanuvchisi jurnalni to'liq ko'rmaydi. Ilovaning o'z chiqishi
ko'rinadi, lekin systemd'ning xabarlari (Started, Failed) va
nginx, postgres kabi boshqa xizmatlarning yozuvlari chiqmaydi — pastdagi
tekshiruvlar esa aynan shularga tayanadi. Buyruqlarni sudo bilan
bering yoki deployni bir marta jurnal guruhiga qo'shing:
sudo usermod -aG systemd-journal deploy, keyin serverdan chiqib,
qayta kiring.
To'g'ri savol berish san'ati#
journalctl -u mysite-web ni ochsangiz, oldingizda minglab satr turadi.
Loglar bilan ishlashning asosiy mahorati — hammasini o'qish emas,
so'rovni toraytirish. Uchta filtr kundalik ishning to'qson foizini
yopadi:
# vaqt bo'yicha: muammo qachon boshlangan bo'lsa, o'sha atrofga qaraymiz
journalctl -u mysite-web --since "14:20" --until "14:40"
journalctl -u mysite-web --since "10 min ago"
# matn bo'yicha: Python xatolari (pattern kichik harfda — katta-kichikka qaramaydi)
journalctl -u mysite-web -g "traceback|error" --since today
journalctl -u mysite-web -g "Timeout" --since yesterday # katta harf bor — aniq moslik
# daraja bo'yicha: systemd'ning ogohlantirish va xatolari (yiqilishlar)
journalctl -u mysite-web -p warning --since today
Ilova xatolarini nega -p err bilan emas, matn bilan qidiryapmiz? systemd
xizmatning stdout va stderr'iga yozilgan har bir satrni jurnalga bir xil
info darajasida yozadi — Python traceback'i ham bundan mustasno emas.
Shuning uchun journalctl -u mysite-web -p err ilova yiqilib yotgan
paytda ham -- No entries -- deyishi mumkin. -p daraja bilan yozadigan
dasturlarda va systemd'ning o'z xabarlarida ishlaydi: masalan, xizmat
yiqilganda chiqadigan Failed with result 'exit-code' — warning.
Sayt 500 qaytaryapti, jurnal esa jim
DEBUG = False bo'lganda Django 500 xatolarining traceback'ini
standart holatda konsolga chiqarmaydi — faqat ADMINS ga email
yuborishga urinadi. Natijada foydalanuvchi "Server Error" ko'radi,
jurnalda esa hech narsa yo'q.
Xatolar jurnalga tushishi uchun sozlamaga bitta blok qo'shing:
# config/settings.py
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {"console": {"class": "logging.StreamHandler"}},
"loggers": {"django": {"handlers": ["console"], "level": "ERROR"}},
}
Endi har 500 xato jurnalda Internal Server Error: /yo'l/ va to'liq
traceback bilan paydo bo'ladi.
Va yana bittasi — reboot bilan bog'liq muammolarda oltinga teng:
journalctl -b # faqat shu yonishdan beri
journalctl -b -1 -e # OLDINGI yonishning oxiri — o'chishdan avval nima bo'lgan?
-b -1 ko'p narsani ochib beradi: server o'zi o'chib qolgan bo'lsa,
sababning izi (masalan OOM-killer ishi) aynan oldingi sessiyaning so'nggi
satrlarida qoladi.
Yashirin kasallik: restart-halqa#
Restart=always bilan ishlaydigan xizmatning bir ayyor holati bor:
u yiqilib-turib ishlayotgan bo'lishi mumkin — har safar restart uni
qutqaradi va tashqaridan hammasi joyida ko'rinadi. Buni
Aladdin seriyasida ogohlantirgan edim,
endi ushlash usulini ko'rsataman:
# bugun necha marta ishga tushgan?
sudo journalctl -u mysite-web --since today | grep -c "Started"
# oxirgi qo'lda start/restart'dan beri systemd uni necha marta o'zi qayta ko'targan?
systemctl show mysite-web -p NRestarts
Bugun deploy ham, reboot ham bo'lmagan bo'lsa, birinchi javob 0 bo'lishi
kerak; bo'lgan bo'lsa — ularning soniga teng. NRestarts=0 bo'lishi
kerak. Javob 47 chiqsa — xizmatingiz kun bo'yi o'lib-tirilib yurgan. Sabab
odatda takrorlanuvchi xato bo'ladi va uni yiqilish paytlarining logidan
topasiz:
# oxirgi yiqilish atrofi: "Main process exited" dan oldingi satrlarda traceback turadi
sudo journalctl -u mysite-web -n 60 --no-pager
Qatlamlarni ajratish: log qaysi savolga javob beradi#
Muammo har doim ham ilovada emas. "Sayt ochilmayapti" degan shikoyat ortida to'rt xil qatlam turishi mumkin va har birining o'z jurnali bor:
| Savol | Qayerga qaraymiz |
|---|---|
| Umuman serverga yetib kelyaptimi? | tashqaridan curl -I va serverda sudo tail -f /var/log/nginx/access.log — bu ayrimda server emas, tarmoq muammosi bo'lib chiqadi |
| Nginx qabul qilib, orqaga uzatolmayaptimi? | /var/log/nginx/error.log — 502 tekshiruv tartibi |
| Ilova ichida xato bormi? | journalctl -u mysite-web -g traceback |
| Baza javob bermayaptimi? | sudo tail -n 50 /var/log/postgresql/postgresql-16-main.log |
Birinchi va oxirgi qatorga e'tibor bering: Ubuntu'da nginx va PostgreSQL o'z loglarini
jurnalga emas, fayllarga yozadi. journalctl -u nginx yoki
journalctl -u postgresql da faqat ishga tushish va to'xtash xabarlari
bo'ladi (nginx konfiguratsiyasi xato bo'lib ishga tushmasa, sababi ham
shu yerda). Fayl nomidagi 16-main — PostgreSQL versiyasi va klaster nomi,
o'zingizdagisini ls /var/log/postgresql/ ko'rsatadi.
Tartib muhim: tashqaridan ichkariga qarab yurasiz. Har qatlamda "bu qatlam sog'mi?" degan bitta savolga javob olasiz va muammo qaysi chegarada yotganini toraytirasiz — xuddi binar qidiruv kabi.
Jurnalning o'zi diskni yemasin#
Bitta amaliy detal ko'pincha e'tibordan chetda qoladi: journald ham disk egallaydi va default sozlamalarda ancha keng yashaydi. Kichik VPS'da buni chegaralab qo'ygan ma'qul:
sudo nano /etc/systemd/journald.conf
[Journal]
# jurnal reboot'dan keyin ham saqlansin (default ba'zan RAM'da!)
Storage=persistent
# jami hajm chegarasi — eski yozuvlar o'zi o'chadi
SystemMaxUse=500M
Izohlarni qiymat bilan bir qatorga yozmang. systemd qator ichidagi # ni
izoh deb bilmaydi: Storage=persistent # ... ni butun holicha qiymat deb
o'qiydi, Failed to parse storage setting, ignoring deydi va sozlamani
jimgina tashlab yuboradi.
sudo systemctl restart systemd-journald
# sozlama qabul qilinganini tekshiramiz — "max 500.0M" ko'rinishi kerak:
sudo journalctl -u systemd-journald -n 3 --no-pager
sudo journalctl --disk-usage # hozir qancha joy egallayotganini ko'rsatadi
Storage=persistent'ni tekshiring
Ba'zi tizimlarda jurnal faqat xotirada yashaydi — reboot bo'ldi, loglar
yo'q. Ayni "server nega o'chdi" degan eng muhim savolni tekshirayotganda
-b -1 bo'sh chiqadi. Storage=persistent bir qator, lekin aynan qora
kunda kerak bo'ladigan qator.
Yakun#
Loglar bilan ishlash tartibi qisqa: systemctl statusdan boshlang, vaqt va
daraja bilan toraytiring, reboot masalasida -b -1ni unutmang, restart-
halqani grep -c "Started" bilan tekshiring va qatlamma-qatlam tashqaridan
ichkariga yuring. Restart — davolash emas, og'riq qoldiruvchi; tashxis esa
har doim jurnalda.
Seriyaning so'nggi qismi oldinda: sirlarni boshqarish — token va parollar qayerda yashashi kerak, qayerda esa hech qachon ko'rinmasligi kerak.