Tek Bir Server'da Log Management
Tek bir server'da bir şey ters gittiğinde, log'lar genelde hepsi orada, /var/log/nginx/, /var/log/postgresql/, systemd journal'ı, ve application'ın kendisinin canının istediği her yere yazdığı şeyler arasında dağılmış halde. İlgili satırı bulmak, beş yerden hangisine bakacağınızı bilmek demek, ve app plain text loglarsa structured bir şey yerine, "son bir saatte bu IP'den gelen tüm request'ler, nginx ve app'in hepsinde" demek, farklı formatlarda birkaç farklı grep komutu demek. Bunların hiçbiri tam olarak broken değil, sadece olması gerekenden daha yavaş, özellikle baskı altında.
Full ELK stack'i (Elasticsearch, Logstash, Kibana) bunu çözüyor, ama tek bir server için gerçekten heavy, Elasticsearch tek başına sadece çalışmak için memory'nin anlamlı bir kısmını istiyor. Tek bir server için kullanışlı orta yol bundan daha küçük.
Structured log'lar her şeyin gerisini kolaylaştırıyor
En yüksek leverage'lı tek değişiklik, application log'larını free-text yerine structured bir formata (JSON) getirmek. Karşılaştırın:
2026-10-28 14:32:01 ERROR Failed to process order 4821 for user 1029: timeout
{"time":"2026-10-28T14:32:01Z","level":"error","msg":"failed to process order","order_id":4821,"user_id":1029,"reason":"timeout"}
İkincisi, ona göz atan bir insan için daha okunaklı değil, ama queryable: "user 1029 için her error" ya da "son bir saatteki her timeout", aynı sayıları içeren ilgisiz text'le de eşleşebilecek bir regex yerine bir field üzerinde bir filter oluyor. Çoğu logging library, bir rewrite değil bir configuration değişikliğiyle structured output'u destekliyor.
journald, insanların kullandığından çok daha fazlasını zaten yapıyor
Bir systemd service olarak çalışan her şey için (ki modern bir Linux server'da bu şeylerin çoğu), journalctl stdout/stderr'i timestamp'lerle zaten merge ediyor, ve birçok insanın başvurmadığı filtering'i destekliyor:
# Everything from the app, last hour
journalctl -u myapp --since "1 hour ago"
# Follow logs from multiple units at once
journalctl -u myapp -u nginx -f
# Only errors, across everything
journalctl -p err --since today
Sonuncusu, tüm sistem boyunca priority'ye göre filtreleme, dağınık bir log dosyası koleksiyonunun external tooling olmadan hiç yapamayacağı bir şey. Application log'ları (ayrı bir dosyaya değil) stdout'a JSON olarak gidiyorsa, journalctl'ın o unit için output'u zaten structured, ve spesifik field'larda filtrelemek için jq'ya pipe'lanabilir.
Dashboard istiyorsanız: lightweight bir stack
Elasticsearch'in footprint'i olmadan gerçek bir log viewer'a daha yakın bir şey için, Grafana Loki plus Promtail genelde önerilen lightweight eşleşme, Promtail log dosyalarını tail'liyor (ya da journal'ı okuyor) ve Loki'ye gönderiyor, Grafana da bunu, zaten kuruluysa Prometheus'tan gelen metric dashboard'larının yanında query edip görüntüleyebiliyor. Loki'nin resource footprint'i, aynı VPS'te bir application'ın yanında rahatça çalışacak kadar küçük, ki Elasticsearch'in olamayacağı yerde burada oturmasının ana sebebi de bu.
# promtail-config.yml (minimal)
scrape_configs:
- job_name: journal
journal:
max_age: 12h
relabel_configs:
- source_labels: ['__journal__systemd_unit']
target_label: 'unit'
Rotation'ı unutmayın
Hiç kimsenin bakmadığı log'larla disk dolarsa, bunların hiçbiri önemli olmuyor. logrotate, yaygın service'ler için genelde zaten configure edilmiş, ama custom bir path'e yazılan application log'larının kendi entry'sine ihtiyacı var:
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 14
compress
missingok
notifempty
}
Ve journal'ın kendisi için, size'ını capping etmek, journal'ın sessizce sınırsız büyümesini engelliyor:
# /etc/systemd/journald.conf
SystemMaxUse=1G
Asıl hedef
Bunların hiçbirinin elaborate olması gerekmiyor. Hedef, ilgili satırın göze çarpmasını umarak plain text'te scroll etmek yerine, bir şey bozulduğunda "ne oldu, ve ne zaman" sorusunun, önemli olana göre filtrelemeye (bir user ID, bir error type, bir time range) yetecek structure'la, bakılacak tek, cevaplanabilir bir yerinin olması. Structured logging plus journalctl'ın filtering'i bunun çoğunu ücretsiz kapsıyor. Loki ve Grafana, "ücretsiz" yetmemeye başladığında üstüne browsable bir interface ekliyor.