Bir web sitesi 502 hatası veriyor, veritabanı bağlantısı kopuyor ya da bir servis açılışta ayağa kalkmıyorsa cevabın nerede olduğu bellidir: loglarda. Modern Linux dağıtımlarında (Ubuntu, Debian, Rocky Linux, AlmaLinux) neredeyse her servis çıktısını systemd'nin merkezi günlük altyapısı olan journald'a yazar. Bu logları okumanın, filtrelemenin ve canlı izlemenin tek aracı ise journalctl. Bir sistem yöneticisinin en sık açacağı komutlardan biri odur; çünkü "sunucuda bir şey ters gitti" cümlesinin somut karşılığı çoğu zaman journalctl -u servis -n 50 çıktısında saklıdır.
Bu rehberde journalctl'i günlük hata ayıklama pratiğine oturtacağız. Belirli bir servisin loglarını okumaktan zamana ve önem derecesine göre süzmeye, önyükleme (boot) bazlı incelemeden journald'ın disk kullanımını sınırlamaya kadar sahada gerçekten işinize yarayacak sorguları örneklerle ele alacağız. Servislerin nasıl başlatıldığını ve durdurulduğunu henüz tam oturtmadıysanız önce systemd servis yönetimi yazımıza, temel kabuk komutlarında eksik hissediyorsanız Linux temel komutları rehberimize göz atmanızı öneririz.
journald ve journalctl Nedir#
Klasik Linux dünyasında loglar /var/log altında düz metin dosyalarına yazılırdı: /var/log/syslog, /var/log/nginx/error.log, /var/log/auth.log gibi. Her servisin kendi dosyası, kendi biçimi ve kendi rotasyon (dönüşüm) mantığı vardı. systemd bu dağınıklığı journald adında merkezi bir günlük servisiyle topladı. journald, sistemdeki tüm servislerin standart çıktısını (stdout), standart hata akışını (stderr), çekirdek mesajlarını ve syslog trafiğini tek bir ikili (binary) veritabanında saklar. Her log satırının yanına metadata ekler: hangi servis, hangi süreç (PID), hangi kullanıcı, hangi önyükleme, hangi öncelik seviyesi.
journalctl bu ikili veritabanını okuyup önünüze getiren araçtır. Loglar ikili biçimde tutulduğu için cat veya less ile doğrudan okunamaz; journalctl metadata sayesinde çok güçlü filtreleme imkânı sunar. Argümansız çalıştırdığınızda en eski kayıttan en yeniye tüm günlüğü bir sayfalayıcı (pager) içinde açar:
# Tüm günlüğü baştan sona görüntüle (q ile çıkılır)
journalctl
# En yeni kayıtları en üstte göster
journalctl -r
# En son 100 satırı göster
journalctl -n 100
Günlükleri okuyabilmek için genellikle sudo gerekir veya kullanıcınızın systemd-journal grubunda olması beklenir. Root olmayan bir kullanıcı yalnızca kendi kullanıcı oturumuna ait mesajları görebilir; sistem servislerinin tamamını görmek için yetki şarttır.
Belirli Bir Servisin Loglarını Okuma#
Günlük hayatta journalctl'i en çok tek bir servisin loglarını okumak için kullanırsınız. -u (unit) bayrağı burada başrolde. Bir servis çöktüğünde, beklenmedik davrandığında ya da yapılandırma değişikliği sonrası düzgün çalışıp çalışmadığını doğrulamak istediğinizde ilk komutunuz bu olmalı:
# nginx servisinin tüm loglarını göster
journalctl -u nginx
# Son 50 satırı göster (hata ayıklamada en pratik başlangıç)
journalctl -u nginx -n 50
# Birden fazla servisi aynı anda izle
journalctl -u nginx -u php8.2-fpm
systemctl status nginx komutu da size servisin son birkaç log satırını gösterir, ama yalnızca 10 satır kadar. Gerçek sorunu görmek için neredeyse her zaman journalctl -u ile daha geriye gitmeniz gerekir. Örneğin bir servis failed durumuna düştüğünde, hatanın gerçek nedeni (yanlış dosya yolu, port çakışması, izin hatası, sözdizimi hatası) tam olarak burada yazar. Bu iş akışı systemd servis yönetimi rehberindeki systemctl status adımının doğal devamıdır.
Belirli bir sürecin loglarını PID üzerinden de çekebilirsiniz; bu, aynı servisin birden fazla örneği çalışıyorsa işe yarar:
# 1421 numaralı sürecin loglarını göster
journalctl _PID=1421
# Belirli bir çalıştırılabilir dosyaya ait tüm loglar
journalctl /usr/sbin/sshd
Canlı Log Takibi ve Gerçek Zamanlı İzleme#
Bir sorunu yeniden üretirken logların gerçek zamanlı akışını izlemek çok değerlidir. -f (follow) bayrağı, klasik tail -f mantığıyla çalışır: komut açık kalır ve yeni log satırları geldikçe ekrana düşer. Bir isteği tarayıcıdan tetiklerken diğer terminalde bu komutu açık tutmak, hata ayıklamanın en verimli yöntemlerinden biridir:
# nginx loglarını canlı izle (Ctrl+C ile durdurulur)
journalctl -u nginx -f
# Son 20 satırı göster, sonra canlı takibe geç
journalctl -u nginx -n 20 -f
# Tüm sistemin canlı akışını izle
journalctl -f
Canlı takibi seviye filtresiyle birleştirmek, gürültüyü ciddi biçimde azaltır. Örneğin yalnızca hata ve üstü mesajları canlı izlemek isterseniz -p err -f kombinasyonu tam istediğiniz şeydir. Bir WordPress sitesinde beyaz ekran (WSOD) hatasını yeniden üretirken PHP-FPM loglarını journalctl -u php8.2-fpm -f -p warning ile izlemek, sorunun tam anını yakalamanızı sağlar. Uygulama katmanındaki PHP hatalarını daha derinlemesine incelemek için WordPress hata çözümü yazımızdaki adımlarla bu çıktıyı birlikte değerlendirebilirsiniz.
Zamana Göre Filtreleme#
Bir kesinti "dün gece 03.00 civarı" yaşandıysa binlerce satırı elle taramak zaman kaybıdır. --since ve --until bayrakları logları tam olarak ilgilendiğiniz zaman aralığına daraltır. journalctl esnek zaman ifadelerini anlar: mutlak tarih-saat, göreli ifadeler ("2 hours ago") ve today, yesterday gibi anahtar kelimeler:
# Bugünün logları
journalctl --since today
# Son bir saatin logları
journalctl --since "1 hour ago"
# Belirli bir tarih-saat aralığı
journalctl --since "2026-07-10 02:00:00" --until "2026-07-10 04:00:00"
# Dünden bugüne, sadece nginx
journalctl -u nginx --since yesterday --until now
Zaman filtresini servis ve seviye filtreleriyle birlikte kullanmak, olay incelemesinin (post-mortem) belkemiğidir. Aşağıdaki tablo en sık kullanacağınız zaman ifadelerini özetliyor:
| Zaman ifadesi | Anlamı |
|---|---|
--since today | Gece yarısından itibaren |
--since yesterday | Dünkü gece yarısından itibaren |
--since "10 min ago" | Son 10 dakika |
--since "2026-07-10" | Belirtilen tarihten itibaren (00.00) |
--until "1 hour ago" | Bir saat öncesine kadar |
--since "-3 days" | Son 3 gün |
Bir örnek senaryo: cumartesi sabahı sitenin yavaşladığını bildiren bir müşteriniz var. Şu tek satır, o pencerede PHP-FPM tarafında ne olduğunu gösterir:
journalctl -u php8.2-fpm --since "2026-07-10 07:00" --until "2026-07-10 10:00" -p warning
Önem Derecesine Göre Süzme (Log Seviyeleri)#
Her log satırının bir öncelik (priority) değeri vardır; bu, syslog standardından gelen 0-7 arası bir ölçektir. -p bayrağı ile bir eşik belirlediğinizde, o seviye ve daha kritik olan tüm mesajları görürsünüz. Yani -p err derseniz err, crit, alert ve emerg gelir; debug ve info gürültüsü elenir. Seviyeleri hem isimle hem numarayla belirtebilirsiniz:
| Numara | İsim | Anlamı |
|---|---|---|
| 0 | emerg | Sistem kullanılamaz durumda |
| 1 | alert | Derhal müdahale gerekli |
| 2 | crit | Kritik durum |
| 3 | err | Hata |
| 4 | warning | Uyarı |
| 5 | notice | Normal ama dikkate değer |
| 6 | info | Bilgi amaçlı |
| 7 | debug | Ayrıntılı hata ayıklama |
Pratikte en çok err ve warning eşiklerini kullanırsınız:
# Sadece hata ve üstü mesajlar
journalctl -p err
# Uyarı ve üstü, son önyüklemeye ait
journalctl -p warning -b
# Belirli bir servisin sadece hataları, bugüne ait
journalctl -u mysql -p err --since today
# Bir aralık ver: sadece warning ile err arası
journalctl -p warning..err
Bir sunucuyu ilk devraldığınızda "sistemde şu an kritik ne var?" sorusunun hızlı cevabı journalctl -p err -b komutudur; son açılıştan bu yana biriken tüm hataları önünüze serer. Bu, düzenli bir sağlık kontrolü alışkanlığı olarak da değerlidir.
Önyükleme (Boot) Bazlı Log İnceleme#
journald, her sistem açılışını ayrı bir "boot" olarak etiketler. Bu, özellikle sunucu beklenmedik biçimde yeniden başladığında ("neden reboot oldu?") ya da açılış sırasında bir servis takıldığında paha biçilmezdir. Önce kayıtlı önyüklemeleri listeleyin, sonra ilgilendiğiniz olana odaklanın:
# Kayıtlı tüm önyüklemeleri listele (her birine bir indeks atanır)
journalctl --list-boots
# Mevcut (son) önyüklemenin logları
journalctl -b
# Bir önceki önyükleme (-1), iki önceki (-2)
journalctl -b -1
# Belirli bir önyüklemenin sadece hataları
journalctl -b -1 -p err
--list-boots çıktısında her önyüklemenin bir ofset numarası (0 = şu anki, -1 = bir önceki), bir boot ID'si ve zaman aralığı görünür. Sunucunun gece kendiliğinden yeniden başladığından şüpheleniyorsanız journalctl -b -1 -e ile bir önceki önyüklemenin son satırlarını (kapanış anını) okuyarak kapanışın temiz mi yoksa ani mi olduğunu anlayabilirsiniz. Çekirdek (kernel) mesajlarına odaklanmak için -k bayrağını ekleyin; donanım veya OOM (bellek yetersizliği) kaynaklı sorunlar burada görünür:
# Bir önceki önyüklemenin çekirdek mesajları
journalctl -b -1 -k
# OOM killer izlerini ara
journalctl -k | grep -i "out of memory"
Kalıcı ve Uçucu Depolama Ayarı#
Varsayılan olarak birçok dağıtımda journald logları uçucu (volatile) tutar; yani /run/log/journal altında bellekte saklar ve sunucu her yeniden başladığında bu loglar silinir. Bu, journalctl -b -1 gibi komutların "boş" dönmesinin en sık nedenidir: önceki önyüklemenin logları diskte kalıcı değildi. Logları yeniden başlatmalar arasında saklamak istiyorsanız kalıcı (persistent) depolamaya geçmelisiniz. Bu, hata ayıklama ve olay incelemesi için neredeyse her zaman istenen ayardır.
Kalıcı depolamayı /etc/systemd/journald.conf dosyasından açarsınız:
[Journal]
# Diskte kalıcı sakla (/var/log/journal)
Storage=persistent
Değişikliği uygulamak için dizini oluşturup servisi yeniden başlatın:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
# Kalıcı depolamaya geçildiğini doğrula
journalctl --disk-usage
Storage seçeneğinin alabileceği değerler şunlardır:
| Değer | Davranış |
|---|---|
volatile | Yalnızca bellekte (/run), yeniden başlatmada silinir |
persistent | Diskte (/var/log/journal), kalıcı; dizin yoksa oluşturur |
auto | /var/log/journal varsa kalıcı, yoksa uçucu (varsayılan) |
none | Hiç saklama; loglar iletilir ama tutulmaz |
auto varsayılanı yüzünden, /var/log/journal dizinini oluşturmak çoğu zaman kalıcılığı açmak için tek başına yeterlidir. Yine de niyeti açık kılmak için Storage=persistent yazmak temiz bir pratiktir.
Disk Kullanımını Sınırlama (SystemMaxUse)#
Kalıcı loglama açıldığında en büyük risk, günlüklerin diski sessizce doldurmasıdır. Yoğun bir sunucuda journald birkaç gigabaytı hızla bulabilir ve /var dolduğunda servisler yazamaz hale gelir. Neyse ki journald otomatik rotasyon yapar ve boyutu kontrol etmeniz için birkaç ayar sunar. Mevcut kullanımı görmek için başlayın:
# journald'ın anlık disk kullanımı
journalctl --disk-usage
Ardından /etc/systemd/journald.conf içinde sınırları tanımlayın. En önemlisi SystemMaxUse — journald'ın diskte tutabileceği toplam üst sınır:
[Journal]
Storage=persistent
# Toplam log boyutu en fazla 500 MB
SystemMaxUse=500M
# Tek bir günlük dosyası en fazla 50 MB
SystemMaxFileSize=50M
# Logları en fazla 30 gün sakla
MaxRetentionSec=30day
# Disk %15 dolduğunda eski logları sil (boş alan koru)
SystemKeepFree=15%
Ayarları değiştirdikten sonra servisi yeniden başlatın:
sudo systemctl restart systemd-journald
Yapılandırmayı beklemeden, mevcut logları elle de budayabilirsiniz. Bu, /var aniden dolduğunda hayat kurtaran iki komuttur:
# Son 200 MB dışındaki tüm logları sil
sudo journalctl --vacuum-size=200M
# 7 günden eski tüm logları sil
sudo journalctl --vacuum-time=7d
# En fazla 5 dosya tut
sudo journalctl --vacuum-files=5
Aşağıdaki tablo en çok kullanılan sınırlama seçeneklerini özetliyor:
| Ayar | İşlevi |
|---|---|
SystemMaxUse | Diskteki toplam log boyutu üst sınırı |
SystemMaxFileSize | Tek günlük dosyasının azami boyutu |
SystemKeepFree | Diskte korunacak asgari boş alan |
MaxRetentionSec | Logların azami saklama süresi |
--vacuum-size | Anlık: verilen boyutun üstünü sil |
--vacuum-time | Anlık: verilen süreden eskiyi sil |
Disk doluluğu genel bir sunucu bakımı konusudur; /var neden dolar, hangi dizin şişer gibi sorulara daha geniş bir çerçeveden bakmak isterseniz Linux temel komutları yazımızdaki du ve df bölümü iyi bir başlangıçtır.
Pratik Hata Ayıklama Sorguları#
Teoriyi bir kenara bırakıp sahada gerçekten kopyalayıp yapıştıracağınız birkaç sorguyu toplayalım. Bir sunucuda "bir şeyler ters" dendiğinde bu komutlar dakikalar içinde yön verir. Bir servis ayağa kalkmıyorsa son elli satırı ters sırayla okuyun:
journalctl -u nginx -n 50 -r
Bir kesinti sonrası son bir saatte sistem genelinde hangi hataların biriktiğini görmek için:
journalctl -p err --since "1 hour ago"
Çıktıyı tam biçimde, kırpılmadan ve zaman damgalarını UTC olarak görmek isterseniz (log paylaşırken faydalı):
journalctl -u mysql -o short-iso-precise --utc -n 100
Bir metni loglar içinde aramak için grep yerine journald'ın kendi filtrelerini kullanmak daha temizdir, ama hızlı arama için boru (pipe) da işinizi görür:
# Belirli bir hata mesajını ara
journalctl -u nginx | grep -i "connection refused"
# JSON çıktısı — log toplama araçlarına beslemek için
journalctl -u nginx -o json-pretty -n 5
Son olarak, çıktı biçimlerini bilmek işinizi kolaylaştırır. -o bayrağıyla varsayılan short yerine short-iso (ISO tarih), verbose (tüm metadata), json (makine okunur) ve cat (sadece mesaj, metadata yok) biçimlerini seçebilirsiniz. Bir logu bir e-postaya ya da destek talebine yapıştırırken -o cat gürültüyü temizler; bir olay incelemesi yaparken -o verbose size süreç, kullanıcı ve öncelik dahil her şeyi verir.
Sıkça Sorulan Sorular#
journalctl ile /var/log altındaki eski log dosyaları arasındaki fark nedir?#
journalctl, systemd'nin merkezi günlük servisi journald tarafından tutulan ikili (binary) veritabanını okur; /var/log/syslog veya /var/log/nginx/error.log gibi klasik düz metin dosyaları ise ilgili servislerin doğrudan diske yazdığı dosyalardır. journald, tüm servisleri metadata ile tek yerde toplayıp güçlü filtreleme sunarken, klasik log dosyaları hâlâ birçok uygulama (özellikle nginx ve Apache erişim logları) tarafından ayrıca tutulur. Pratikte sunucu ve servis düzeyi olaylar için journalctl'e, uygulamaya özel erişim/hata detayları için ise /var/log dosyalarına bakarsınız.
journalctl -b -1 neden boş çıktı veriyor?#
Bu neredeyse her zaman journald'ın uçucu (volatile) modda çalışmasından kaynaklanır; loglar bellekte tutulur ve sunucu her yeniden başladığında silinir, dolayısıyla bir önceki önyüklemenin kaydı diskte kalmaz. Çözüm, kalıcı depolamaya geçmektir: /var/log/journal dizinini oluşturup Storage=persistent ayarını yapın ve systemd-journald servisini yeniden başlatın. Bu ayardan sonra önceki önyüklemelerin logları saklanır ve --list-boots çıktısında geçmiş açılışları görebilirsiniz.
journald diskimi doldurursa ne yapmalıyım?#
Öncelikle journalctl --disk-usage ile ne kadar yer kapladığını görün, ardından anlık olarak sudo journalctl --vacuum-size=200M veya sudo journalctl --vacuum-time=7d komutuyla eski logları budayın. Kalıcı çözüm için /etc/systemd/journald.conf içinde SystemMaxUse (toplam boyut sınırı) ve SystemKeepFree (korunacak boş alan) değerlerini tanımlayıp servisi yeniden başlatın; böylece journald kendini otomatik olarak bu sınırların altında tutar ve /var bölümünü bir daha doldurmaz.
Belirli bir servisin sadece hatalarını nasıl görürüm?#
Servis filtresi olan -u ile önem eşiği belirleyen -p bayrağını birleştirmeniz gerekir; örneğin journalctl -u mysql -p err yalnızca MySQL'in err seviyesi ve üstündeki (crit, alert, emerg) mesajlarını getirir, info ve debug gürültüsünü eler. Buna bir de zaman filtresi eklerseniz incelemeyi iyice daraltabilirsiniz; journalctl -u mysql -p err --since today bugünkü tüm MySQL hatalarını listeler. Canlı takip için sona -f eklemeniz yeterlidir.
journalctl -f ile tail -f arasında ne fark var?#
İkisi de yeni satırları anlık olarak ekrana düşürür, ama tail -f yalnızca tek bir düz metin dosyasını izlerken journalctl -f journald'ın tuttuğu tüm merkezi günlüğü izler ve metadata sayesinde aynı anda servise (-u), önem derecesine (-p) ve zamana göre filtrelemenize izin verir. Yani journalctl -u nginx -f -p warning gibi bir komutla tek bir dosyaya bağlı kalmadan, tam istediğiniz kesiti canlı takip edebilirsiniz; bu esneklik klasik tail -f ile mümkün değildir.
Root olmadan journalctl kullanabilir miyim?#
Kısmen. Root olmayan bir kullanıcı varsayılan olarak yalnızca kendi kullanıcı oturumuna ait log mesajlarını görebilir; sistem servislerinin (nginx, mysql, sshd) tüm loglarını okumak için ya sudo kullanmanız ya da kullanıcınızı systemd-journal grubuna eklemeniz gerekir. sudo usermod -aG systemd-journal kullaniciadi komutuyla bir kullanıcıya bu yetkiyi kalıcı olarak verebilirsiniz; değişikliğin geçerli olması için oturumu kapatıp açması gerekir.
Kapanış#
journalctl, systemd tabanlı bir Linux sunucusunda hata ayıklamanın merkezindeki araçtır. -u ile servise, --since / --until ile zamana, -p ile önem derecesine odaklanmak; -f ile canlı izlemek ve -b ile önyüklemeleri ayrı ayrı incelemek bir kez alışkanlık haline geldiğinde, "sunucuda bir sorun var" cümlesini birkaç dakikada somut bir hataya indirgersiniz. journald'ı kalıcı depolamaya geçirip SystemMaxUse ile disk kullanımını sınırlamak ise bu logların hem kalıcı hem de güvenli olmasını sağlar.
Tüm bunları uygulamak için root erişimine sahip, journald'ı özgürce yapılandırabileceğiniz bir sunucuya ihtiyacınız var. Clou.TR'nin VDS sunucuları ve sanal sunucu çözümleri size bu tam kontrolü sunar; kurulum, izleme ve log yönetimi yükünü uzman bir ekibe bırakmak isterseniz sunucu yönetimi hizmetimiz ile journald yapılandırmanızı ve servis izlemenizi biz sizin adınıza üstlenelim. İhtiyacınıza uygun bir başlangıç için tüm sunucu paketlerimizi inceleyebilir, paylaşımlı bir ortamdan başlıyorsanız hosting paketlerimize göz atabilirsiniz.