İçindekiler
- 1 Bir Gece Yarısı Log Peşinde: Neden Merkezi Loglama?
- 2 Parçaları Sakin Sakin Tanıyalım: Loki, Promtail, Grafana
- 3 Kurulum Stratejisi: Küçük Adımlar, Net Sonuçlar
- 4 Docker Compose ile Hızlı Başlangıç
- 5 Loki’yi Ayarlamak: Saklama, Arşiv, Retention
- 6 Promtail: VPS’in İçindeki Sesleri Toplamak
- 7 Grafana: Logları Gözle Okumaktan Gözlemlenebilirliğe
- 8 Uyarılar: Hata Sesini Zamanında Duymak
- 9 Arşiv ve Saklama: Ne Kadar, Nerede, Nasıl?
- 10 Güvenlik ve Erişim: Sadece İhtiyacı Olan Görsün
- 11 Sahadan Notlar: Etiket Disiplini, Bellek ve Sorgu Hızı
- 12 Uygulamadan Örnekler: Nginx, Node.js, systemd
- 13 Gözlemlenebilirlik Haritasını Genişletmek: Metrikler ve Uptime
- 14 Değişiklikleri Güvenle Yaymak: Konfigürasyon, Sürümleme, Geri Alma
- 15 Sorun Giderme: Bağlantılar, Roll-up’lar, Gürültü
- 16 Kapanış: Derli Toplu Log, Sakin Operasyon
Bir Gece Yarısı Log Peşinde: Neden Merkezi Loglama?
Hiç gece yarısı telefondaki bildirimle irkilip, “Sunucu bir anlığına nefesini tuttu” hissini yaşadın mı? Ben yaşadım. SSH ile sunucuya girdim, bir baktım her şey dağınık; Nginx başka yerde fısıldıyor, uygulama kendi köşesinde mırıldanıyor, systemd ise bambaşka bir defter tutmuş. Kimin ne dediğini tek tek dinlemek, uykulu bir kafayla pek şık bir çözüm olmuyor. İşte o an merkezî loglamanın kıymeti insanın içine işliyor. Tek pencereden her şeyi görmek, akışı geriye sarabilmek, “O sırada ne oldu?” sorusunu bir iki sorguda yanıtlayabilmek müthiş bir konfor.
Bu yazıda tam da bu rahatlığı kuracağız. Bir VPS üzerinde Loki, Promtail ve Grafana üçlüsüyle logları toplayacak, saklayacak, arşivleyecek ve uyarılarla kendimizi emniyete alacağız. Uygulamanın sesi, Nginx’in fısıltısı, sistem servislerinin iç çekişi… Hepsi tek yerde, okunaklı, aranabilir ve görselleştirilebilir olacak. Arada küçük tüyolar, hatalara düşmemek için deneyim kırıntıları ve günlük hayattan küçük hikayeler de var. Hadi başlayalım.
Parçaları Sakin Sakin Tanıyalım: Loki, Promtail, Grafana
Mesela şöyle düşün: Mahalleden bir sürü söylenti geliyor ve sen bunları tek bir masada toplayıp anlamlandırmak istiyorsun. Promtail dışarıdaki tüm sesleri kayıt altına alan muhabir. Loki bu kayıtları saklayan ve dönüp dönüp dinleyebildiğin arşiv. Grafana ise bunları renkli grafiklere, hızlı aramalara ve pratik uyarılara dönüştüren bir anlatıcı. Birlikte çalıştıklarında tam bir “olay defteri” kuruyorlar. Loki tarafını tanımak istersen, Loki’nin resmi sayfası iyi bir durak.
Güzel olan şu: Logları “metrik” gibi etiketlerle saklıyor, ama ham metinleri de kaybetmiyor. Yani istersen “son 1 saatte 500 hatayı aşmış mıyız?” diye sayı bakabiliyor, istersen o hataların metnini olduğu gibi okuyabiliyorsun. Bu, kopuk kopuk tutulan dosya loglarından çok daha rahat bir dünya. Üstelik tek bir VPS’te bile gayet keyifle çalışıyor.
Kurulum Stratejisi: Küçük Adımlar, Net Sonuçlar
Ben genelde böyle şeyleri iki yoldan kuruyorum: Ya sistem servisleriyle (systemd) tek tek ayağa kaldırıyorum ya da hepsini ufak bir Docker Compose dosyasında topluyorum. Tek VPS senaryosunda Compose kullanmak pratik oluyor; sürümleri güncellemek, config dosyalarını bir arada tutmak, arıza durumunda kaldırıp yeniden denemek daha rahat. Ama “Docker istemiyorum” diyorsan, aynı yapılandırmayı systemd ile de kurabilirsin. Önemli olan, ilk gün basit başlayıp, ihtiyaç büyüdükçe katman eklemek.
İlk iş, ufak bir çalışma dizini açmak. İçine üç dosya koyacağız: docker-compose.yml, loki-config.yaml ve promtail-config.yml. Böyle düzenli bir başlangıç, ileride neyin nerede olduğunu hatırlamayı kolaylaştırıyor. Sonra tek komutla ayaklanacaklar. Hazırsan, bir taslak görelim.
Docker Compose ile Hızlı Başlangıç
Aşağıdaki dosyayı çalışma dizinine docker-compose.yml adıyla kaydet. Portlar yerel ortam için açık, veriler kalıcı hacimlerde tutuluyor. Versiyon numaraları örnek; istersen güncel etiketleri kullan.
version: '3.9'
services:
loki:
image: grafana/loki:2.9.0
command: -config.file=/etc/loki/local-config.yaml
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml:ro
- loki-data:/var/lib/loki
ports:
- "3100:3100"
restart: unless-stopped
promtail:
image: grafana/promtail:2.9.0
command: -config.file=/etc/promtail/config.yml
volumes:
- ./promtail-config.yml:/etc/promtail/config.yml:ro
- /var/log:/var/log
- /run/log/journal:/run/log/journal:ro
- /var/lib/promtail:/var/lib/promtail
- /etc/machine-id:/etc/machine-id:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
depends_on:
- loki
restart: unless-stopped
grafana:
image: grafana/grafana:10.4.0
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_INSTALL_PLUGINS=grafana-piechart-panel
restart: unless-stopped
volumes:
loki-data:
grafana-data:
Bu dosya hazırsa, tek bir komutla ayağa kaldırabilirsin. Klasöre gelip “docker compose up -d” demek yeterli. Sonrasında tarayıcıda 3000’e gidince Grafana seni karşılayacak. İlk şifreyle girip (admin/admin gibi bir şeyse değiştir), sonra Loki’yi veri kaynağı olarak ekleyeceğiz. Ama önce Loki’ye doğru bir dükkan düzeni verelim.
Loki’yi Ayarlamak: Saklama, Arşiv, Retention
Loki’yi küçük bir VPS’te çalıştırırken aşırı ayrıntıya boğmadan, tek kopya, dosya tabanlı bir arşivle başlamak rahat. “Sonraki aşamada S3’e taşıyabilir miyim?” diye soruyorsan, evet; aynı mantık S3 deposuyla da çalışıyor. Aşağıdaki örnek config, dosya sistemi üzerinde boltdb-shipper ile saklama yapıyor, derli toplu bir retention sağlıyor.
# loki-config.yaml
server:
http_listen_port: 3100
grpc_listen_port: 9095
common:
instance_addr: 127.0.0.1
path_prefix: /var/lib/loki
storage:
filesystem:
chunks_directory: /var/lib/loki/chunks
rules_directory: /var/lib/loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: boltdb-shipper
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /var/lib/loki/index
cache_location: /var/lib/loki/boltdb-cache
shared_store: filesystem
filesystem:
directory: /var/lib/loki/chunks
chunk_store_config:
max_look_back_period: 168h # 7 gün geriye bak
table_manager:
retention_deletes_enabled: true
retention_period: 168h
compactor:
working_directory: /var/lib/loki/compactor
compaction_interval: 5m
retention_enabled: true
ruler:
rule_path: /var/lib/loki/rules-temp
storage:
type: local
local:
directory: /var/lib/loki/rules
alertmanager_url: http://localhost:9093
enable_api: true
Burada retention basitçe 7 gün. İlk denemede kısa tutmak iyi; diski, sorgu hızını ve alışkanlıklarını gördükçe uzatabilirsin. Dosya sistemi yerine bir “object store” kullanmak istersen, filesystem kısmını S3 ile değiştirmen yeterli. Yedekleme tarafında işin kolaylaşsın istersen, benim sevdiğim yaklaşımı anlattığım S3 uyumlu uzak yedekleme rehberine göz atabilirsin.
Promtail: VPS’in İçindeki Sesleri Toplamak
Promtail, logların kapısındaki güvenilir muhabir. Neleri toplayacağını söyle, o da titizlikle taşısın. Systemd günlükleri, Nginx access/error logları, uygulama klasöründeki dosyalar, hatta Docker container logları… Hepsini toparlamak mümkün. Önemli olan, etiketleri (labels) sade tutmak. Her isteğin ID’sini etiket yapmak kulağa hoş gelir ama belleği yorar. Ben genelde job, environment, service name, host gibi sabit etiketlerle başlıyorum.
# promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /var/lib/promtail/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: journal
journal:
max_age: 12h
labels:
job: systemd
host: ${HOSTNAME}
relabel_configs:
- source_labels: ['__journal__systemd_unit']
target_label: unit
- job_name: nginx
static_configs:
- targets: [localhost]
labels:
job: nginx
env: prod
__path__: /var/log/nginx/*.log
- job_name: app
static_configs:
- targets: [localhost]
labels:
job: app
env: prod
service: webshop
__path__: /var/www/app/storage/logs/*.log
pipeline_stages:
- regex:
expression: '^[(?P<level>w+)]s+(?P<msg>.*)$'
- labels:
level:
- output:
source: msg
Burada systemd günlüklerini ünite adına göre etiketliyoruz, Nginx loglarını tek etikette birleştiriyoruz, uygulama loglarını da seviyeyi (INFO, ERROR gibi) ayıklayarak zenginleştiriyoruz. Böyle olunca Grafana’dan “son 15 dakikadaki ERROR sayısı 50’yi geçti mi?” gibi alarm kurmak kolay. Promtail’in boru hattı aşamalarını merak edersen, Promtail aşamaları belgeleri hoş bir anlatımla özetliyor.
Grafana: Logları Gözle Okumaktan Gözlemlenebilirliğe
Grafana açıldığında, önce “Data Sources” menüsünden Loki’yi ekle. URL olarak http://loki:3100 yazman yeterli, Compose ağı içinde isimle erişilecek. Sonra “Explore” bölümüne girip ufak bir deneme yapalım. Mesela son 5 dakikada Nginx’te 500 hatası var mı diye soralım. LogQL dili tam bu iş için var; sade, niyetini belli eden bir dille konuşuyor.
{job="nginx"} |= " 500 "
Bu sorgu, Nginx loglarında 500 geçen satırları getirir. Saymak istersen bir adım daha atarsın, “rate” gibi metrik benzeri operatörleri devreye sokarsın. Örnek olsun:
sum by (job) (rate({job="nginx"} |= " 500 " [5m]))
Biraz daha tatlı bir örnek: Uygulama loglarında ERROR’ları seviyeye göre sayalım, panellerde ısınma varsa kırmızıya dönsün. Bunun için önce Explore’da oynar, sonra panelleri kaydedersin. LogQL’i tanımak istersen, LogQL ile sorgulama sayfası kısa örneklerle iyi bir eşlikçi.
Uyarılar: Hata Sesini Zamanında Duymak
Uyarı dediğin, bardak devrilmeden önce “Masada bir sallantı var” diyen iç ses. Grafana’nın yeni nesil alarm sistemiyle log tabanlı kurallar oluşturmak epey kolay. Örneğin, “Son 10 dakikada ERROR sayısı 100’ü aşarsa Slack’e haber ver” gibi bir kural yazabiliriz. Explore’da çalışan sorgunu bir panele koy, panelden Alert sekmesine geç, eşiği belirle, bir iletişim noktası (Slack, e‑posta) seç ve kaydet.
Bazen metin aramak yetmez; belirli bir servis adının hata hızını da izlemek istersin. O zaman etiketleri kullanarak seçici olursun. Diyelim ki “webshop” servisi için ERROR akışını sayalım:
sum by (service) (rate({job="app", service="webshop", level="ERROR"}[10m]))
Bu değer 0.2’yi aşarsa alarm ver, hızlıca bak. Paneldeki eşiği düşük tutup sonra kademeli yükseltmek pratik oluyor. Bir de sevdiğim küçük alışkanlık: Uyarı metnine, bakılacak sorgunun ve ilgili dashboard’un bağlantısını eklemek. Gece uykusu bölündüğünde, “Ben nereye bakıyordum?” derdini azaltıyor.
Arşiv ve Saklama: Ne Kadar, Nerede, Nasıl?
Logun ömrü biraz da ihtiyacınla alakalı. Geliştirme aşamasında 7 gün yetebilir, üretimde belki 30 güne uzatırsın. Loki’nin retention ayarı burada anahtar. Disk daralıyorsa önce gereksiz etiketleri azalt, sonra saklama süresini toparla. S3 gibi bir object store’a geçmek istersen de configte “object_store” kısmını S3’e çevirip erişim bilgilerini eklemen kafi. Günün birinde “Ben bu arşivi dışarı da alayım” dersen, log klasörlerinin yedeğini planlı bir boru hattına koymak iyi fikir. Ben bunun için zamanında anlattığım S3 uyumlu uzak yedekleme pratiğini seviyorum; şifreleme, sürümleme ve saklama politikası bir arada yürüyor.
Arşiv demişken, küçük ama etkili bir alışkanlık: Rotasyonlarını ve retention’ı çakıştırma. Uygulama kendi içinde çok hızlı rotasyon yapıyorsa Promtail’in pozisyon dosyası şaşırabilir. Rotasyon aralıklarını biraz rahat bırakmak, Promtail’in acele etmeden kuyruğu taşımasına fırsat verir.
Güvenlik ve Erişim: Sadece İhtiyacı Olan Görsün
Grafana’yı 3000’den, Loki’yi 3100’den açtık, güzel. Ama bu portları herkese açık bırakmak istemeyebilirsin. Ben çoğu zaman Nginx’in arkasına alıp basit bir kimlik doğrulama ekliyorum. İstersen mTLS, istersen IP kısıtlaması, istersen temel kimlik doğrulama… Küçük bir örnek, Grafana için:
server {
listen 443 ssl;
server_name logs.example.com;
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
auth_basic "Logs";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:3000;
}
}
Bu örnekle temel bir koruma sağlarsın. Eğer websiteni zaten Nginx ve modern şifreleme ile güçlendiriyorsan, oradaki prensipleri burada da uygula. Geliştirici ortamlarında ise şifreyi bir ekip kasasında saklamak, erişimi gerektiğinde açıp kapatmak işleri düzenli tutuyor. Uygulama loglarına gereğinden fazla detay basmamak da güvenlikte ilk adım; kimlik bilgileri veya kişisel veriler loga düşmesin.
Sahadan Notlar: Etiket Disiplini, Bellek ve Sorgu Hızı
Uzun vadede en çok fayda sağlayan alışkanlık, etiket disiplini. Her isteğe özel, sürekli değişen değerleri etiket yapmamak gerekiyor. Request ID, kullanıcı ID, token gibi değerler metin içinde kalsın; filtrelerken “|= “.user_id=123″” gibi metin aramasına güven. Etiketlerde; job, service, env, host, level gibi sakin değerleri tercih et. Böylece Loki’nin kartopu gibi büyümesini engellersin, sorgular da seri akar.
İkincisi, sorgu pencerelerini akıllı seçmek. Çok geniş bir zaman aralığında “her şeyi” istemek zorlar. Önce yakın bir aralığı tarayıp ipucunu bul, sonra geriye genişle. Bir de unutma: Çok gürültülü loglar varsa, uygulama tarafında seviyeyi ayarlamak ve gereksiz satırları azaltmak çift taraflı bir kazanım.
Uygulamadan Örnekler: Nginx, Node.js, systemd
Nginx’te access ve error dosyaları klasik. Access loglarında “request_time” ve “upstream_status” gibi alanlar varsa, metin aramalarıyla performans kokusu alan sorgular yazabilirsin. Uygulamada Node.js kullanıyorsan, anlamlı ve tek satırlık log formatı işleri çok kolaylaştırır. Nasıl canlıya alırken panik yapmadan derli toplu bir ortam kuracağını anlattığım Node.js’i canlıya alırken PM2/systemd ve Nginx notları, log düzeni için de ilham verebilir.
Systemd tarafında ise servis isimlerine göre ayırmak, özellikle “neden yeniden başladı?” soru işaretini çözer. Journal’dan ünite adına etiketleme yapınca, hangi servis ne zaman inlemiş görürsün. Promtail burada hayati; positions dosyasını korur, koptuğu yerden devam eder, panik yok.
Gözlemlenebilirlik Haritasını Genişletmek: Metrikler ve Uptime
Loglar tek başına yetmez, doğru. Ama iyi bir başlangıç. Üzerine metrikleri ve uptime kontrollerini koyduğunda tablo tamamlanıyor. Ben genelde Loki ile logları oturttuktan sonra, aynı Grafana içinde Prometheus ve küçük bir uptime izleyici ekliyorum. Bu konuda “ilk taşları nasıl dizerim?” dersen, VPS izleme ve alarm kurulumuna dair rehber hoş bir yoldaş olur. Loglardaki ERROR artarken CPU, bellek ve yanıt süresi ne yapıyor, birlikte bakınca hikaye tamamlanıyor.
Değişiklikleri Güvenle Yaymak: Konfigürasyon, Sürümleme, Geri Alma
Günün sonuna doğru ufak bir Promtail kuralı ekledin diyelim. Canlıda denemek istiyorsun ama “ya bir şeyi bozarsam” çekincesi hep var. O noktada küçük bir CI/CD hattı kurtarıcı. Konfigürasyon dosyalarını versiyon kontrolüne al, bir “staging” VPS’te dene, sonra üretime güvenle at. Benzer bir yaklaşımı adım adım anlattığım VPS’e sıfır kesinti CI/CD yazısı burada harika çalışıyor. Bir de küçük öneri: Loki ve Promtail’in sürümlerini birlikte güncelle, büyük atlamalarda önce test et.
Sorun Giderme: Bağlantılar, Roll-up’lar, Gürültü
Olur ya, Promtail gönderiyor ama Loki’de görünmüyor. İlk kontrol adresi Promtail arayüzü; 9080 portundan “targets” sayfasına bak, durum “ready” mi? Sonra firewall veya reverse proxy araya giriyor mu diye bakarsın. Görünüyor ama yavaşsa, sorgu penceresini daralt, gereksiz etiket var mı diye incele. Loglar çok gürültülü ise, uygulamada seviyeyi INFO yerine WARN’a çekmek bazen en kestirme çözüm. Bir de kompaktörün çalıştığından emin ol; arşivi toparlarken o görevli.
Grafana’da panel boş dönüyorsa, zaman aralığı ayarı ve sorgu ifadesine yeniden göz at. LogQL basit ama küçük tırnak ve eşittir oyunları önemli. Emin olamadığında Explore ekranında adım adım ilerlemek en temiz yol.
Kapanış: Derli Toplu Log, Sakin Operasyon
Merkezî loglama, ilk bakışta bir “nice to have” gibi duruyor. Oysa gece yarısı bir hata patlayınca, sabah trafiği artınca ya da ekip büyüyüp el değişmeye başlayınca, değerini çok net görüyorsun. Loki + Promtail + Grafana üçlüsü, tek VPS’te bile hafif adımlarla kurulup günlük hayata uyumlanan bir sistem. Üstelik büyümek istediğinde, aynı alışkanlıkları daha geniş bir oyuncağa taşıyorsun.
Başlangıç için küçük önerilerimi toparlayayım. Etiketleri sade tut; job, env, service, host sana yeter. Retention’ı kademeli artır, diski ve sorgu süresini izleyerek karar ver. Uyarıları erken kur, eşikleri zamanla finetune et. Değişiklikleri sürüm kontrolünde sakla, küçük adımlarla yayımla, bir şey olursa geri alması kolay olsun. Ve unutmadan, uygulamayı canlıya alırken log formatını basit ve tek satırlı tutmak, ileride sana dakikalar kazandırır; nitekim bu konuda paylaştığım canlıya alma notları log düzenini sadeleştirmeye de göz kırpıyor.
Umarım bu yolculuk sana iyi gelmiştir. Bir sonraki küçük krizde elinin altındaki bu düzenle nefes alacağını bilmek güzel. Sorun, deneyim paylaş, kendi mutfağında işe yarayan minik teknikleri anlat; hep birlikte daha sakin bir operasyon kültürü kuruyoruz. Görüşmek üzere.
