Observability — logs, metrics, traces ve alarm tasarımı.
Bir gece p99'unuz iki katına çıktığında ya da yeni sürüm sonrası hata oranı tırmandığında elinizdeki tek şey sistemin size söylediği şeydir. Bu sayfada üç temel sinyalden — log, metrik ve trace — yapılandırılmış loglama disiplinine, OpenTelemetry'den SLO burn-rate alarmlarına kadar üretim sistemlerini bilinçli biçimde gözlemlemek için temel kavramları birlikte yan yana koyduk.
Monitoring ile observability aynı şey değil — bilinmez hatalarla karşılaşmak
Klasik monitoring "bildiğiniz şeyleri" izler: CPU yükü, disk doluluk, HTTP 5xx oranı. Sorun şudur ki üretimde sizi uyandıran şey çoğu zaman bilmediğiniz bir kombinasyondur — yalnızca İstanbul'daki kullanıcıların belirli bir ödeme yöntemiyle yaşadığı bir hata. Observability, sisteme önceden tahmin etmediğiniz soruları sorabilme kabiliyetidir: yeterli ham veriyi (yüksek-kardinaliteli olaylar, traces, yapılandırılmış log) öyle bir biçimde tutarsınız ki, sahada karşılaşacağınız ama bugünden öngöremeyeceğiniz vakalar için araç hazır olur.
Senaryo · 01Outage
Üretim düştü, sebebi belirsiz
Servis 03:14'te 5xx kusmaya başlıyor. CPU, RAM, disk normal. Son deploy 6 saat önce. Loglarda yalnızca "connection reset" görüyorsunuz — hangi upstream'in, hangi tenant için, hangi sıklıkta? Yapı yeterli değilse cevabı sabah ekibe sorarsınız.
Senaryo · 02Regresyon
Sürüm sonrası sessiz yavaşlama
Yeni deploy'dan sonra her şey "çalışıyor" görünür ama p95 yanıt süresi 120 ms'den 380 ms'ye sıçramıştır. Ortalama bunu yumuşatır; sahadan şikâyet birkaç gün gecikir. Sürümle metriği yan yana koyabilen bir kurulum bunu dakikalar içinde gösterir.
Senaryo · 03P99
Kuyruktaki azınlık kullanıcı
Ortalama yanıt süresi 90 ms; ama %1 kullanıcı 4 saniye bekliyor. Bu azınlık genelde en pahalı planlardaki müşteridir — büyük tenant, büyük sorgu, büyük cüzdan. p99 metriğini ve trace örneklerini sakladığınızda bu kullanıcıların kim olduğunu görürsünüz.
Senaryo · 04Kapasite
Ne zaman ölçeklendirelim?
Disk %78 dolu. Üç hafta önce %71'di. Trend devam ederse Pazartesi servis durur — ama bunu görmek için saatlik snapshot ve eski veri saklama gerekir. Anlık değer "iyi" der; eğim ise "yarın değil ama önümüzdeki ayın ilk haftası" der.
Senaryo · 05Audit
Kim, ne zaman, neye dokundu?
Bir kayıt silindi ve nedeni belirsiz. Admin paneli mi, API entegrasyonu mu, otomatik bir job mu? Hangi kullanıcı oturumunun, hangi IP'den, hangi sürüm ile yaptığı net olmazsa hem soruşturma hem KVKK / SOC 2 kanıtlama imkânsızlaşır. Yapılandırılmış audit logları bu boşluğu doldurur. Oturum, token ve yetkilendirme katmanının nasıl kurulduğu için Kimlik ve Erişim Yönetimi.
Senaryo · 06İş metriği
Düşen dönüşüm — sebep ne?
Ödeme tamamlanma oranı %3 düştü. Bu bir altyapı sorunu mu (3D Secure timeout), bir ürün değişikliği mi (yeni form alanı), yoksa bir kampanya etkisi mi? Teknik metrikler ile iş metriklerini aynı pano üzerinde gösterebilen kurulum, ürün ve altyapı ekibinin aynı zemini paylaşmasını sağlar.
Aksiyon alınamayan veri, gürültüdür.
Sahip olduğunuz her metrik, log ve trace bir bütçe (depolama, sorgu, dikkat) tüketir. Test edilecek bir soru, kovalanacak bir hipotez ya da bağlanacak bir alarm olmadan toplanan veri yalnızca panoları doldurur. Yola çıkarken sorun: "Bu sinyal hangi soruyu cevaplar? Cevap geldiğinde ne yaparım?" Cevap yoksa, sinyali kapatın.
02 — Üç sinyal
Logs, metrics, traces — üç sinyalin farklı işleri var
Modern observability üç temel sinyale dayanır: yapılandırılmış log kayıtları (zengin olaylar), zaman serisi metrikleri (ucuz sayılar) ve trace span'leri (istek yolculuğu). Her birinin güçlü olduğu bir soru türü, zayıf olduğu bir başka soru türü vardır — bir sinyali diğerinin yerine koymaya çalışmak en yaygın maliyet kaynağıdır.
Pratik kural şudur: metrik "ne kadar, ne sıklıkta" sorusunu cevaplar (agregat, alarm temeli); log "tam olarak ne oldu" sorusunu cevaplar (zengin bağlam, daha pahalı); trace "bu istek hangi servislere uğradı, nerede takıldı" sorusunu cevaplar (örnekleme zorunlu). Üçünü ortak bir trace_id ile birbirine bağladığınızda soruşturma süresi dakikalardan saniyelere iner.
Her satır bağımsız bir olayı anlatır: hangi servis, hangi kullanıcı, hangi hata. JSON satırı (NDJSON) tek standart pratiktir; serbest metin ("string concat") ne sorgulanabilir ne de filtrelenebilir. Güçlü yanı zengin bağlam taşımasıdır; zayıf yanı yüksek hacim ve pahalı saklama. Her log satırına trace_id ekleyin, tek başına satırlar değil hikâye anlatsın.
L2
Metrics — agregat sayılar ve dağılımlar
Sayaç (counter), gösterge (gauge), histogram ve özet (summary) — zaman içinde önceden hesaplanmış değerler. Çok ucuzdur, panoları ve alarmları besler. Sınırı şurada: tek bir kullanıcının "neden 4 saniye bekledi" sorusuna cevap veremez, yalnızca p99'unuzun 4 saniye olduğunu söyler. Cevabın detayı için log ya da trace gerekir.
L3
Traces — bir isteğin baştan sona yolculuğu
Mikroservisli ya da çoklu bileşenli bir mimaride tek bir isteğin hangi servislere uğradığını, her birinde ne kadar takıldığını gösteren span ağacı. Hangi adımın darboğaz olduğunu görsel olarak yakalarsınız. Hacim büyüktür, bu yüzden örnekleme (head sampling, tail sampling) zorunludur — bütün isteklerin trace'ini saklayan kimse yoktur, hatalı/yavaş olanları öncelikleyin.
03 — Yapılandırılmış log
Yapılandırılmış loglama: JSON satır, korelasyon ID ve PII disiplini
Loglama disiplinin yarısı tek satırlık karardır: serbest metin yerine yapılandırılmış JSON. User 42 logged in from 10.0.0.5 satırı görünüşte okunaklıdır ama beş dakika sonra "son bir saatte hangi IP'lerden hangi tenant'lar giriş yaptı" sorusuna cevap vermez. Aynı bilgi NDJSON olarak yazıldığında jq, Loki, Elasticsearch ya da BigQuery saniyeler içinde sorgular — insan da okur, makine de.
Her isteğin başında bir trace_id üretin (W3C traceparent başlığı) ve sonraki tüm log satırlarına, downstream çağrılara taşıyın. Bir hata satırından başlayıp aynı isteğin tüm logunu çekmek tek sorguya düşer; trace ile log arasındaki köprü budur.
Seviye
DEBUG yalnızca geliştirme/sorun giderme için; üretimde dinamik açılır. INFO iş olayı (sipariş alındı, kullanıcı oluştu). WARN beklenmedik ama otomatik düzelen durum. ERROR mutlaka eyleme dönüşmesi gereken hata. Bu disiplin korunmazsa alarm panellerini gürültü doldurur.
PII
Loglar KVKK ve PCI-DSS kapsamındadır. TC kimlik, IBAN, kart numarası, e-posta, telefon — kaynakta otomatik maskelenmeli (regex/format-aware redaction). Saklama süresini açıkça politika olarak yazın (örn. 30 gün sıcak, 90 gün soğuk, sonra sil). Yanlışlıkla loglanan bir kart numarası tüm log altyapınızı PCI scope'una çeker.
Loglama uygulamayı yavaşlatıyorsa, yanlış yapıyorsunuz.
Senkron disk yazımı yerine asenkron appender (async logger, ring buffer) kullanın; yüksek hacimli INFO satırlarını agresif örnekleyin (örn. 1/100), ERROR'ları her zaman saklayın. JSON serileştirmesinin pahalı olduğu yerlerde kayıtsız (zerolog/zap) kütüphanelere geçin. Loglama gözlemlemek içindir, sistemin kendisini felç etmek için değil.
04 — Metrik tasarımı
RED, USE ve Four Golden Signals — hangi metodoloji ne zaman
"Hangi metrikleri toplamalıyım" sorusunun pratik üç çerçevesi vardır. Hepsi aynı zemine basar — gözlenecek şey iş yüküdür, donanım değil — ama farklı sorulara cevap verirler. Bir SaaS API'sini RED ile, fiziksel bir veritabanı düğümünü USE ile, bütün sistemi sahanın gözünden Four Golden Signals ile izlemek tutarlı bir kombinasyon kurar.
Yöntem · 01RED
İstek tabanlı servisler için
Tom Wilkie'nin önerdiği üçlü — Rate (saniyede istek), Errors (başarısız oran), Duration (yanıt süresi dağılımı). HTTP API, gRPC servisi, kuyruk tüketicisi gibi her şeyin "istek" olarak sayılabildiği yerde işin %80'ini cevaplar. Üç metrik, üç pano, anlaşılır mesai.
http_requests_total
http_requests_total{status="5xx"}
http_request_duration_seconds
Yöntem · 02USE
Kaynak tabanlı bileşenler için
Brendan Gregg'in çerçevesi: her kaynak için Utilization (kullanım oranı), Saturation (kuyruk derinliği, bekleyen iş) ve Errors (hata sayacı). CPU, RAM, disk I/O, ağ arayüzü, veritabanı bağlantı havuzu — kaynak gibi düşünülebilen her bileşende çalışır. Saturation utilization'ı tamamlar: %70 CPU "rahat" görünür, ama run-queue 8 ise sistem boğulmuştur.
cpu_usage_percent
node_load1, run_queue
disk_io_errors_total
Yöntem · 03Four Golden
Google SRE — sahanın gözünden sistem
Latency (yanıt süresi, başarılı/başarısız ayrı), Traffic (talep), Errors (başarısızlık) ve Saturation (kaynak doluluğu). RED ile USE'un üst kümesi gibi davranır; SLO tasarımı ve kullanıcıya yansıyan deneyimi merkeze koyar. Çoğu üretim sistemi için bugünün önerilen başlangıç noktasıdır.
Latency: p50, p95, p99 — başarılı/hatalı ayrı
Saturation: en sınırlayıcı kaynak
SLO tasarımı için doğal zemin
Pratik · 01
Cardinality patlamasına dikkat
Prometheus benzeri sistemler her benzersiz label kombinasyonu için ayrı zaman serisi tutar. user_id, request_id, dinamik URL parametresi gibi yüksek-kardinaliteli alanları metrik label'ı olarak kullanmayın — milyon serili bir veritabanı saatler içinde diski doldurur, sorgular dakikalara çıkar. Yüksek kardinalite log ve trace'in işidir, metriğin değil.
Pratik · 02
Histogram > Summary — agregasyon için
Summary tipinde quantile'lar her örnek için yerel hesaplanır; sunucular arası birleştirilemezler ("p99 of p99 ≠ true p99"). Histogram ham bucket'ları toplar — farklı düğümlerden, farklı bölgelerden gelen veriyi sorgu zamanında doğru biçimde toplayabilirsiniz. Çok düğümlü servislerde varsayılan tercihiniz histogram olsun; bucket sınırlarını trafik dağılımına göre seçin.
05 — OpenTelemetry
OpenTelemetry ve dağıtık izleme boru hattı
OpenTelemetry (OTel) CNCF tarafından korunan, vendor-bağımsız bir observability standardıdır — SDK'lar, OTLP protokolü, semantik kurallar ve bir collector ile log/metrik/trace'i tek bir dil üzerinden konuşturur. Bu sayede sağlayıcı değiştirmek için kodu yeniden enstrümante etmek gerekmez; yalnızca collector'ın "export" hedefini değiştirirsiniz. Pratikte hat beş aşamadan geçer — her aşamada bilinçli bir karar vermek, hattı sürdürülebilir kılan şeydir.
OpenTelemetry boru hattı — soldan sağa
Aşama 01
Instrumentation
Uygulama içinde OTel SDK ile span üretimi. Çoğu dil için otomatik enstrümantasyon HTTP, gRPC ve veritabanı çağrılarını sıfır kodla yakalar; iş mantığı için manuel span'lar ekleyin.
SDK + auto-instr
Aşama 02
Collector
Uygulamadan ayrı bir process (sidecar / agent / gateway). Veriyi alır, zenginleştirir (resource attributes), filtreler, sampling uygular ve hedeflere export eder. Sağlayıcı değişimini izole eden katmandır.
OTLP gRPC/HTTP
Aşama 03
Backend
Depolama ve sorgu motoru: Tempo, Jaeger, Honeycomb, Datadog, Grafana Cloud. Veri modeli, saklama süresi ve sorgu dili (TraceQL, LogQL, PromQL) bu katmanda belirlenir.
Tempo / Jaeger
Aşama 04
Query & Pano
Grafana, backend'in kendi UI'ı ya da özel panolar. Sorgu kalitesi enstrümentasyon kalitesinden bağımsız değildir — eksik label sorgulamayı imkânsızlaştırır. "Hangi soruları sorduğumuz" panolarda görünür hale gelir.
Grafana / native UI
Aşama 05
Action — kapanan döngü
Bir alarmın bir runbook'a, bir runbook'un bir incident'a ve bir incident'ın bir kod/yapı değişikliğine dönüşmesi. Burası boş kalan bir observability yatırımı, en pahalı pano duvarına dönüşür.
alarm → runbook
OTel'in en büyük operasyonel hediyesi Aşama 02'dir — collector. Uygulama kodu OTLP'yi konuştuğu sürece, "yarın Honeycomb'dan Tempo'ya geçeceğiz" demek için yeni bir bütçe kalemi açmazsınız; yalnızca collector'ın exporters bölümünü değiştirir, kademeli geçiş için iki hedefe aynı anda yazarsınız.
Pratik · 01
Vendor-bağımsız enstrümentasyon
Sağlayıcı-özel SDK ile kod yazmak (Datadog, New Relic agent) kısa vadede kolay görünür, uzun vadede taşınmaz bir yük olur. OTel SDK'larına ve OTLP'ye bağlanın; sağlayıcı, sözleşme yenilemesinde verdiğiniz karar olsun, kodun dayattığı bir kader değil.
Pratik · 02
Head vs tail sampling
Head sampling isteğin başında karar verir (örn. %1) — ucuz ama nadir hataları kaçırır. Tail sampling trace tamamlandıktan sonra karar verir (hatalı/yavaş olanları sakla) — pahalı ama doğru veri tutar. Düşük trafikte head, yüksek trafikte tail tercih edilir; bazen ikisi katmanlı kullanılır.
Pratik · 03
Context propagation şart
Servisten servise W3C traceparent / tracestate başlıkları taşınmazsa trace zinciri kopar; ortaya bağımsız "yarım" span'lar çıkar. Kuyruk (RabbitMQ, Kafka), cron job ve background worker geçişlerinde mesaj header'ına trace context'ini koymayı unutmayın.
06 — Alarm tasarımı
SLO tabanlı alarm tasarımı ve burn-rate yaklaşımı
İyi alarm, insanları gece uyandırdığında karşılığını veren alarmdır. "CPU %85" tek başına bir alarm sebebi değildir — yalnızca sahadaki kullanıcı şikâyetinin önüne geçen bir sinyaldir. SLO (Service Level Objective) bu zemini sağlar: kullanıcıya verdiğiniz sözü ölçen bir SLI ile bağlanır, üzerinde bir hata bütçesi tanımlanır ve alarmlar bu bütçenin "ne kadar hızlı yandığına" göre tetiklenir. Sayfanın altındaki anti-pattern'lar, klasik tuzakların listesidir. SLO'nun sürüm hattı ve hata bütçesiyle ilişkisi için DevOps & Otomasyon.
Alarm kurulum runbook'u — sıfırdan üretime
Adım 01
SLO'yu kullanıcı sözüyle tanımlayın
"Checkout API isteklerinin %99.9'u 30 gün içinde 500 ms altında, başarılı yanıt döner." SLO ürünün vaadidir, altyapının ortalaması değil. Önce ne sözü verdiğinize karar verin; SLI ve alarmlar bunun ardından gelir.
Adım 02
SLI'ı ölçülebilir hâle getirin
SLO'ya karşılık gelen oranı koda dökün: sum(rate(http_requests_total{status!~"5.."}[5m])) / sum(rate(http_requests_total[5m])). SLI metriğin kendisidir; net, tek satır PromQL/LogQL. Belirsiz tanım belirsiz alarm üretir.
Adım 03
Hata bütçesini hesaplayın
%99.9 SLO, 30 günlük pencerede yaklaşık 43 dakika 12 saniye hata payı verir. Bu bütçe risk almanın ölçüsüdür: bütçe rahatsa cesur deploy yapın, tükenmişse dağıtımı yavaşlatın. Ekibin paylaştığı tek "evet/hayır" sayısıdır.
Adım 04
Multi-window multi-burn-rate alarm kurun
Tek pencerede tek eşik yerine iki pencereyi birleştirin: hızlı burn (örn. 5 dk + 1 saatte 14.4× burn → sayfa) ile yavaş burn (örn. 1 sa + 6 sa'te 6× burn → ticket). Bu yapı yanlış pozitifi düşürür, gerçek olayı erken yakalar — Google SRE Workbook'un önerdiği temel desendir.
Adım 05
Şiddete göre kanalı seçin
Her alarm aynı kanala gitmez. Page (PagerDuty, telefon zili): hızlı burn, üretim down. Ticket / Slack: yavaş burn, sabah bakılır. E-posta / pano: bilgi, eyleme gerek yok. Yanlış yönlendirme alert fatigue'in en yaygın sebebidir.
Adım 06
Her alarma bağlı bir runbook yazın
Alarm metni bir runbook URL'i içermeli — "ne demek bu alarm, ilk üç bakılacak yer, geçici çare, kalıcı çözümün izleneceği bilet". Runbook'u yazılmayan bir alarm, gecenin üçünde tartışılan bir alarmdır. Her postmortem runbook'u günceller; runbook'lar yaşayan belgelerdir.
Sık görülen anti-pattern'lar
Anti · 01cause-based
Sebep tabanlı alarm
"Disk %90" gece üçte uyandırır ama kullanıcı bunu hissetmiyor olabilir. Sebep değil, kullanıcının gördüğü belirti üzerinden alarm kurun: "checkout başarı oranı %99.5'in altına düştü". Disk bir runbook adımı olsun — alarm değil.
Anti · 02fatigue
Alarm yorgunluğu
Haftada 200 alarmın 195'i göz ardı ediliyorsa hiç alarm yok demektir. On-call'ın gerçek alarmı kaçırma maliyeti, gürültüyü kapatma maliyetinden büyüktür. Alarm silmek bir kayıp değil, bir özelliktir; düzenli alarm temizliği takvime girsin.
Anti · 03static
Sabit eşik körlüğü
"Latency > 500 ms" kuralı Black Friday'de boğulur, gecenin üçünde ise hiçbir şey yakalamaz. SLO'ya bağlı oransal eşik (hata bütçesinin %X'i tüketildi) ya da değişim oranı (15 dakikada 3× artış) bağlama uyum sağlar — statik eşik her zaman geçici çözümdür.
Hatırlatma
Her alarm bir "evet" demektir: "evet, bu gece uyandırılmaya değer". Sayfanın altındaki klavyeniz: alarmları paged-runbook eşiğiyle test edin — son üç ay tetiklenmemiş bir alarm gerçek bir uyarı mı, yoksa kapatılması gereken bir kalıntı mı?
07 — Sık karıştırılanlar
Sık karıştırılan observability kavramları
Monitoringvs.Observability
Monitoring önceden tanımladığınız sorulara cevap verir: CPU yüksek mi, hata sayısı eşiği aştı mı. Observability ise sistemin durumunu sonradan da sorgulanabilir hâle getirir — yeterli ham veri (yüksek-kardinaliteli event, trace, yapılandırılmış log) sayesinde bugün öngörmediğiniz sorulara da cevap üretebilirsiniz. İkincisi birincisinin yerini almaz, onu genişletir.
Logsvs.Events
Log klasik olarak satır-tabanlı, çoğu kez serbest metin olan kayıttır. Event ise yapılandırılmış, çok-alanlı bir kayıttır — bir log satırı tek bir alanı, bir event ise tüm bağlamı (kullanıcı, tenant, oturum, latency, trace_id) bir arada tutar. "Wide events" disiplinine geçmek, sorgulayabildiğiniz şeyleri büyütür.
Metricvs.Histogram
Metric bir zaman serisi içindeki sayıdır (counter, gauge). Histogram ise bir metrik tipidir — değerleri bucket'lara dağıtır ve sorgu zamanında quantile hesaplamaya izin verir. Tek bir gauge ortalamayı söyler; histogram p50, p95, p99 hepsini çıkarır.
APMvs.Distributed Tracing
APM (Application Performance Monitoring) tarihsel olarak tek bir uygulamanın iç performansını izleyen, sağlayıcı-özel agent'lara dayanan kategoridir. Distributed tracing ise servisler arası bir isteğin yolculuğunu standart bir biçimde (OpenTelemetry) izler. Modern APM ürünleri zaten tracing içerir; ama karar verirken "OTel native mi, agent dayatıyor mu" sorusu kritiktir.
Alertingvs.Paging
Alerting bir koşul gerçekleştiğinde bildirim üretmektir (e-posta, Slack, ticket). Paging ise birini telefonuyla, mesai dışında, uyandırarak çağırmaktır. Her alarm paging değildir; çoğu uyarı bir bilet ya da panoya akmalıdır. Paging özel rezerv edildiğinde anlamını korur.
Birinci el kaynaklar
OpenTelemetry, Google SRE Workbook, Prometheus, W3C Trace Context ve observability literatürünün temel kaynakları.
Logs, metrics, traces hattınızı, SLO ve alarm tasarımınızı gözden geçirelim — gece uyandıran alarmın değerli, görmezden gelinen alarmın az olduğu bir kurulumu birlikte planlayalım.