journalctl ile Log Okuma: Sorun Gidermek İçin Pratik Rehber
systemd günlüklerini servis, zaman aralığı, öncelik ve açılış bazında filtrelemeyi; günlük boyutunu sınırlamayı ve gerçek bir arıza analizini örneklerle anlatan rehber.
Bir servis çalışmıyor, bir betik gece sessizce başarısız oldu ya da cihaz yeniden başladı ve nedenini bilmiyorsunuz. Böyle anlarda ilk bakacağınız yer günlüklerdir. Modern Linux dağıtımlarında (Raspberry Pi OS dahil) bunların çoğu systemd-journald tarafından toplanır ve journalctl ile okunur. Doğru filtreleri bilmek, bir arızayı on dakikada ya da iki saatte çözmek arasındaki farkı yaratır.
Temel kullanım
Parametresiz çalıştırdığınızda tüm kayıtlar en eskiden yeniye gelir; bu pek işe yaramaz. Pratikte hep bir filtreyle kullanılır:
journalctl -n 50 # son 50 satır
journalctl -f # canlı izle (tail -f gibi)
journalctl -e # sonuna git
Sayfalayıcıdan çıkmak için q'ya basın. Uzun satırlar kesiliyorsa --no-pager ile düz çıktı alabilir ya da -o cat ile yalnızca mesaj kısmını görebilirsiniz.
Servise göre filtrelemek
En sık kullanacağınız seçenek -u (unit) parametresidir:
journalctl -u nginx.service -n 100
journalctl -u myapp -f
Birden fazla servisi birlikte görmek istiyorsanız -u parametresini tekrarlayın:
journalctl -u myapp -u mariadb --since today
Servis adlarının sonuna .service yazmak zorunlu değildir. Bir servisin adından emin değilseniz systemctl list-units --type=service listesine bakın.
Zamana göre filtrelemek
--since ve --until doğal ifadeleri anlar:
journalctl --since "1 hour ago"
journalctl --since "2026-10-18 22:00" --until "2026-10-19 02:00"
journalctl -u myapp --since yesterday --until today
"Dün gece 02:00 civarında bir şey oldu" gibi durumlarda bu ifade size doğrudan o pencereyi verir. Zaman damgalarının tam biçimde (saat dilimiyle) görünmesi için -o short-iso kullanın.
Önceliğe göre filtrelemek
Günlük satırlarının bir önem düzeyi vardır: emerg, alert, crit, err, warning, notice, info, debug. -p parametresi, belirtilen düzey ve daha ciddilerini getirir:
journalctl -p err -b # bu açılıştan beri hatalar
journalctl -p warning --since today
Bir sistemin genel sağlığına bakarken journalctl -p err -b iyi bir başlangıç noktasıdır; çıktı kısaysa sorun muhtemelen başka yerdedir.
Açılışlara göre bakmak
Cihaz yeniden başladıysa, önceki açılışın kayıtlarına bakmak gerekir:
journalctl --list-boots # açılışların listesi
journalctl -b # bu açılış
journalctl -b -1 # bir önceki açılış
journalctl -b -1 -e # önceki açılışın sonuna git
Önceki açılışların kayıtları ancak günlükler kalıcı tutuluyorsa vardır. Varsayılan ayar dağıtıma göre değişir; kalıcı olup olmadığını ls /var/log/journal ile anlayabilirsiniz. Dizin yoksa ve kalıcılığı istiyorsanız:
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
Dikkat: Raspberry Pi'de SD kart ömrü için günlükleri RAM'de tutmak istenebilir; iki ihtiyaç çelişir. Hangisini seçeceğiniz, "arıza sonrası kayıt" ile "kart ömrü" arasındaki tercihtir. Bu dengeyi SD kart yazısında ele aldık; ortada bir çözüm olarak günlüklere sınır koymak mümkündür.
Metin aramak
-g (grep) parametresi, kayıtlarda düzenli ifade arar:
journalctl -u myapp -g "Traceback|Error" --since today
journalctl -k -g "usb|mmc" # çekirdek mesajları
-k yalnızca çekirdek mesajlarını gösterir ve dmesg çıktısıyla benzerdir. Alternatif olarak çıktıyı grep ile süzebilirsiniz; -g ise filtrelemeyi veri okunurken yapar ve çoğu durumda daha hızlıdır.
Günlüğün boyutunu yönetmek
Günlükler sonsuza kadar büyümez ama varsayılan sınırlar küçük disklerde yine de fazla olabilir. Mevcut kullanımı görün:
journalctl --disk-usage
Eski kayıtları elle temizlemek:
sudo journalctl --vacuum-size=200M
sudo journalctl --vacuum-time=14d
Kalıcı bir sınır için /etc/systemd/journald.conf dosyasında SystemMaxUse=200M değerini ayarlayın ve sudo systemctl restart systemd-journald komutunu çalıştırın. Her satırı kendiniz silmeye çalışmayın; journald'in kendi mekanizmasını kullanmak güvenlidir.
Uygulamanızdan günlük yazmak
Bir Python betiği ya da servisi standart çıktıya (print, logging.StreamHandler) yazdığında, systemd bunu otomatik olarak journal'a alır; ek bir dosya yönetimine gerek kalmaz. Bu, aynı zamanda log dosyası döndürme (logrotate) ihtiyacını da azaltır. Uygulamanızı servis olarak çalıştırmak için Flask + systemd rehberine bakabilirsiniz.
Bir betikten manuel olarak kayıt eklemek için logger komutu kullanılabilir:
logger -t yedek "Gece yedegi basladi"
journalctl -t yedek -n 5
Örnek: "Dün gece yedek çalışmadı"
Bir yedekleme servisinin yedek.service adıyla bir timer tarafından tetiklendiğini varsayalım. Sırayla şunlara bakılır:
systemctl status yedek.timer # bir sonraki ve son çalışma zamanı
journalctl -u yedek.service --since yesterday
journalctl -u yedek.service -p err --since "3 days ago"
journalctl --since "yesterday 02:00" --until "yesterday 04:00"
Birinci komut timer'ın etkin olup olmadığını gösterir. İkinci komut servisin çıktısını verir; üçüncü yalnızca hataları süzer. Dördüncüsü ise servisle ilgisiz olarak o saat aralığında sistemde ne olduğunu gösterir ve örneğin ağın o sırada koptuğunu ortaya çıkarabilir. Zamanlanmış görevlerin nasıl tanımlanacağı için systemd timer rehberine bakın.
Hızlı başvuru
| İhtiyaç | Komut |
|---|---|
| Son 50 satır | journalctl -n 50 |
| Canlı izle | journalctl -f |
| Servis | journalctl -u ad |
| Zaman | --since "1 hour ago" |
| Hata düzeyi | -p err |
| Önceki açılış | -b -1 |
| Metin ara | -g "desen" |
| Boyut | --disk-usage, --vacuum-size=200M |
Bu birkaç komutu bilmek, çoğu sunucu sorununu tahmine değil kanıta dayanarak çözmenizi sağlar. Günlüklerde aradığınızı bulamıyorsanız bile, hangi aralıkta ve hangi servisten kayıt olmadığı önemli bir bilgidir.