Dağıtık İzleme (Distributed Tracing) Nedir?
Kısa tanım
Dağıtık izleme (distributed tracing), tek bir isteğin birden fazla servis, veritabanı ve kuyruk üzerinden geçerken izlediği yolu, her adımın süresiyle birlikte uçtan uca kaydeden tekniktir. Her adım bir span, bir isteğe ait tüm span'ler bir trace oluşturur. İz kimliği servisler arasında W3C Trace Context gibi standart başlıklarla taşınır; böylece yavaşlığın veya hatanın hangi halkada çıktığı görülür.
Diğer adları: distributed tracing, tracing, trace, span, iz sürme, traceparent

Loglar neden yetmiyor?
Tek bir uygulamada yavaş bir isteği bulmak görece kolaydır. Ama bir ödeme isteği önce API ağ geçidine, oradan sipariş servisine, ödeme servisine, bir dış bankaya ve bir kuyruğa uğruyorsa, her servisin kendi logu hikâyenin yalnızca bir parçasını anlatır. Hangi satırın hangi isteğe ait olduğunu, toplam 820 milisaniyenin nerede harcandığını loglardan birleştirmek saatler alabilir. Dağıtık izleme, bu parçaları ortak bir kimlikle birbirine bağlayıp tek bir zaman çizelgesi olarak gösterir. Mikroservis mimarilerinde hata ayıklamanın temel araçlarından biri bu yüzdendir.
Trace ve span: isteğin ağacı
Trace, bir isteğin baştan sona tüm yolculuğudur. Span ise bu yolculuktaki tek bir iş birimidir: bir HTTP çağrısı, bir veritabanı sorgusu, bir kuyruğa mesaj bırakma. Her span'in başlangıç zamanı, süresi, durumu ve bir üst span'i vardır; bu sayede span'ler bir ağaç oluşturur. İzleme araçları bu ağacı “şelale” görünümünde çizer:
trace 4bf92f35… POST /odeme 820 ms
└─ api-gateway 815 ms
├─ siparis-servisi SELECT siparisler 38 ms
├─ odeme-servisi POST banka.example/charge 690 ms ← darboğaz
└─ siparis-servisi publish odeme.tamamlandi 12 msSpan'lere eklenen öznitelikler (HTTP yöntemi, durum kodu, veritabanı adı, müşteri segmenti) sorgulamayı mümkün kılar: “Son bir saatte 500 ms'yi aşan ödeme isteklerinde hangi span en uzun sürdü?” Bu, toplam gecikmeyi bileşenlerine ayırmanın en doğrudan yoludur.
Bağlam yayılımı ve traceparent başlığı
Bir servisin çağırdığı diğer servise “bu istek şu trace'in parçası” demesi gerekir. Buna bağlam yayılımı (context propagation) denir ve HTTP'de bir HTTP başlığı ile yapılır. 2021'de W3C Recommendation olarak yayımlanan Trace Context standardı bu başlığın biçimini tanımlar:
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ │ │ └ bayraklar (01 = örneklendi)
│ │ └ üst span kimliği (16 hex)
│ └ trace kimliği (32 hex)
└ sürümAynı standarttaki tracestate başlığı, farklı izleme sağlayıcılarının kendi ek bilgilerini taşımasına izin verir. Ortak bir standart sayesinde farklı dillerde yazılmış ve farklı araçlarla enstrümante edilmiş servisler aynı trace'e katkı yapabilir. Asenkron akışlarda bağlam, mesaj kuyruğuna bırakılan mesajın başlıklarına eklenir; böylece tüketicinin yaptığı iş de aynı trace'te görünür.
Örnekleme: her isteği kaydetmek gerekmez
Yoğun bir sistemde tüm isteklerin tüm span'lerini saklamak pahalıdır. Bu yüzden trace'ler örneklenir:
- Baştan örnekleme (head-based): Karar isteğin başında verilir, örneğin isteklerin %5'i kaydedilir. Ucuz ve basittir ama nadir görülen hatalı veya yavaş istekleri kaçırabilir. Karar,
traceparentiçindeki bayrakla sonraki servislere iletilir. - Sondan örnekleme (tail-based): Trace tamamlandıktan sonra karar verilir; hata içeren veya belirli bir süreyi aşan trace'lerin hepsi tutulur, sıradan olanların küçük bir kısmı. Daha değerli veri üretir ama tüm span'lerin geçici olarak toplanmasını gerektirir.
Log ve metriklerle birlikte kullanmak
Trace kimliği her log satırına yazıldığında, şelale görünümündeki bir span'den o adımın loglarına doğrudan geçilebilir. Metrik panosunda görülen bir gecikme sıçramasından örnek trace'lere inmek de aynı bağlantıya dayanır; bu üçlü, gözlemlenebilirliğin omurgasıdır. Uygulamada enstrümantasyon çoğunlukla OpenTelemetry kütüphaneleriyle yapılır: HTTP sunucuları, istemciler ve veritabanı sürücüleri için otomatik enstrümantasyon, span'lerin büyük bölümünü kod yazmadan üretir. Toplanan veriler Jaeger veya Zipkin gibi açık kaynak araçlara ya da ticari bir platforma gönderilebilir.

