Debian’da Log Yönetimi ve journald Yapılandırması

Bir sunucuda bir şeyler ters gittiğinde, log dosyaları senin en iyi arkadaşın olur. Ama bu arkadaşın düzgün yapılandırılmamışsa, ihtiyacın olduğu anda seni yarı yolda bırakabilir. Debian sistemlerde log yönetimi, geleneksel syslog tabanlı araçlardan modern systemd-journald sistemine geçişle birlikte hem daha güçlü hem de daha karmaşık bir hal aldı. Bu yazıda Debian üzerinde log yönetimini baştan sona ele alacağız: journald yapılandırmasından log rotasyonuna, merkezi log sunucusundan pratik troubleshooting senaryolarına kadar her şeyi konuşacağız.

journald Nedir ve Neden Önemlidir?

systemd-journald, systemd’nin bir parçası olarak gelen binary formatlı log yönetim daemonudur. Geleneksel syslog’dan en temel farkı, logları düz metin yerine binary formatta saklamasıdır. Bu sayede metadata zengin, sorgulama hızlı ve veri bütünlüğü korumalı bir log ortamı elde edersin.

Debian Bullseye ve sonrasında systemd varsayılan init sistemi olduğundan journald de otomatik olarak devrede gelir. Ancak çoğu Debian kurulumunda rsyslog da varsayılan olarak yüklüdür ve journald ile birlikte çalışır.

Şunu net söyleyeyim: journald ve rsyslog birbirinin rakibi değil, tamamlayıcısıdır. journald sistem loglarını toplar, rsyslog ise bu logları klasik /var/log/ dizinine metin dosyası olarak yazar. İkisini birlikte kullanmak en yaygın ve önerilen yaklaşımdır.

journald Temel Yapılandırması

journald’nin ana yapılandırma dosyası /etc/systemd/journald.conf dosyasıdır. Varsayılan değerleri görmek için önce bu dosyaya bir bakalım:

cat /etc/systemd/journald.conf

Dosya içeriği genellikle şöyle görünür ama büyük kısmı yorum satırı olarak gelir:

[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes

Şimdi production ortamı için önerilen bir yapılandırma yapalım. /etc/systemd/journald.conf dosyasını düzenleyelim:

sudo nano /etc/systemd/journald.conf

Aşağıdaki yapılandırmayı uygulayalım:

[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=2G
SystemKeepFree=1G
SystemMaxFileSize=200M
SystemMaxFiles=20
MaxRetentionSec=3month
MaxFileSec=1week
ForwardToSyslog=yes
RateLimitIntervalSec=30s
RateLimitBurst=50000

Önemli parametrelerin ne işe yaradığını açıklayayım:

  • Storage=persistent: Logları /var/log/journal/ dizinine kalıcı olarak yazar. auto değerinde bu dizin yoksa RAM’e yazar.
  • Compress=yes: Log dosyalarını sıkıştırır, disk tasarrufu sağlar.
  • SystemMaxUse=2G: Journal’in kullanabileceği maksimum disk alanı.
  • SystemKeepFree=1G: Disk üzerinde en az bu kadar boş alan bırakır.
  • SystemMaxFileSize=200M: Tek bir journal dosyasının maksimum boyutu.
  • SystemMaxFiles=20: Maksimum journal dosyası sayısı.
  • MaxRetentionSec=3month: Log kayıtlarının tutulma süresi.
  • RateLimitBurst=50000: 30 saniyede maksimum 50000 mesaj kabul eder, yoğun log basan servisler için artırılabilir.

Yapılandırmayı uygulamak için journald’yi yeniden başlatalım:

sudo systemctl restart systemd-journald

Kalıcı Log Depolama Ayarı

Varsayılan Debian kurulumlarında journal logları RAM’de tutulur ve sistem yeniden başladığında kaybolur. Production sunucusunda bu kabul edilemez bir durum. Kalıcı depolamayı etkinleştirmek için:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

Artık logların kalıcı olarak saklandığını doğrulayalım:

ls -la /var/log/journal/
journalctl --disk-usage

journalctl ile Log Sorgulama

journalctl komutu, journal loglarını sorgulamak için kullanılan ana araçtır. Günlük işlerde en çok kullandığım komutları paylaşayım.

Temel kullanım örnekleri:

# Son 50 log satırını göster
journalctl -n 50

# Gerçek zamanlı log takibi (tail -f gibi)
journalctl -f

# Belirli bir servisin loglarını göster
journalctl -u nginx.service

# Son 1 saatin logları
journalctl --since "1 hour ago"

# Belirli zaman aralığı
journalctl --since "2024-01-15 08:00:00" --until "2024-01-15 10:00:00"

# Sadece hata logları (priority: err ve üzeri)
journalctl -p err

# Belirli bir process ID'nin logları
journalctl _PID=1234

# Kernel logları
journalctl -k

# Belirli bir boot'un logları
journalctl -b -1  # bir önceki boot

# JSON formatında çıktı
journalctl -u ssh.service -o json-pretty | head -50

# Belirli bir kullanıcının logları
journalctl _UID=1000

Gerçek bir senaryo düşünelim: Nginx servisiniz gece 03:00’da çökmüş ve siz sabah gelip bunu fark ettiniz. Ne yaparsınız?

# Önce nginx ile ilgili tüm hataları bulalım
journalctl -u nginx.service -p err --since "yesterday"

# Servis restart edilmiş mi kontrol edelim
journalctl -u nginx.service | grep -E "Started|Stopped|Failed"

# O gece tam olarak ne olduğuna bakalım
journalctl -u nginx.service --since "2024-01-15 02:00:00" --until "2024-01-15 04:00:00"

rsyslog ile Entegrasyon

Debian’da rsyslog, journald ile birlikte çalışır. /etc/rsyslog.conf ve /etc/rsyslog.d/ dizinindeki yapılandırma dosyaları ile logları yönetirsiniz.

rsyslog’un journald’den log alabilmesi için imjournal modülünün yüklenmiş olması gerekir. /etc/rsyslog.conf dosyasında şu satırların olduğundan emin olun:

# /etc/rsyslog.d/50-default.conf dosyasına ekleyin
# Özel uygulama loglarını ayırma örneği
if $programname == 'myapp' then /var/log/myapp/application.log
& stop

# Auth loglarını ayrı tut
auth,authpriv.*    /var/log/auth.log

# Kritik hataları ayrı dosyaya yaz
*.crit             /var/log/critical.log

rsyslog’u yeniden başlatalım:

sudo systemctl restart rsyslog

logrotate ile Log Rotasyonu

Loglar zamanla büyür ve disk dolabilir. logrotate bu problemi çözer. Debian’da /etc/logrotate.d/ dizininde her servis için ayrı rotasyon kuralları tanımlanabilir.

Özel bir uygulama için logrotate yapılandırması oluşturalım:

sudo nano /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/myapp.pid ]; then
            kill -USR1 $(cat /var/run/myapp.pid)
        fi
    endscript
}

Yapılandırma parametrelerini açıklayayım:

  • daily: Her gün rotasyon yap
  • rotate 30: 30 eski dosyayı sakla
  • compress: Eski dosyaları gzip ile sıkıştır
  • delaycompress: En son rotasyonu sıkıştırma, bir sonrakinde sıkıştır
  • notifempty: Boş log dosyasını rotate etme
  • create 0640: Yeni log dosyasını bu izinlerle oluştur
  • postrotate/endscript: Rotasyon sonrası çalışacak komut

Logrotate yapılandırmasını test etmek için:

# Dry-run (gerçekten çalıştırmaz, sadece ne yapacağını gösterir)
sudo logrotate -d /etc/logrotate.d/myapp

# Zorla çalıştır
sudo logrotate -f /etc/logrotate.d/myapp

Merkezi Log Sunucusu Kurulumu

Birden fazla sunucu yönetiyorsanız, logları tek bir yerden toplamak büyük kolaylık sağlar. rsyslog ile basit bir merkezi log sunucusu kuralım.

Log Sunucusu (Server) Tarafı:

sudo nano /etc/rsyslog.conf

Aşağıdaki satırları ekleyin veya uncomment edin:

# TCP üzerinden log alma (514 portu)
module(load="imtcp")
input(type="imtcp" port="514")

# UDP üzerinden log alma
module(load="imudp")
input(type="imudp" port="514")

# Gelen logları hostname'e göre ayrı dizinlere yaz
$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteLogs
& ~

Log dizinini oluşturalım:

sudo mkdir -p /var/log/remote
sudo chown syslog:adm /var/log/remote
sudo systemctl restart rsyslog

Firewall’da 514 portunu açalım:

sudo ufw allow 514/tcp
sudo ufw allow 514/udp

Log İstemcisi (Client) Tarafı:

sudo nano /etc/rsyslog.d/remote-logging.conf
# Tüm logları merkezi sunucuya gönder (TCP)
*.* @@192.168.1.100:514

# Sadece kritik logları gönder
*.crit @192.168.1.100:514

@@ TCP, @ UDP anlamına gelir. TCP daha güvenilir olduğundan tercih edilir.

sudo systemctl restart rsyslog

Log Güvenliği ve İzleme

Log güvenliği genellikle ihmal edilen bir konudur. Logların bütünlüğünü korumak için bazı önlemler alalım.

journald Seal Özelliği:

journald’nin Seal=yes özelliği (varsayılan olarak aktiftir), log dosyalarını kriptografik olarak imzalar. Bu sayede log manipülasyonu tespit edilebilir.

# Journal bütünlüğünü kontrol et
journalctl --verify

Log Dosyası İzinleri:

# /var/log dizinindeki önemli dosyaların izinlerini kontrol et
ls -la /var/log/auth.log
ls -la /var/log/syslog

# auth.log sadece root ve adm grubu tarafından okunabilmeli
sudo chmod 640 /var/log/auth.log
sudo chown root:adm /var/log/auth.log

fail2ban ile Entegrasyon:

fail2ban, log dosyalarını izleyerek şüpheli aktivitelerde IP’leri banlar. journald ile entegrasyonu şöyle yapılır:

sudo apt install fail2ban

sudo nano /etc/fail2ban/jail.local
[DEFAULT]
backend = systemd
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = ssh
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Disk Alanı Yönetimi ve Temizlik

Journal logları zamanla disk alanını tüketebildiğinden, periyodik temizlik gerekebilir.

# Mevcut journal disk kullanımını göster
journalctl --disk-usage

# 2 haftadan eski logları sil
sudo journalctl --vacuum-time=2weeks

# Journal boyutunu 500MB ile sınırla
sudo journalctl --vacuum-size=500M

# Belirli sayıda dosyadan fazlasını sil
sudo journalctl --vacuum-files=10

Bu temizlik işlemlerini otomatikleştirmek için bir cron job oluşturalım:

sudo nano /etc/cron.weekly/journal-cleanup
#!/bin/bash
# Journal loglarını haftalık temizle
journalctl --vacuum-time=4weeks --vacuum-size=2G
echo "Journal cleanup completed on $(date)" >> /var/log/journal-cleanup.log
sudo chmod +x /etc/cron.weekly/journal-cleanup

Gerçek Dünya Senaryosu: Yavaş Servis Teşhisi

Bir web uygulamanızın zaman zaman yavaşladığına dair şikayetler geliyor. Loglar üzerinden problemi bulalım.

# Nginx access loglarında yavaş istekleri bul (3 saniyeden uzun)
grep "request_time" /var/log/nginx/access.log | awk '$NF > 3 {print}' | tail -20

# PHP-FPM loglarını journald üzerinden kontrol et
journalctl -u php8.2-fpm.service --since "2 hours ago" -p warning

# Sistem kaynak kullanımını loglara bak
journalctl -k --since "today" | grep -E "OOM|memory|swap"

# Hangi servisler en çok log üretiyor?
journalctl --since "1 hour ago" | awk '{print $5}' | sort | uniq -c | sort -rn | head -20

Problemin veritabanı bağlantısından kaynaklandığını düşünüyorsak:

# PostgreSQL loglarını kontrol et
journalctl -u postgresql.service --since "2 hours ago" | grep -E "ERROR|FATAL|slow query"

# Bağlantı sayısını loglardan takip et
journalctl -u postgresql.service | grep "connection" | tail -30

Log Analizi için Pratik Araçlar

Günlük log analizini kolaylaştıran bazı araçları da kuralım:

# lnav - terminal tabanlı log görüntüleyici
sudo apt install lnav

# Kullanım
lnav /var/log/syslog
lnav /var/log/nginx/access.log /var/log/nginx/error.log

# goaccess - nginx/apache log analiz aracı
sudo apt install goaccess

# Gerçek zamanlı web log analizi
goaccess /var/log/nginx/access.log --log-format=COMBINED

Özellikle lnav, birden fazla log dosyasını aynı anda renk kodlu olarak görüntüleyebildiği için production sorunlarını çözerken çok işe yarıyor.

journald Drop-In Yapılandırması

Bazı durumlarda belirli bir servisin log seviyesini değiştirmek istersiniz. Her seferinde ana yapılandırmayı değiştirmek yerine drop-in dosyaları kullanabilirsiniz:

sudo mkdir -p /etc/systemd/system/nginx.service.d/
sudo nano /etc/systemd/system/nginx.service.d/logging.conf
[Service]
# Nginx için ayrı log namespace tanımla
LogNamespace=webserver
StandardOutput=journal
StandardError=journal
SyslogIdentifier=nginx
sudo systemctl daemon-reload
sudo systemctl restart nginx

Bu yöntemle farklı servislerin loglarını namespace ile ayırabilir ve ayrı ayrı yönetebilirsiniz.

Yapılandırma Doğrulama ve Test

Yaptığınız değişikliklerin doğru çalışıp çalışmadığını test edelim:

# journald durumunu kontrol et
systemctl status systemd-journald

# Yapılandırma dosyasını doğrula
sudo journalctl --header | head -20

# Test mesajı gönder ve logda görün
logger -t testapp "Bu bir test mesajıdır"
journalctl -t testapp -n 5

# rsyslog yapılandırmasını test et
sudo rsyslogd -N1

# Logrotate test
sudo logrotate -d /etc/logrotate.conf

Sonuç

Debian’da sağlam bir log yönetimi altyapısı kurmak, aslında birkaç temel prensip üzerine oturuyor: logları kalıcı olarak sakla, disk kullanımını kontrol altında tut, kritik logları merkezi bir yere topla ve düzenli olarak analiz et.

journald’yi Storage=persistent ile kalıcı moda alarak başlayın, SystemMaxUse ve MaxRetentionSec parametrelerini sunucunuzun kapasitesine göre ayarlayın. rsyslog ile entegrasyonu bozmayın, iki sistem birlikte gayet iyi çalışıyor. logrotate yapılandırmalarınızı gözden geçirin ve her uygulama için mantıklı rotasyon kuralları tanımlayın.

Birden fazla sunucu yönetiyorsanız, merkezi log sunucusu kurmayı ciddiye alın. Bir sorun çıktığında 10 ayrı sunucuya SSH açmak yerine tek yerden sorgulama yapabilmek gerçekten hayat kurtarıyor.

Son olarak şunu söyleyeyim: en iyi log yapılandırması, düzenli olarak okuduğunuz ve üzerine aksiyon aldığınız yapılandırmadır. Loglar bir yerlerde birikip duruyor ama kimse bakmıyorsa, o yapılandırma ne kadar mükemmel olursa olsun size bir faydası olmaz. Haftalık log review alışkanlığı edinin, anormal desenleri yakalayın ve sisteminizi daha iyi tanıyın.

Yorum yapın