Monitoring ve Logging Arasındaki Fark: Sistemde Sorun Olduğunu Nasıl Anlarız?
Metrik, log ve trace verilerini kullanıcı etkisi etrafında birleştirelim; SLI/SLO, anlamlı alarmlar ve yüksek cardinality sorununu pratik örneklerle ele alalım.
Bir dashboard tamamen yeşil görünürken kullanıcı ödeme yapamıyor olabilir. Tersi de mümkündür: CPU yükselmiştir ama kullanıcı deneyimi değişmemiştir. Sistemi izlemek, mümkün olan her sayıyı ekrana koymaktan çok hangi davranışın gerçekten önemli olduğunu tanımlamaktır.
Monitoring ve logging birbirinin alternatifi değildir. Biri koşulların zaman içindeki durumunu takip etmeye, diğeri belirli olayların bağlamını anlamaya yardımcı olur. Dağıtık sistemlerde tracing de aradaki ilişkiyi görünür hale getirir.
Metrik, log ve trace hangi soruyu cevaplar?
Metrik, sayısal bir ölçümün zaman içindeki özetidir: istek sayısı, hata oranı veya kuyruk uzunluğu gibi. Log, belirli bir olayın kaydıdır: bir isteğin doğrulama hatasıyla reddedilmesi veya bağlantının kesilmesi gibi. Trace ise bir işlemin servisler arasındaki yolculuğunu span'ler üzerinden izler.
Örneğin ödeme API'sinde gecikme arttıysa metrik “ne zaman ve ne kadar?” sorusunu, trace “hangi adım yavaş?” sorusunu, ilgili log ise “o adımda hangi olay oluştu?” sorusunu cevaplayabilir. Kavramlar OpenTelemetry observability primer içinde birbirine bağlanır.
Her istek için her ayrıntıyı kaydetmek zorunda değilsiniz. Maliyet, gizlilik ve örnekleme politikası tasarımın parçasıdır.
Kullanıcı davranışından bir ölçüm seçin
Bir sipariş servisi için CPU oranı yerine şu soruyla başlayın: “Geçerli sipariş oluşturma girişimlerinin ne kadarı kabul edilebilir sürede başarıyla tamamlanıyor?”
Bu sorudan bir SLI, yani hizmet düzeyi göstergesi çıkarabilirsiniz. SLO ise bu göstergenin belirli zaman penceresindeki hedefidir. “Son 30 günde uygun isteklerin yüzde 99,9'u başarılı” gibi bir hedef örnektir; gerçek eşik iş beklentisi ve sistem maliyetiyle belirlenmelidir.
Hangi isteklerin paydaya girdiğini açıklamazsanız gösterge yanıltıcı olur. Kullanıcı doğrulama hatalarını hizmet kesintisi sayıyor musunuz? Timeout'ları dışarıda bırakırsanız en kötü istekler görünmez hale geliyor mu? Ölçüm sözleşmesi sorgudan önce gelir.
RED ve USE yaklaşımını birlikte düşünmek
İstek tabanlı bir servis için rate, errors ve duration; kaynaklar için utilization, saturation ve errors iyi başlangıç noktalarıdır. Örneğin API istek oranı normalken veritabanı bağlantı havuzu tamamen dolmuş olabilir.
İzlenecek örnekler:
- Endpoint bazında istek ve hata oranı.
- p50, p95 ve p99 gecikme; uygun histogram sınırlarıyla.
- Veritabanı havuzunda kullanılan ve bekleyen bağlantılar.
- Worker kuyruğunda iş sayısı ve en eski işin yaşı.
- Process belleği, restart sayısı ve event loop gecikmesi.
Sadece ortalama süreye bakmak uzun kuyruktaki kötü kullanıcı deneyimini saklayabilir. Öte yandan farklı instance'ların p95 değerlerini ortalamak da toplam p95'i vermez. Histogram verisini uygun şekilde birleştirmek gerekir.
Alarmın bir eylemi olmalı
Aşağıdaki PromQL ifadesi örnektir. Sistemin http_requests_total sayacını, service ve status etiketleriyle ürettiği varsayılır:
(
sum(rate(http_requests_total{service="task-api",status=~"5.."}[5m]))
/
sum(rate(http_requests_total{service="task-api"}[5m]))
) > 0.05
and
sum(rate(http_requests_total{service="task-api"}[5m])) > 1
Bu, yeterli trafik varken beş dakikalık hata oranının yüzde 5'i aşmasını seçer. Eşikler örnektir. Uygun bir for süresi, kısa sıçramalarda gereksiz alarmı azaltabilir. Trafik yokken ya da metrik hiç gelmezken sorgunun sessiz kalabilmesi nedeniyle ayrı erişilebilirlik ve veri yokluğu kontrolleri gerekir.
Alarm açıklamasında sorumlu servis, dashboard bağlantısı ve ilk inceleme adımı bulunmalıdır. Prometheus alarm rehberi özellikle kullanıcıya yansıyan semptomlara ve anlamlı alarmlara odaklanır.
Logları sorgulanabilir tasarlamak
Serbest metin yerine tutarlı alanlar kullanmak olaylar arasında bağ kurmayı kolaylaştırır:
{
"level": "error",
"service": "task-api",
"event": "database_timeout",
"request_id": "example-request-42",
"route": "/api/tasks/:id",
"duration_ms": 2000,
"deployment": "example-revision"
}
Bu örnek sentetiktir. Gerçek kayıtta parolayı, Authorization header'ını veya tüm request body'yi otomatik yazmayın. Request ID'yi dış girdiden alıyorsanız biçim ve uzunluk sınırını kontrol edin; üretim ve taşıma politikasını belirleyin.
İstek kimliği logda yararlıdır, fakat onu her metriğin etiketi yapmak ayrı bir sorundur.
Cardinality maliyetini görün
Her kullanıcı ID'si, tam URL veya request ID ayrı metrik serileri yaratabilir. Etiket kombinasyonları büyüdükçe depolama ve sorgu maliyeti artar. /api/tasks/123 yerine /api/tasks/:id gibi sınırlı route şablonları kullanmak daha kontrollüdür.
Ayrıntılı kimlikleri log veya trace bağlamında tutup metrikleri sınırlı boyutlarla toplamak çoğu durumda daha dengelidir. OpenTelemetry'nin sinyal modeli bu veri türlerini ortak bir gözlemlenebilirlik yapısında ele alır.
Örnek arıza incelemesi
Alarm tetiklendiğinde önce kullanıcı etkisinin hangi endpoint ve sürümde yoğunlaştığını bulun. Sonra yavaş trace'lerde veritabanı span'lerinin uzayıp uzamadığını inceleyin. Aynı zaman aralığındaki loglar connection pool timeout gösteriyorsa, yeni sürümün bağlantıları serbest bırakmaması gibi bir hipotez kurabilirsiniz.
Tek bir grafiğin düzelmesiyle olayı kapatmayın. Kullanıcı işlemi tekrar başarılı mı, kuyruk geriliyor mu ve hata bütçesi üzerindeki etki durmuş mu kontrol edin. Gözlemlenebilirlik, çok veri toplamak yerine bu soruları güvenilir kanıtla cevaplayabilmektir.
Related Posts
Reverse Proxy Nedir? Nginx ile Gerçek Bir Kullanım Senaryosu
Node.js uygulamasını Nginx arkasına alırken URI yönlendirme, forwarded header, timeout ve 502/504 teşhisinin nasıl birlikte tasarlanacağını inceleyelim.
Terraform ile Infrastructure as Code Mantığını Anlamak
Terraform'u komut otomasyonu yerine istenen durum yönetimi olarak ele alalım; plan, state, drift, bağımlılık grafiği ve güvenli apply sürecini örnekleyelim.
Docker Container Nasıl Çalışır? Image, Container ve Volume Mantığı
Image katmanları, çalışan container, izolasyon ve kalıcı veriyi birbirinden ayıralım; Node.js örneğiyle build ve işletim kararlarını inceleyelim.