Bir servis beklenmedik şekilde durduğunda, disk aniden dolduğunda ya da şüpheli bir giriş denemesini araştırmanız gerektiğinde cevap neredeyse her zaman log dosyalarındadır. Sorun, çoğu yeni sistem yöneticisi loglara bakmayı bilse de doğru dosyayı, doğru komutu ve doğru filtreyi bilmemesidir. Binlerce satırlık bir log dosyasında doğru filtre bulunamayınca ya baştan sona kaydırılıp zaman kaybedilir ya da aranan satır gözden kaçar.
Bu yazıda journalctl komutundan /var/log altındaki klasik metin dosyalarına kadar, gerçek komutlarla log okumayı ele alıyorum. Örnekler hem systemd tabanlı güncel dağıtımlarda hem de eski tarz syslog kullanan sistemlerde çalışır.
systemd Sistemlerinde journalctl Kullanımı
Modern dağıtımların çoğu (Ubuntu 16.04+, Debian 8+, Fedora, RHEL 7+) systemd kullanır ve loglarını journald üzerinden ikili (binary) formatta tutar. Bu logları okumak için kullanılan komut journalctl:

journalctl
journalctl -f
Bayraksız çalıştırıldığında komut en eski kayıttan başlar. -f bayrağı ise tail -f gibi davranır ve yeni gelen satırları canlı gösterir. Çıktı varsayılan olarak less benzeri bir sayfalayıcıda açılır: ok tuşlarıyla gezinip q ile çıkabilirsiniz, /arananmetin yazıp Enter'a basmak sayfalayıcı içinde arama yapar.
Belirli bir servisin loglarını filtrelemek en sık yapılan işlemdir:
journalctl -u nginx.service
journalctl -u nginx.service --since "1 hour ago"
--since ve --until insan tarafından okunabilir tarih ifadeleri kabul eder: "2026-07-01 09:00:00", "yesterday", "1 hour ago" gibi. İkisini birlikte kullanmak belirli bir zaman aralığını daraltır. Örneğin journalctl -u nginx.service --since "09:00" --until "09:30" yalnızca o yarım saatlik pencereyi gösterir; bir kesinti raporunu incelerken bu daralma, gereksiz binlerce satırı elemenizi sağlar.
Sadece hata seviyesindeki kayıtları görmek için önem seviyesi filtrelenebilir:
journalctl -p err -b
-p err yalnızca error ve üzeri (crit, alert, emerg) kayıtları gösterir. -b ise sonucu mevcut açılış oturumuyla sınırlar. syslog önem seviyeleri sekiz basamaklıdır: emerg, alert, crit, err, warning, notice, info, debug. -p warning yazdığınızda warning ve üzerindeki her şeyi görürsünüz; yalnızca tek bir seviyeyi istiyorsanız -p warning..warning gibi aralık sözdizimi kullanılır.
Önceki açılışları listelemek ve o oturuma ait logları görmek, çökme sonrası teşhiste kritiktir:
journalctl --list-boots
journalctl -b -1
-b -1 bir önceki açılışı, -b -2 iki önceki açılışı gösterir. Sunucu beklenmedik şekilde yeniden başladıysa, çökme anındaki son satırlar genelde önceki oturumun sonunda bulunur. journalctl -b -1 -p err bu iki filtreyi birleştirir ve yalnızca önceki oturumdaki hata seviyesi kayıtları gösterir; bir sunucu neden yeniden başladığını araştırırken ilk çalıştırılacak komut genelde budur.
Klasik Metin Tabanlı Log Dosyaları
journald her şeyi kapsamaz; birçok uygulama hâlâ kendi log dosyasını /var/log/ altına düz metin olarak yazar. En sık başvurulan dosyalar şunlardır:
| Dosya | İçeriği |
|---|---|
/var/log/syslog (Debian/Ubuntu) | Genel sistem mesajları |
/var/log/messages (RHEL/CentOS) | Genel sistem mesajları |
/var/log/auth.log / /var/log/secure | Giriş denemeleri, sudo kullanımı |
/var/log/kern.log | Kernel mesajları |
/var/log/nginx/error.log | Web sunucu hataları |
Debian ve Ubuntu'da /var/log/syslog genelde en genel başvuru noktasıdır. RHEL ailesinde aynı işi /var/log/messages görür; ikisi de kernel dışı sistem servislerinin ürettiği mesajları toplar. Bu dosyaları canlı izlemek için tail -f klasik yöntemdir, birden fazla dosyayı aynı anda takip etmek de mümkündür:
tail -f /var/log/syslog
tail -f /var/log/nginx/*.log
Büyük bir log dosyasında belirli bir metni aramak için grep kullanılır. Tarih aralığına göre süzmek için satır numaralarıyla uğraşmak yerine doğrudan tarihi arayabilirsiniz:
grep -i "failed password" /var/log/auth.log
grep "Jul 2" /var/log/syslog | grep -i error
Log dosyaları sonsuza kadar büyümez. logrotate adlı araç bu dosyaları belirli aralıklarla (genelde günlük ya da haftalık) sıkıştırıp arşivler ve eski kopyaları siler. Yapılandırması /etc/logrotate.d/ altındadır ve her uygulama genelde kendi kuralını buraya bırakır. Örneğin /etc/logrotate.d/nginx dosyası kaç eski kopyanın tutulacağını (rotate 14), ne zaman döndürüleceğini (daily) ve eski kopyaların sıkıştırılıp sıkıştırılmayacağını (compress) tanımlar. Bu yüzden bir sunucuda access.log.1, access.log.2.gz gibi dosyalar görürsünüz.
Bir kuralı elle test etmek isterseniz sudo logrotate -d /etc/logrotate.d/nginx komutu "debug" modunda çalışır ve hiçbir dosyayı değiştirmeden ne yapacağını ekrana yazar. Yapılandırma değişikliğinden sonra gerçek dosyalara dokunmadan önce doğrulama yapmanın güvenli yolu budur.
Güvenlik Olaylarını Loglardan Yakalamak
Sunucunuza kimlerin giriş denemesi yaptığını görmek, saldırı tespitinin ilk adımıdır. Başarısız SSH girişlerini saymak için:

grep "Failed password" /var/log/auth.log | wc -l
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
İkinci komut başarısız girişleri IP adresine göre gruplar ve en çok deneme yapan adresleri en üste sıralar. Kısa sürede yüzlerce deneme yapan bir IP genelde otomatik bir brute-force saldırısının işaretidir. journald tabanlı sistemlerde aynı sorguyu journalctl -u ssh --since today | grep "Failed password" | wc -l şeklinde de yazabilirsiniz; /var/log/auth.log her dağıtımda aynı isimle bulunmaz.
Başarılı girişleri de ayrıca kontrol etmek gerekir:
last -n 20
lastb -n 20
last başarılı girişleri, lastb ise başarısız girişleri (bad logins) listeler; ikinci komut için /var/log/btmp dosyasının var olması gerekir. Bilinmeyen bir saatte ya da tanımadığınız bir konumdan başarılı giriş görürseniz, bu parolanın ele geçirilmiş olabileceğinin ilk işaretidir. last çıktısındaki her satır kullanıcı adını, terminali, giriş kaynağını (IP ya da hostname) ve oturum süresini gösterir. last reboot yalnızca sistem yeniden başlatmalarını listeler ve kararsız bir sunucunun geçmişini hızlıca ortaya koyar.
Tekrarlayan brute-force denemelerine karşı manuel log takibi yeterli kalmaz. fail2ban gibi araçlar logları otomatik izler ve belirli eşiği aşan IP'leri güvenlik duvarından geçici olarak engeller. Kurulumu basittir ama yapılandırması loglardaki gerçek desenleri anlamayı gerektirir; bu yüzden önce elle log okumaya aşina olmak faydalıdır.
sudo apt install fail2ban ile kurduktan sonra /etc/fail2ban/jail.local dosyasında bantime, findtime ve maxretry değerlerini kendi eşiklerinize göre ayarlarsınız; varsayılan olarak SSH için beş başarısız denemeden sonra on dakikalık bir yasak uygulanır. sudo fail2ban-client status sshd komutu o an yasaklı IP listesini gösterir ve elle takip ettiğiniz logların otomatikleştirilmiş hâlidir.
Disk Dolarsa: Log Dosyalarını Küçültmek
Log dosyaları zamanla diski doldurabilir, özellikle logrotate yanlış yapılandırılmışsa ya da bir uygulama hata döngüsüne girip aynı satırı binlerce kez yazıyorsa. Bir uygulama saniyede yüzlerce satır yazan bir hata döngüsüne girdiğinde /var/log birkaç saat içinde gigabaytlarca yer kaplayabilir; bu durumda önce hangi dosyanın şişkin olduğunu bulmak gerekir. Hangi log dosyasının en çok yer kapladığını bulmak için:

du -sh /var/log/* | sort -rh | head -10
Çalışan bir servisin hâlâ yazdığı dosyayı silmek yerine dosyayı boşaltmak daha güvenlidir. rm kullanırsanız servis dosya tanıtıcısını (file descriptor) tutmaya devam eder ve disk alanı, servis yeniden başlayana kadar gerçekte boşalmaz. Bu durumu lsof +L1 komutu ortaya çıkarır: silinmiş ama hâlâ bir süreç tarafından açık tutulan dosyaları listeler. df -h disk dolu gösterirken du -sh çok daha az yer kullanılmış görünüyorsa neden genelde budur:
truncate -s 0 /var/log/nginx/access.log
journald'ın kendi disk kullanımını sınırlamak için /etc/systemd/journald.conf içinde SystemMaxUse ayarlanabilir:
[Journal]
SystemMaxUse=500M
Bu satır journal'ın diskte en fazla 500 MB yer kaplamasına izin verir; aşıldığında en eski kayıtlar otomatik silinir. SystemMaxFileSize ile tek bir journal dosyasının boyutunu, MaxRetentionSec ile kayıtların ne kadar süre tutulacağını ayrıca sınırlayabilirsiniz; örneğin MaxRetentionSec=30day otuz günden eski hiçbir kaydı tutmaz. Değişiklikten sonra sudo systemctl restart systemd-journald komutuyla servisi yeniden başlatmanız gerekir.
Mevcut journal boyutunu görmek için:
journalctl --disk-usage
Log Formatlarını Yapılandırılmış Biçimde Okumak
Karmaşık filtreleme yapacaksanız journalctl'ın JSON çıktısı, script yazarken düz metinden çok daha kullanışlıdır:
journalctl -u nginx -o json-pretty | head -40
journalctl -u nginx -o json | jq '.MESSAGE'
jq ile JSON çıktısını ayrıştırmak, belirli alanları (zaman damgası, öncelik, mesaj) programatik olarak çekmenizi sağlar; bir izleme scripti yazarken düz metin grep'ten çok daha güvenilirdir. journalctl -u nginx -o json | jq 'select(.PRIORITY=="3")' gibi bir filtre yalnızca error seviyesindeki (PRIORITY=3) kayıtları JSON formatında çeker; bu çıktıyı bir izleme sistemine (Prometheus, Grafana Loki gibi) beslemek istediğinizde başlangıç noktası genelde budur.
Belirli bir sürecin (PID) tüm loglarını izlemek istediğinizde:
journalctl _PID=4521
journalctl _COMM=sshd
_COMM=sshd yalnızca SSH daemon'ının ürettiği kayıtları gösterir; bu, karışık bir syslog dosyasında elle arama yapmaktan çok daha hızlı bir yoldur. _UID=1001 gibi kullanıcı ID'sine göre filtrelemek de mümkündür. Bir kullanıcının başlattığı tüm süreçlerin loglarını tek sorguda toplamak, paylaşımlı bir sunucuda sorumluyu bulmayı hızlandırır.
Log okumak başlangıçta göz korkutucu görünse de, doğru filtreyi bulduğunuzda bir sorunu dakikalar içinde teşhis etmenizi sağlayan en güvenilir araçtır. Resmî journalctl kılavuz sayfası (man journalctl) her filtre seçeneğini örnekleriyle listeler.
Henüz yorum yok.
Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.