Teknoloji

VPS’te Loki: Etiketler, Saklama Süresi ve Alarmlar

VPS’te Merkezi Log Yönetimi Neden Gerekir?

Bir API aralıklı olarak hata verirken Nginx, uygulama ve sistem kayıtlarının farklı yerlerde tutulduğunu düşünün. Her sunucuya ayrı bağlanmak, aynı olayın zamanını ve bağlamını karşılaştırmayı zorlaştırır. Merkezi loglama, gerekli kayıtları ortak bir sorgu noktasında toplar; sorunun kaynağını bulmak ise doğru veri toplama, etiketleme ve zaman bilgisini gerektirir.

Bu rehber, VPS log yönetiminde Loki ile etiket tasarımı, saklama ve alarm kurallarına odaklanır. Promtail, 2 Mart 2026’da kullanım ömrünü tamamladı ve artık güncelleme almıyor; yeni kurulumlarda Grafana Alloy gibi desteklenen bir toplayıcı kullanın. Aşağıdaki Promtail örneği eski yapılandırmaları incelemek ve geçişi planlamak için korunmuştur. Loki ve alarm örneklerinin önkoşulları ayrıca belirtilmiştir; anlatım işletim sistemi paketlerinin, Grafana’nın veya Alertmanager’ın kurulumunu kapsamaz.

Toplayıcı, Loki ve Grafana’nın Rolleri

Toplayıcı, VPS üzerindeki dosya, journal veya uygun konteyner kaynağından logları alır; işler, etiketler ve Loki’ye gönderir. Mevcut eski kurulumlarda bu rolü Promtail üstlenebilir; desteklenen Alloy’da kaynak, işleme ve gönderme bileşenleri kullanılır. Loki logları saklar ve LogQL ile sorgular; Grafana ise veri kaynağına bağlanarak arama, pano ve alarm yönetimi sağlar. Grafana’nın çalışması tek başına log toplandığı anlamına gelmez.

Loki, log metninin tamamı yerine akış etiketlerini indeksler. Her benzersiz etiket kombinasyonu bir akış oluşturur. Bu yaklaşımın disk, CPU ve sorgu maliyeti; hacme, sorguya ve akış sayısına bağlıdır. app, env, host ve job gibi kararlı etiketlerle başlayın. Seviye ve HTTP durum kodu gibi sınırlı değerli etiketler bile akışları böler; yalnızca somut sorgu veya saklama ihtiyacı varsa ekleyin.

Bir veya iki servisin temsilî loglarıyla başlayın. Hangi soruların etiket seçicisiyle, hangilerinin satır içeriğini ayrıştırarak cevaplanacağını belirleyin. User-Agent, istek kimliği, kullanıcı kimliği ve tam URL gibi çok farklı değerler alan bilgileri indeks etiketi yapmayın. Bunları gerekli oldukları ölçüde log satırında veya desteklenen yapılandırılmış meta veride tutun.

Yerel Servis Varsayımları ve Eski Promtail Örneği

Loki, desteklenen toplayıcı ve Grafana yerel servislerle veya uygun konteyner dağıtımıyla çalıştırılabilir. Buradaki adresler aynı sunucuda çalışan yerel süreçleri varsayar; ayrı Compose konteynerlerinde 127.0.0.1 diğer servisi göstermez. Kalıcı veri dizinleri, dosya okuma izinleri ve servis hesaplarını önceden hazırlayın. Promtail’in positions dosyası yazılabilir ve kalıcı olmalı; journal kaynağı için ilgili derleme desteği ve journal okuma izni bulunmalıdır. Örnekteki host değerini gerçek sunucunun kararlı kimliğiyle değiştirin.

Aşağıdaki eski Promtail YAML örneği, Nginx combined erişim biçimini ve her olayı 2026-11-04T12:00:00Z level=error msg=... gibi RFC3339 zamanıyla başlatan uygulama loglarını varsayar. Nginx hata kayıtları bu erişim regex’ine uymaz ve ham satır olarak kalır. Örnek, ortam değişkeni genişletmesi kapalıyken kullanılan tek tırnaklı regex kaçışlarına göredir. Yeni bir Promtail servisi kurmak yerine resmi Promtail’den Alloy’a geçiş rehberiyle mevcut yapılandırmanızı dönüştürün; aşağıdaki filtreleri ancak tutulması gereken veriyi belirledikten sonra uyarlayın.

# Legacy Promtail YAML: inspection/migration reference, not a new installation.
# Native processes on the same host; no --config.expand-env=true.
server:
  http_listen_address: 127.0.0.1
  http_listen_port: 9080
  grpc_listen_address: 127.0.0.1
  grpc_listen_port: 0

positions:
  filename: /var/lib/promtail/positions.yaml

clients:
  - url: http://127.0.0.1:3100/loki/api/v1/push

scrape_configs:
  - job_name: nginx
    static_configs:
      - targets: ["localhost"]
        labels:
          job: nginx
          app: web
          env: prod
          host: vps-01
          __path__: /var/log/nginx/*.log
    pipeline_stages:
      - regex:
          expression: '^(?P<remote_addr>\S+) \S+ \S+ \[(?P<time_local>[^\]]+)\] "(?P<request>[^"]+)" (?P<status>\d{3}) (?P<body_bytes_sent>\d+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)"$'
      - timestamp:
          source: time_local
          format: '02/Jan/2006:15:04:05 -0700'
          action_on_failure: skip
      - labels:
          status:
      - match:
          selector: '{job="nginx", status=~"2.."}'
          stages:
            - drop:
                source: request
                expression: '^(GET|HEAD) /healthcheck(\?[^ ]*)? HTTP/[0-9.]+$'
                drop_counter_reason: successful_healthcheck

  - job_name: app
    static_configs:
      - targets: ["localhost"]
        labels:
          job: app
          app: api
          env: prod
          host: vps-01
          __path__: /var/log/myapp/*.log
    pipeline_stages:
      - multiline:
          firstline: '^[0-9]{4}-[0-9]{2}-[0-9]{2}T'
          max_wait_time: 3s
          max_lines: 128
      - regex:
          expression: '^(?P<time>\S+) level=(?P<level>debug|info|warn|error|fatal)(?:\s|$)'
      - timestamp:
          source: time
          format: RFC3339Nano
          action_on_failure: skip
      - labels:
          level:
      - match:
          selector: '{job="app", level="debug"}'
          action: drop

  - job_name: system
    journal:
      json: false
      max_age: 24h
      labels:
        job: systemd
        app: system
        env: prod
        host: vps-01
    relabel_configs:
      - source_labels: ['__journal__systemd_unit']
        target_label: unit

İstek alanına uygulanan filtre yalnızca başarılı 2xx durum kodlu GET/HEAD /healthcheck çağrılarını düşürür; başarısız kontroller ve başka yollar korunur. User-Agent ayrıştırılır ama indeks etiketi yapılmaz. Uygulamada yalnızca belirtilen küçük harfli seviyeler çıkarılır ve debug olayları düşürülür. Multiline, tarih ile başlayan yeni olaya kadar satırları birleştirir; üç saniye bekleme ve 128 satır sınırı vardır. Nginx ve uygulama zamanları uygun biçimde ayrıştırılır; başarısız zaman ayrıştırmasında skip toplama zamanını korur. Biçime uymayan kayıtların sınıflandırılmadığını ve alarm hesabının dışında kalabileceğini test edin.

Konteyner logları için kaynağın Docker, dosya veya journal olmasına göre desteklenen toplayıcı bileşenini seçin; aynı satırı birden fazla yoldan göndermeyin. Konteyner stdout kayıtları ayrıca bir kapsayıcı log biçimi kullanabilir; düz uygulama dosyası regex’ini doğrudan uygulamak doğru olmayabilir. İlgili servis ve log düzeni için Docker ile WordPress, Nginx, MariaDB ve Redis çalıştırma rehberini inceleyebilirsiniz.

Loki Tarafında Saklama (Retention): Ne Kadar, Nerede ve Neden?

Saklama süresini olay inceleme ihtiyacı, yasal veya denetim yükümlülükleri ve kapasiteyle belirleyin. Tanılama kayıtları için 7–14 gün, uygulama hataları için 30 gün veya erişim kayıtları için 7 gün yalnızca örnek politikalardır; her ortama uygun süreler değildir. Farklı süreleri bir akışın etiketleriyle seçebilirsiniz. Bu nedenle örnekteki level etiketi gibi bir ayrımın sağlayacağı yararı, oluşturduğu ek akış maliyetiyle birlikte değerlendirin.

Aşağıdaki yapılandırma, Loki 3.7 için yeni ve tek sunuculu bir yerel kurulum örneğidir; mevcut kurulumun geçmiş schema_config kayıtlarını bununla değiştirmeyin. TSDB v13 ve 24 saatlik indeks dönemi, yedi günlük saklama, kalıcı compactor dizini ve delete-request deposu tanımlanır. Kaldırılmış shared_store ayarı kullanılmaz. Yalnızca loopback üzerinde tek kiracılı çalışır; auth_enabled: false kullanıcı kimlik doğrulaması sağlamaz. /var/lib/loki altındaki veri, WAL, indeks, compactor ve geçici kural dizinlerini Loki hesabının erişebileceği şekilde hazırlayın. Bu tek kopyalı dosya sistemi örneği yüksek erişilebilirlik sağlamaz.

# Loki 3.7 configuration example for a fresh, single-host native deployment.
# Preserve existing schema history when adapting an existing installation.
auth_enabled: false
target: all

server:
  http_listen_address: 127.0.0.1
  http_listen_port: 3100
  grpc_listen_address: 127.0.0.1
  grpc_listen_port: 9096

common:
  path_prefix: /var/lib/loki
  storage:
    filesystem:
      chunks_directory: /var/lib/loki/chunks
      rules_directory: /var/lib/loki/rules
  replication_factor: 1
  ring:
    instance_addr: 127.0.0.1
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: "2024-01-01"
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

storage_config:
  tsdb_shipper:
    active_index_directory: /var/lib/loki/index
    cache_location: /var/lib/loki/index-cache

ingester:
  wal:
    enabled: true
    dir: /var/lib/loki/wal

limits_config:
  reject_old_samples: true
  reject_old_samples_max_age: 168h
  retention_period: 168h

compactor:
  working_directory: /var/lib/loki/compactor
  retention_enabled: true
  delete_request_store: filesystem

ruler:
  alertmanager_url: http://127.0.0.1:9093
  rule_path: /var/lib/loki/rules-temp
  storage:
    type: local
    local:
      directory: /var/lib/loki/rules
  ring:
    kvstore:
      store: inmemory
  enable_api: false

retention_period: 168h tek başına silmeyi etkinleştirmez; compactor’ın retention işlevi ve delete_request_store da gerekir. Silme, compactor ve gecikmeli silme işlemleriyle yürür; saklama süresi dolunca disk anında boşalmaz. reject_old_samples_max_age ise gelen kayıtların kabul edilebilecek yaşını sınırlar, depodaki kayıtları silmez. Akış bazlı politikalar ve kullanılan sürümün önkoşulları için Loki’nin resmi dokümantasyonunu izleyin. Dolu diski kurtarmak için yalnızca saklama süresini değiştirmeye güvenmeyin.

Uzun arşiv ihtiyacı varsa, aktif olarak sorgulanan Loki verisiyle ayrı arşiv kopyalarının erişim beklentisini ayırın. Loki’nin kullandığı chunk veya indeksleri bağımsız bir lifecycle kuralıyla soğuk sınıfa taşımak ya da silmek sorguları bozabilir. Ayrı arşiv için veri, indeks, yapılandırma ve geri yükleme yöntemini birlikte planlayın. Restic ve Borg ile uzak yedekleme rehberi kopyalama ve geri yükleme tasarımına yardımcı olabilir; aktif Loki deposunun tutarlı yedeğini oluşturmanın yerine geçmez.

Filtreleme, Multiline ve Veri Koruma

Kaynakta veya toplayıcıda düşürülen loglar Loki’ye ulaşmaz. Debug ve başarılı sağlık kontrolü kayıtlarını kaldırmadan önce hata oranı hesabında, trafik analizinde, olay incelemesinde veya denetimde gerekip gerekmediğini belirleyin. Başarılı istekleri seçerek düşürmek, kalan loglardan hesaplanan 5xx yüzdesinin paydasını değiştirir. Tasarruf miktarını ölçün; filtrelemenin trafiği ya da log hacmini belirli bir oranda azaltacağı varsayımıyla kapasite planlamayın.

Kararlı app, env, host ve job etiketleri sorguları sınırlamaya yardımcı olur. Seviye, durum kodu veya journal unit gibi dinamik değerlerin sayısını da izleyin; çok sayıda geçici birim akış sayısını artırabilir. Toplayıcının regex/JSON aşamasında çıkardığı alanlar sonraki işlem aşamalarında kullanılan geçici verilerdir. Kalıcı etiket, desteklenen yapılandırılmış meta veri veya log satırı olarak açıkça taşınmadıkça Loki’de bağımsız alan olarak saklanmış sayılmazlar; satırdaki alanlar LogQL ile sorgu sırasında ayrıştırılabilir.

Java, Python veya Node.js stack trace’lerinin doğru birleştirilmesi gerçek başlangıç biçimine bağlıdır. firstline desenini her uygulamaya göre sınayın; iki ayrı hatanın tek olaya birleşmesi de bir hatanın parçalanması kadar yanıltıcıdır. Temsilî çok satırlı kayıtlar, kesik başlangıçlar ve bekleme/satır sınırlarıyla test yapın. Alloy’a geçerken biçim, zaman damgası, etiketler ve düşürülen olayların sonucu aynı kalıyor mu kontrol edin.

Parola, token ve ödeme verisinin loglara hiç yazılmaması ilk tercihtir. Gerekli kişisel veri alanlarını azaltın, erişimi ve saklamayı sınırlandırın. Maskeleme ek bir önlem olabilir; regex ile her hassas verinin yakalanacağını varsaymayın. Toplayıcıda yapılan replace işlemi, kaynak dosyadaki veya daha önce alınmış yedekteki veriyi temizlemez. Normal, kaçışlı ve çok satırlı örneklerle maskelemenin sınırlarını doğrulayın.

LogQL, Grafana ve Alarm Değerlendirmesi

Çalışan Grafana’da Loki’yi veri kaynağı olarak tanımlayın ve önce zaman aralığıyla etiketlerin doğru olduğunu kontrol edin. {app="api", env="prod"} uygulama akışlarını seçer. Yukarıdaki küçük harfli level etiketi çıkarılıyorsa hata sorgusu {app="api", env="prod", level="error"} olur. count_over_time({app="api", env="prod", level="error"}[5m]) her akış için beş dakikadaki olay sayısını verir; toplam için ayrıca toplama işlemi gerekir. Metin filtresi kullanılırsa büyük/küçük harf ve log biçimi ayrıca önemlidir.

Grafana tarafından yönetilen kurallar Loki’yi sorgular ve Grafana’nın bildirim yapılandırmasını kullanır. Loki ruler ise kuralları değerlendirip etkin alarmları Alertmanager’a yollar. Aşağıdaki örnek ikinci yoldur: üstteki ayar, 127.0.0.1:9093 üzerinde ayrı bir Alertmanager’ın ve bildirim alıcılarının hazır olduğunu varsayar. Tek kiracılı varsayılan tenant kimliği fake olduğundan kural dosyası /var/lib/loki/rules/fake/app-alerts.yml altında bulunur. Yerel kural deposu API üzerinden kural yazmayı desteklemez; rule_path ise kaynak dosyadan ayrı, yazılabilir geçici çalışma alanıdır.

# /var/lib/loki/rules/fake/app-alerts.yml
groups:
  - name: loki-app-alerts
    rules:
      - alert: UygulamaHataSatiriHiziYuksek
        expr: sum by (app) (rate({app="api", env="prod", level="error"}[5m])) > 1
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "API hata loglarının saniyelik hızı yükseldi"
          description: "5 dakikalık penceredeki ortalama hata logu hızı, 2 dakika boyunca saniyede 1 olayın üzerinde kaldı."

Bu kural, beş dakikalık penceredeki ortalama hata logu sayısını saniye başına hesaplar; isteklerin hata yüzdesi değildir. Uygulama bazındaki hız 1’in üzerinde iki dakika boyunca kaldığında alarm etkinleşir. Bir istek birden fazla log üretebileceği için bunu doğrudan başarısız istek sayısı olarak yorumlamayın. Eşik ve for süresi iş yüküne göre belirlenmelidir; önce gerçek olay örnekleriyle doğrulayın. Ayrıntılar için Loki dokümantasyonu ve Grafana Alerting belgelerine bakın.

Uyarı ve kritik bildirimlerini farklı etki düzeylerine göre ayırın; Nginx 5xx olaylarını uygulama hata loglarından bağımsız izleyin. Dağıtım sırasında bildirimleri susturmak gerekiyorsa kapsamı ve bitişi belli bir pencere kullanın; veri toplamayı ve önemli olay incelemesini durdurmayın. PM2, systemd ve Nginx ile Node.js dağıtım rehberi, servis değişikliklerinin log akışıyla ilişkilendirilmesine yardımcı olur.

Kapasite, Yedek ve Dağıtım Bilgisi

du ve df ile kullanımın hangi dizin ve dosya sisteminde büyüdüğünü kontrol edin; inode kapasitesini de izleyin. Grafana’da disk paneli için Node Exporter gibi bir kaynağın metriklerinin bir metrik veri kaynağında toplanması gerekir. Günlük saklanan hacim × gün sayısı yalnızca başlangıç hesabıdır; sıkıştırma, indeks, WAL, cache, compaction, geçici alan ve büyümeyi ayrıca ölçün. Yüzde 20–30 boş alan da evrensel garanti değil, yükle doğrulanacak bir planlama payıdır.

Yedek ihtiyacını kayıtların tanılama verisi mi yoksa zorunlu denetim izi mi olduğuna göre belirleyin. Dosya sistemi kullanan Loki’de yalnızca canlı bir dizini kopyalamak tutarlı kurtarma seti sağlamayabilir; kullanılan tüm veri ve indeks yolları, WAL, compactor durumu, kurallar ve yapılandırma birlikte değerlendirilmelidir. Tutarlı kopyayı ayrı konumda koruyun ve geri yükleme testi yapın. Saklama süresi silme politikasını yönetir; donanım kaybına karşı yedek değildir.

Dağıtım sürümü veya git SHA’yı her ilgili uygulama logunun alanı olarak taşımak hataları sürümle ilişkilendirmeyi kolaylaştırır. Her sürümü yeni bir indeks etiketi yapmak akışları çoğaltabilir; yalnızca başlangıçta bir kez sürüm yazmak da sonraki her olaya bu bağlamı otomatik eklemez. Rsync ve sembolik sürümlerle CI/CD rehberi dosya dağıtımını açıklar; Loki, Alloy ve Grafana ayarlarının yüklenmesi için her servisin doğrulama, yeniden yükleme veya yeniden başlatma yöntemini ayrıca izleyin.

Loglar, metrikler ve erişilebilirlik kontrolleri farklı soruları cevaplar. Kuyruk derinliği ve çalışan süreç sağlığı gibi panolar, bu değerleri üreten uygulama/broker telemetrisi veya ayrı bir metrik kaynağı gerektirir; sıradan erişim loglarından kendiliğinden oluşmaz. Daha geniş tasarım için merkezi loglama ve gözlemlenebilirlik rehberini kullanabilirsiniz; Promtail geçen bölümleri yaşam döngüsü bilgisiyle birlikte değerlendirin.

Toplayıcı Geçişi ve Alarm Sağlığını Doğrulama

Alarm gürültüsünde önce olayın gerçek olup olmadığını, sorgu kapsamını, parse hatalarını ve toplama gecikmesini inceleyin; for süresini yükseltmek gerçek sorunu gizleyebilir. 4xx yanıtlar her zaman kullanıcının hatası değildir; kimlik doğrulama, WAF veya uygulama yapılandırması da bunları üretebilir. 5xx yanıtları ise sunucu ya da upstream sorununa işaret edebilir. Log gelmemesi alarmı yalnızca beklenen üretim sıklığı bilinen kaynakta anlamlıdır; sessiz uygulamalar için heartbeat veya ayrı sağlık metriği gerekir. Loki ve alarm değerlendiricisini de bağımsız izleyin.

Güncel ayarlar için Loki dokümantasyonunu, eski bileşenin durumu için Promtail başvuru adresini kullanın. Alloy’un convert aracıyla mevcut Promtail yapılandırmasını ayrı bir çıktı dosyasına dönüştürün; raporu inceleyin ve validate ile sözdizimini kontrol edin. Bu işlem dosya izinlerini, okuma konumlarını veya uçtan uca teslimatı kanıtlamaz. Geçişte atlanan/çift gelen kayıtları, zamanları, etiketleri ve filtreleri sınayın. Alloy’un kendi metrikleri Promtail’den farklı olduğundan ilgili sağlık panolarını ve alarmları da uyarlayın.

Sürdürülebilir Log Yönetimi Planı

Önce gerekli kayıtları ve saklama gerekçelerini belirleyin; ardından kararlı etiketler, test edilmiş ayrıştırma, ölçülen kapasite ve anlamı açık alarmlar oluşturun. Grafana panoları veri saklamaz: loglar silindikten sonra uzun dönem eğilimleri görmek için recording rule sonuçlarını ayrı bir metrik deposuna yazmak veya özetleri ayrıca saklamak gerekir. Toplayıcı, Loki, metrik deposu ve bildirim zincirinin her birinin sorumlusu ve doğrulama yöntemi belli olsun.

Yeni işler için desteklenen toplayıcıyla küçük bir serviste başlayın; eski Promtail kurulumunu belgeli bir Alloy geçişiyle yenileyin. Canlıya almadan önce normal logu, çok satırlı hatayı, başarısız sağlık kontrolünü, kesilen veri akışını ve geri yüklemeyi doğrulayın. Bu kontroller tamamlandığında aynı düzeni diğer servislere uygulayın.

Sıkça Sorulan Sorular

Promtail 2 Mart 2026’da kullanım ömrünü tamamladı ve artık güncelleme almıyor. Yeni kurulumlarda Grafana Alloy gibi desteklenen bir toplayıcı kullanın. Buradaki Promtail YAML’i eski ayarları inceleme ve geçiş içindir; dönüştürme sonrası etiket, zaman, filtre, okuma konumu ve teslimatı doğrulayın.

Olay inceleme, yasal veya denetim ihtiyaçları ve kapasiteyi birlikte değerlendirin. 7–14 gün tanılama ya da 30 gün hata kaydı gibi süreler yalnızca örnektir. Loki’de süreyi belirtmek yetmez; uygun compactor ve silme deposu yapılandırması gerekir. Grafana panoları süresi dolmuş logları ayrıca saklamaz.

Kaynak tüketimi log hızına, regex ve multiline işlemlerine, etiketlere ve gönderim durumuna bağlıdır. CPU, bellek, gecikme, düşürülen kayıt ve yeniden deneme metriklerini ölçün. Gereksiz kayıtları filtrelemek yardımcı olabilir; fakat oran hesaplarında veya denetimde gereken veriyi silmeyin.

Önce veri kaynağı, zaman damgaları, sorgu ve eşik anlamını kontrol edin. rate saniyedeki log olayı sayısını verir; istek hata yüzdesi değildir. Pencere ve for süresini gerçek yükle ayarlayın. Veri yokluğu kuralları için beklenen log sıklığı veya heartbeat gerekir; kritik olayları genel susturma kurallarıyla gizlemeyin.
↑