Gözlemlenebilirlik ve OpenTelemetry

Yazılımda Gözlemlenebilirlik (Observability) ve OpenTelemetry nedir? Metrik (Prometheus/Grafana), merkezi loglama ve dağıtık izleme (Distributed Tracing).

Yozel

12 dakika

Gözlemlenebilirlik ve OpenTelemetry
İçindekiler (16)

Tek bir sunucu üzerinde çalışan monolitik yazılım mimarilerinde bir hata veya yavaşlama yaşandığında sorunun kaynağını bulmak nispeten basitti: Mühendis sunucuya SSH ile bağlanır, htop ile CPU ve RAM kullanımına bakar ve tail -f /var/log/app.log komutuyla log dosyasını okurdu. Ancak günümüzün bulut-yerel (cloud-native) dünyasında tek bir kullanıcı isteği (örneğin bir e-ticaret sitesinde "Siparişi Tamamla" butonuna basılması); API Gateway, Kimlik Doğrulama Servisi, Sepet Servisi, Stok Servisi, Kampanya Motoru, Ödeme Sağlayıcısı, Kafka mesaj kuyrukları ve üç farklı veritabanı olmak üzere 15 ila 30 farklı mikroservis ve sunucusuz (serverless) fonksiyondan geçmektedir. Bu dağıtık kaos içinde geleneksel izleme (Monitoring) araçları yalnızca "Sistemde bir sorun var" diyebilirken, sorunun neden ve hangi mikroservisin hangi satırında gerçekleştiğini anlamamızı sağlayan disiplin Gözlemlenebilirlik (Observability) ve onun evrensel açık standardı OpenTelemetry (OTel) olmuştur. Uygulama ve yazılım mimarileri dünyasında kesintisiz çalışma süresinin (Uptime) ve yüksek performansın sigortası olan gözlemlenebilirlik mimarisini; Metrik, Log ve Dağıtık İzleme (Trace) sütunlarından Google SRE Altın Sinyallerine, Prometheus/Grafana/Loki/Tempo yığınından OpenTelemetry Collector mimarisine kadar tüm teknik derinliğiyle inceliyoruz.

1. İzleme (Monitoring) vs. Gözlemlenebilirlik (Observability): Fark Nedir?

Sektörde sıklıkla birbirinin yerine kullanılsa da Monitoring (İzleme) ve Observability (Gözlemlenebilirlik) temelden farklı iki mühendislik yaklaşımıdır. Kontrol teorisinden (Control Theory) yazılım mühendisliğine geçen Gözlemlenebilirlik kavramı; bir sistemin iç durumunu (internal state), yalnızca dışarıya ürettiği çıktılara (telemetri verilerine) bakarak ne kadar iyi anlayabildiğinizin ölçüsüdür.

Aradaki temel farkı Donald Rumsfeld'in ünlü bilgi matrisiyle özetlemek mümkündür:

  • Geleneksel Monitoring "Bilinen Bilinmeyenleri" (Known Unknowns) takip eder: Sistemin nerede kırılabileceğini önceden tahmin edersiniz ve buna göre eşik değerleri (thresholds) belirlersiniz. Örneğin: "CPU kullanımı %85'i geçerse alarm çal", "Disk doluluk oranı %90 olursa SMS at" veya "HTTP 500 hata oranı %2'yi aşarsa PagerDuty uyarısı üret." Ancak modern dağıtık sistemlerde CPU %30'dayken, RAM boşken ve hiçbir sunucu kapanmamışken bile belirli bir kullanıcı grubunun ödeme işlemleri 12 saniye sürebilir. Geleneksel izleme panelleri bu durumda tamamen yeşil yanmaya devam eder.
  • Observability ise "Bilinmeyen Bilinmeyenleri" (Unknown Unknowns) keşfetmenizi sağlar: Daha önce hiç karşılaşmadığınız, öngörülemez ve yalnızca belirli koşullar bir araya geldiğinde (örneğin "Yalnızca iOS 17.4 kullanan, sepetinde hem dijital hem fiziksel ürün olan ve X bankasının kredi kartıyla taksitli ödeme yapan kullanıcılarda stok kilitleme servisinin Redis zaman aşımına uğraması") ortaya çıkan karmaşık hataları, sisteme yeni kod ekleyip yeniden dağıtım yapmaya gerek kalmadan, mevcut yüksek kardinaliteli (high-cardinality) telemetri verilerini sorgulayarak dakikalar içinde bulabilme yeteneğidir.

2. Gözlemlenebilirliğin Üç Temel Sütunu: Metrics, Logs ve Traces

Modern bir gözlemlenebilirlik mimarisi birbirini tamamlayan üç temel telemetri sinyali (Three Pillars of Observability) üzerine inşa edilir. Bu üç sinyalden herhangi biri eksik olduğunda olay müdahale (Incident Response) sürecinde kör noktalar oluşur ve ortalama onarım süresi (MTTR) saatlere uzar.

Gözlemlenebilirliğin Üç Temel Sütunu Metrik Log ve Dağıtık İzleme Trace
Metrikler sorunun varlığını, Dağıtık İzler (Traces) sorunun hangi mikroserviste yaşandığını, Yapılandırılmış Loglar ise hatanın tam kök nedenini ortaya koyar.

2.1. Birinci Sütun: Metrikler (Metrics) – "Bir Sorun Var mı ve Ne Kadar Büyük?"

Metrikler, zaman damgalı (time-series) ve etiketlenmiş sayısal ölçümlerdir. Depolanması ve sorgulanması son derece ucuzdur çünkü ham olayları tek tek kaydetmek yerine matematiksel özetleri tutar. Prometheus, VictoriaMetrics, Mimir ve Grafana bu katmanın endüstri standartlarıdır. Dört temel metrik tipi bulunur:

  • Counter (Sayaç): Yalnızca artabilen (veya servis yeniden başladığında sıfırlanan) kümülatif değerlerdir. Örnek: Toplam HTTP istek sayısı (http_requests_total), toplam başarılı sipariş sayısı, toplam yakalanan istisna (exception) sayısı.
  • Gauge (Gösterge): Zaman içinde hem artabilen hem azalabilen anlık durum ölçümleridir. Örnek: Anlık bellek kullanımı (process_resident_memory_bytes), aktif WebSocket bağlantı sayısı, Kafka kuyruğunda bekleyen mesaj sayısı (Consumer Lag).
  • Histogram: Ölçülen değerleri (örneğin yanıt sürelerini veya istek boyutlarını) önceden tanımlanmış kova (bucket) aralıklarına göre gruplar. Yazılım performans analizinde Ortalama (Average) yanıt süresi son derece yanıltıcıdır; çünkü 99 isteğin 10 milisaniyede, 1 isteğin ise 10 saniyede yanıtlandığı bir sistemde ortalama 109 milisaniye görünür. Histogramlar sayesinde P95, P99 ve P99.9 (Yüzdelik Dilim / Percentile) gecikme sürelerini doğru şekilde hesaplayabiliriz.
  • Summary: Histogram'a benzer şekilde yüzdelik dilimleri doğrudan istemci tarafında hesaplar ancak birden fazla uygulama kopyası (Pod) arasında matematiksel olarak birleştirilemediği (non-aggregatable) için dağıtık sistemlerde Histogram tercih edilir.

2.2. İkinci Sütun: Yapılandırılmış Loglar (Structured Logs) – "Tam Olarak Neden Oldu?"

Loglar, uygulama çalışırken meydana gelen ayrık (discrete) olayların zaman damgalı metin kayıtlarıdır. Ancak geleneksel düz metin (2026-10-21 14:22:01 ERROR Odeme basarisiz oldu kullanici 4821) logları milyarlarca satır arasında düzenli ifadelerle (Regex) aramak hem çok yavaştır hem de yüksek CPU maliyeti yaratır. Bu nedenle modern sistemlerde tüm loglar Yapılandırılmış JSON (Structured JSON Logging) formatında üretilir:

{"timestamp": "2026-10-21T14:22:01.412Z", "level": "ERROR", "service": "payment-service", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "span_id": "00f067aa0ba902b7", "user_id": "usr_4821", "order_id": "ord_99102", "provider": "iyzico", "error_code": "INSUFFICIENT_FUNDS", "latency_ms": 1420}

Bu yapı sayesinde Grafana Loki, Elasticsearch (ELK / OpenSearch) veya ClickHouse üzerinde service="payment-service" AND error_code="INSUFFICIENT_FUNDS" şeklinde milisaniyeler içinde filtreleme ve gruplama yapılabilir. Özellikle Grafana Loki, logların tamamını indekslemek yerine yalnızca Prometheus gibi etiketlerini (labels) indeksleyerek depolama maliyetlerini ELK yığınına kıyasla %70'e varan oranda düşürmektedir.

2.3. Üçüncü Sütun: Dağıtık İzleme (Distributed Tracing) – "Sorun Hangi Serviste Yaşandı?"

Mikroservis mimarisinde gözlemlenebilirliğin en kritik sütunu Distributed Tracing (Dağıtık İzleme) katmanıdır. Kullanıcı tarayıcıdan veya mobil uygulamadan ilk isteği gönderdiğinde, sisteme giriş noktasında (Ingress / API Gateway) bu isteğe küresel olarak benzersiz bir TraceID (İz Kimliği) atanır. İstek A servisinden B servisine HTTP (REST/gRPC) ile geçerken veya Kafka/RabbitMQ kuyruğuna bırakılırken, W3C Trace Context standardına uygun olarak HTTP başlığında (traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01) bu TraceID taşınır (Context Propagation).

İsteğin geçtiği her bir mikroservis, yaptığı her alt işlem (örneğin bir PostgreSQL sorgusu çalıştırma, Redis önbellekten veri okuma, dış API çağırma) için kendi Span (Kapsam) kaydını oluşturur ve buna bir SpanID ile kendisini çağıran üst işlemin ParentSpanID bilgisini ekler. Jaeger, Grafana Tempo veya Zipkin gibi araçlar bu Span'ları birleştirerek isteğin uçtan uca yolculuğunu bir Şelale Grafiği (Waterfall / Flame Graph) olarak görselleştirir. Böylece 3 saniye süren bir sipariş işleminin 2.85 saniyesinin "Kampanya Servisi" içindeki indeks eklenmemiş tek bir SQL sorgusunda harcandığını tek bakışta görebilirsiniz.

3. Google SRE Altın Sinyalleri (Four Golden Signals), RED ve USE Metodolojileri

Yüzlerce metrik toplayıp ekrana 50 tane grafik koymak gözlemlenebilirlik değildir; aksine "Alarm Yorgunluğu" (Alert Fatigue) yaratır. Google Site Reliability Engineering (SRE) kitabında tanımlanan Dört Altın Sinyal (Four Golden Signals) ve onu tamamlayan RED / USE metodolojileri, neyi ölçmemiz gerektiğini standartlaştırır:

  • 1. Latency (Gecikme Süresi): Bir isteğe yanıt vermenin ne kadar sürdüğüdür. Burada kritik kural, başarılı (HTTP 200) isteklerin gecikmesi ile başarısız (HTTP 500) isteklerin gecikmesini ayrı ayrı ölçmektir. Çünkü veritabanı bağlantısı koptuğunda uygulama 1 milisaniye içinde 500 Internal Server Error dönebilir ve bu hızlı hata yanıtları genel gecikme ortalamanızı yapay olarak düşük gösterir!
  • 2. Traffic (Trafik / Talep): Sistemin üzerindeki anlık yük miktarıdır (Saniyedeki HTTP isteği - RPS, saniyedeki veritabanı işlemi veya eşzamanlı aktif oturum sayısı).
  • 3. Errors (Hatalar): Başarısız olan isteklerin tüm isteklere oranıdır. Yalnızca açık HTTP 5xx hataları değil; HTTP 200 dönüp içinde yanlış veri barındıran mantıksal hatalar ve SLA süresini (örneğin >2 saniye) aşan yanıtlar da hata bütçesine (Error Budget) dahil edilir.
  • 4. Saturation (Doygunluk): Sistemin kapasitesinin ne kadar "dolu" olduğudur. CPU, RAM, disk I/O, veritabanı bağlantı havuzu (Connection Pool) doluluk oranı veya iş parçacığı (Thread Pool) kuyruk uzunluğu doygunluk göstergesidir. Çoğu sistem %100 doygunluğa ulaşmadan çok önce (%80-85 civarında) kuyruk teorisi gereği üstel gecikme artışları yaşar.

4. OpenTelemetry (OTel): Satıcı Bağımsız (Vendor-Neutral) Telemetri Standardı

Yakın geçmişe kadar bir şirket Datadog, New Relic veya Dynatrace kullanmak istediğinde, tüm mikroservislerinin kaynak koduna o şirkete özel tescilli (proprietary) SDK ve ajanları eklemek zorundaydı. İki yıl sonra lisans maliyetleri arttığında ve başka bir platforma veya açık kaynaklı Grafana/Prometheus yığınına geçmek istediklerinde, yüzlerce mikroservisin kodunu baştan aşağı değiştirmek (Vendor Lock-in - Satıcı Bağımlılığı) zorunda kalıyorlardı.

OpenTelemetry Standardı OTel Collector Mimarisi ve Darboğaz Tespiti
OpenTelemetry (OTel), uygulama kodunu tek bir açık standartla enstrümante ederek telemetri verilerini kod değişikliği yapmadan istenilen tüm analiz platformlarına yönlendirir.

Bu parçalanmayı bitirmek için CNCF çatısı altında OpenTracing ve OpenCensus projeleri birleştirilerek OpenTelemetry (OTel) oluşturuldu. Bugün Kubernetes'ten sonra CNCF'in en aktif ikinci projesi olan OpenTelemetry; Metrik, Log, Trace ve Sürekli Profilleme (Continuous Profiling) verilerini üretmek, toplamak ve dönüştürmek için tek bir evrensel API, SDK ve protokol (OTLP - OpenTelemetry Protocol) sunar.

4.1. Zero-Code (Otomatik) vs. Manuel Enstrümantasyon

OpenTelemetry iki katmanlı enstrümantasyon yeteneği sağlar:

  • Otomatik Enstrümantasyon (Auto-Instrumentation): Java, Node.js, Python, .NET ve Go (eBPF desteğiyle) uygulamalarında tek satır iş kodu değiştirmeden çalışan ajanlar; gelen HTTP isteklerini, gRPC çağrılarını, PostgreSQL/MySQL sorgularını, Redis komutlarını ve Kafka mesajlarını otomatik olarak yakalar ve Span üretir.
  • Manuel Enstrümantasyon (Custom Spans & Attributes): Mühendisler OTel API'sini kullanarak iş mantığına özel verileri Span içerisine ekleyebilir (örneğin span.setAttribute("app.tenant.tier", "enterprise") veya span.setAttribute("cart.item_count", 14)).

4.2. OpenTelemetry Collector Mimarisi: Receivers, Processors, Exporters

Uygulama Pod'larının topladığı telemetri verilerini doğrudan dış dünyadaki analiz sunucularına göndermesi yerine, küme içinde çalışan OpenTelemetry Collector bileşenine göndermesi kurumsal en iyi pratiktir. OTel Collector üç aşamalı bir boru hattı (Pipeline) çalıştırır:

  1. Receivers (Alıcılar): OTLP (gRPC/HTTP), Prometheus, Jaeger veya FluentBit formatındaki telemetri verilerini uygulamalardan kabul eder.
  2. Processors (İşleyiciler): Veriyi arka uca göndermeden önce bellekte tamponlar (Batching), kredi kartı numarası veya T.C. Kimlik No gibi kişisel verileri (PII) KVKK/GDPR uyumu için maskeler (Redaction), Kubernetes Pod etiketlerini ekler (K8s Attributes) ve Tail-Based Sampling (Kuyruk Tabanlı Örnekleme) uygular. Örneğin saniyede 50.000 başarılı (HTTP 200) isteğin yalnızca %1'inin Trace kaydını saklarken, hata veren (HTTP 500) veya 2 saniyeden uzun süren isteklerin %100'ünü saklayarak depolama maliyetlerini %90 düşürür!
  3. Exporters (Aktarıcılar): İşlenmiş veriyi aynı anda hem şirket içi Grafana Tempo/Prometheus'a hem de buluttaki Datadog, Honeycomb veya New Relic'e paralel olarak gönderir. Arka uç sağlayıcısını değiştirmek istediğinizde uygulama koduna hiç dokunmadan yalnızca Collector'ın config.yaml dosyasındaki 3 satırı değiştirmeniz yeterlidir.
Telemetri Sinyali Temel Soru Veri Hacmi ve Maliyet Açık Kaynak Standart Araçlar Örnek Kullanım Senaryosu
Metrics (Metrikler) "Sistemde bir sorun var mı?" Çok Düşük (Sayısal zaman serisi) Prometheus, VictoriaMetrics, Mimir, Grafana Ödeme servisinde P99 gecikmesinin 300ms'den 2.4 saniyeye fırladığını tespit edip alarm üretmek
Traces (Dağıtık İzler) "Sorun hangi serviste ve adımda?" Orta (Örnekleme / Sampling ile yönetilir) Grafana Tempo, Jaeger, Zipkin, OpenTelemetry 2.4 saniyelik gecikmenin 2.1 saniyesinin Stok Servisi'nin yaptığı kilitli SQL sorgusundan kaynaklandığını görmek
Logs (Yapılandırılmış Loglar) "Hatanın tam kök nedeni ve detayı ne?" Yüksek (JSON indeksleme/sıkıştırma gerekir) Grafana Loki, OpenSearch (ELK), ClickHouse İlgili TraceID'ye tıklandığında o SQL sorgusunun hangi product_id parametresiyle Deadlock hatası verdiğini okumak
Profiles (Sürekli Profilleme) "Hangi fonksiyon CPU/RAM tüketiyor?" Düşük (eBPF örnekleme tabanlı) Grafana Pyroscope, Parca, OpenTelemetry Profiling Canlı ortamda CPU'nun %60'ını tüketen JSON serileştirme fonksiyonunu satır bazında Flame Graph ile yakalamak
Sinyaller Arası Korelasyon (Exemplars): Modern gözlemlenebilirliğin zirvesi üç sütunu tek tıklamayla birbirine bağlayan Exemplars (Örnekleyiciler) teknolojisidir. Grafana üzerinde Prometheus gecikme grafiğinde (Metric) ani bir yükseliş gördüğünüzde, grafiğin üzerindeki küçük elmas ikonuna (Exemplar) tıklayarak o yükselişe sebep olan örnek isteğin doğrudan Jaeger/Tempo şelale grafiğine (Trace) atlayabilir, oradan da ilgili Span'a tıklayarak o milisaniyede üretilmiş Loki hata satırlarını (Log) aynı ekranda açabilirsiniz.

5. Modern Mimarilerde AIOps ve eBPF Tabanlı Gözlemlenebilirlik

Gözlemlenebilirlik dünyası bugün iki yeni devrimle daha da güçlenmektedir: Linux çekirdeği (Kernel) seviyesinde çalışan eBPF (Extended Berkeley Packet Filter) ve yapay zeka destekli sistem analizi (AIOps). Cilium Hubble, Pixie ve Beyla gibi eBPF tabanlı araçlar, uygulamanın içine hiçbir SDK kurmadan ve uygulamayı yeniden başlatmadan doğrudan Linux çekirdeğindeki sistem çağrılarını (syscalls) ve TCP/HTTP/gRPC paketlerini dinleyerek tam kapsamlı servis haritaları ve OpenTelemetry metrikleri üretebilmektedir.

İster yüksek hacimli bulut tabanlı e-ticaret ve SaaS platformları, ister merkezsiz Web3 düğüm ağları, isterse kurumsal B2B bayi portalları ve API entegrasyon katmanları yönetiyor olun; OpenTelemetry standardını mimarinin merkezine yerleştirmek, karanlıkta hata aramak yerine sisteminizin her milisaniyesini röntgen cihazı netliğinde görmenizi sağlar.

6. Sıkça Sorulan Sorular (SSS)

1. OpenTelemetry kendi başına Grafana veya Datadog gibi görsel bir arayüz (Dashboard) sunar mı?

Hayır, bu en sık düşülen kavram yanılgısıdır. OpenTelemetry bir depolama veritabanı veya görselleştirme arayüzü değildir. OpenTelemetry; telemetri verilerinin (Metrik, Log, Trace) üretilmesi, toplanması, işlenmesi ve dışa aktarılması için evrensel boru hattı ve standarttır. Verileri saklamak ve grafiklerde görmek için OTel Collector'ın ucuna açık kaynaklı LGTM yığınını (Loki, Grafana, Tempo, Mimir/Prometheus), Jaeger'ı, SigNoz'u veya ticari bir APM platformunu bağlamanız gerekir.

2. Prometheus'ta "High Cardinality" (Yüksek Kardinalite) tehlikesi nedir ve sistemi nasıl çökertir?

Prometheus metriklerinde her benzersiz etiket (label) kombinasyonu bellekte (RAM) yeni bir zaman serisi (time-series) oluşturur. Eğer bir metriğe method="POST" (5 olası değer) ve status="200" (10 olası değer) etiketi verirseniz toplam 5 x 10 = 50 zaman serisi oluşur, bu çok sağlıklıdır. Ancak yanlışlıkla metriğin etiketine user_id, email, ip_address veya request_id gibi milyonlarca farklı değer alabilen (yüksek kardinaliteli) bir alan koyarsanız, milyonlarca zaman serisi oluşur (Cardinality Explosion) ve Prometheus sunucunuz dakikalar içinde Out-Of-Memory (OOM) hatasıyla çöker. Kullanıcı ID'si ve Sipariş ID'si gibi yüksek kardinaliteli veriler asla Metrik etiketlerine konulmamalı; Trace (Span Attributes) ve Yapılandırılmış Log içinde tutulmalıdır.

3. Canlı ortamda (Production) tüm istekler için Distributed Tracing açmak performansı düşürür mü?

OpenTelemetry SDK'ları asenkron ve bellek içi halka tamponlar (ring buffers) kullanarak çalıştığı için uygulama üzerindeki CPU ve gecikme etkisi %1-2'nin altındadır. Asıl maliyet CPU değil, ağ trafiği ve disk depolama maliyetidir. Saniyede 20.000 istek alan bir sistemde her isteğin tüm Span'larını diske yazmak terabaytlarca veri üretir. Bu nedenle canlı ortamda Tail-Based Sampling (Kuyruk Tabanlı Örnekleme) kullanılır: Hata alan (HTTP 4xx/5xx) ve yavaş çalışan (örneğin >500ms) isteklerin %100'ü kaydedilirken, normal ve hızlı çalışan başarılı isteklerin yalnızca %1 ila %5'i örneklenerek hem performans hem bütçe korunur.

4. ELK (Elasticsearch, Logstash, Kibana) yığını mı yoksa Grafana PLG (Promtail/Alloy, Loki, Grafana) yığını mı tercih edilmeli?

Eğer log metinlerinin içindeki her bir kelime üzerinde karmaşık tam metin aramaları (full-text search) ve ağır analitik agregasyonlar yapmanız gerekiyorsa Elasticsearch / OpenSearch çok güçlüdür ancak yüksek RAM, disk ve küme yönetim maliyeti vardır. Eğer Kubernetes ortamındaysanız, logları servis/pod/ortam etiketleriyle filtreleyip TraceID üzerinden nokta atışı incelemek istiyorsanız ve Prometheus/Grafana ile tek ekranda düşük maliyetli bir yapı arıyorsanız Grafana Loki çok daha hafif, ekonomik ve modern bir alternatiftir.

5. SLA, SLO ve SLI kavramları gözlemlenebilirlikte ne anlama gelir?

SLI (Service Level Indicator - Hizmet Seviyesi Göstergesi): Ölçtüğünüz gerçek metriktir (Örn: Son 30 günde başarılı ve 200ms altında yanıtlanan HTTP isteklerinin oranı = %99.94). SLO (Service Level Objective - Hizmet Seviyesi Hedefi): Mühendislik ekibinin kendine koyduğu iç hedeftir (Örn: SLI değerimiz %99.9'un altına düşmemelidir). Geriye kalan %0.1'lik dilim (ayda 43.2 dakika) ekibin Hata Bütçesidir (Error Budget); yeni özellik çıkarken yapılan riskli denemeler bu bütçeden harcar. SLA (Service Level Agreement - Hizmet Seviyesi Sözleşmesi) ise müşterilerle imzalanan hukuki ve finansal sözleşmedir (Örn: Erişilebilirlik %99.5'in altına düşerse müşteriye faturanın %10'u iade edilir).

Paylaş

Yozel

Codex haberleri en az iki bağımsız kaynakla doğrulanır; düzeltmeler yazının altında tarih ve saatle belirtilir. Yayın ilkelerimiz