dağıtık izleme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
dağıtık izleme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

13 Aralık 2025 Cumartesi

OpenTelemetry ile Mikroservislerde Dağıtık İzleme: Grafana Tempo ve Loki ile Uçtan Uca Kılavuz

Giriş

Mikroservis mimarisine geçtikçe uygulamaların davranışını anlamak ve sorunları hızla tespit etmek, basit log takibinin çok ötesine geçmeyi gerektirir. OpenTelemetry (OTel), ölçümleme (metrics), izleme (traces) ve günlük (logs) verilerini satıcıdan bağımsız bir standartla üretip toplamanıza izin veren modern bir çatı sunar. Bu yazıda, OpenTelemetry ile Node.js ve Python (FastAPI) servislerinin enstrümantasyonunu kavramsal olarak ele alacak, verileri Grafana Tempo (tracing) ve Loki (logging) ile toplayıp Grafana’da görselleştirmenin pratik adımlarını anlatacağım.

Mimari: Hangi bileşenler bir araya geliyor?

OpenTelemetry iki ana katmandan oluşur: uygulama içine eklediğiniz SDK/Enstrümantasyon katmanı ve veriyi toplayıp yöneten Collector. Uygulamalarınız OTLP protokolü üzerinden Collector’a veri gönderir; Collector da bu veriyi işleyip farklı hedeflere (Tempo, Loki, Prometheus, vs.) dağıtır. Bu yapının avantajı, uygulama kodunuza dokunmadan hedefleri, örneğin Jaeger’den Tempo’ya veya bir APM’e, değiştirebilmenizdir.

Bu kılavuzda şu akışı hedefliyoruz: Uygulamalar (Node.js/FastAPI) → OTLP (gRPC/HTTP) → OTel Collector → Tempo (traces) + Loki (logs) + Prometheus (metrics, opsiyonel) → Grafana ile görselleştirme.

Collector: Konfigürasyon mantığı

Collector konfigürasyonu üç ana bloktan oluşur: receivers (hangi protokolden veri alacağını belirtir, örn. otlp), processors (batch, attributes, memory_limiter gibi akış içi işlemler), exporters (veriyi nereye göndereceği, örn. tempo/loki). Tipik bir senaryoda, otlp receiver’dan gelen tüm izleri batch işlemcisinden geçirir, servis adı gibi resource etiketleri ekler ve tempo exporter’a yönlendirirsiniz. Loglar için benzer akış loki exporter’a gider. Metrics verisini kullanacaksanız prometheus veya otlp exporter ekleyebilirsiniz.

Üretimde şunları eklemek iyi bir pratiktir: memory_limiter (Collector’ın stabil kalması için), batch (veri paketleme ve throughput optimizasyonu), tail_sampling (yüksek trafik altında daha anlamlı izleri seçmek için kuyruk sonu örnekleme), attributes/resource (ortam, sürüm, ekip etiketleri).

Uygulama tarafı: Node.js servisini enstrümante etmek

Node.js tarafında çekirdek bileşenler: @opentelemetry/sdk-node, otomatik enstrümantasyon paketleri (HTTP, Express, MySQL/Postgres istemcileri vb.) ve OTLP exporter. Amaç; servisiniz başlarken bir tracer sağlayıcısı başlatmak, service.name, deployment.environment, service.version gibi resource etiketlerini tanımlamak ve Collector’a OTLP üzerinden veri göndermektir. Bağlantı için OTEL_EXPORTER_OTLP_ENDPOINT gibi çevre değişkenlerini kullanabilirsiniz. Üretimde gRPC tercih etmek genellikle daha performanslıdır.

Log korelasyonu için Node.js logger’ınız (ör. pino veya winston) ile trace_id ve span_id alanlarını yapılandırılmış loglara enjekte edin. Böylece Grafana’da bir trace’i incelerken ilgili loglara tek tıkla geçebilirsiniz. Eğer logs sinyalini de OTel üzerinden gönderecekseniz OTEL_LOGS_EXPORTER=otlp ve Collector’da loki exporter’ı etkinleştirerek aynı akış içinde korelasyon sağlayabilirsiniz.

Uygulama tarafı: Python FastAPI servisinde OTel

Python’da opentelemetry-sdk, opentelemetry-instrumentation-fastapi ve opentelemetry-exporter-otlp paketleriyle hızlıca başlarsınız. Çoğu durumda opentelemetry-instrument komutu ile otomatik enstrümantasyon yeterli olur. Yine OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_RESOURCE_ATTRIBUTES (örn. deployment.environment=prod) gibi değişkenlerle konfigürasyon yapın. Asenkron çağrılarda bağlamın (context) düzgün taşındığından emin olmak için FastAPI ve HTTPX/Requests enstrümantasyonlarının etkin olduğuna dikkat edin.

Log korelasyonunda Python logging veya structlog ile trace_id’yi log kaydına dahil ederek Loki tarafında aynı etiketlerle sorgulanabilir hale getirin. Bu, “Trace → İlgili logları göster” yolculuğunu saniyelere indirir.

Grafana: Tempo ve Loki ile görselleştirme

Grafana’da veri kaynakları olarak Tempo ve Loki’yi ekleyin. Tracing için Tempo Explore sekmesinde service.name veya http.method, http.route gibi etiketlerle arama yapabilirsiniz. Eğer Collector’da exemplar desteğini ve histogram metriklerini açtıysanız, metrik panellerinde örnek izlere (trace exemplars) tıklayarak doğrudan ilgili trace’e atlayabilirsiniz.

Loki’de, log etiketlerinizi (level, service, env gibi) sade ve anlamlı tutun. Trace kimlikleri log mesajlarına etiketsiz gömülmek yerine alan olarak eklenirse sorgu performansı ve filtreleme kolaylaşır. Amacınız; “Belirli bir isteğin izini aç, aynı trace_id ile logları getir, botleneck’i gör” akışını akıcı hale getirmektir.

Gelişmiş konular: Örnekleme, maliyet ve güvenlik

Örnekleme (sampling) stratejisi maliyet ve görünürlük dengesini belirler. Giriş seviyesinde head-based (SDK tarafında sabit oranlı) örnekleme iş görür; ileri seviye üretim senaryolarında tail-based (Collector içinde karar veren), hata veya yüksek gecikmeli izlere öncelik veren kurallarla çok daha anlamlı veri tutulur. Örneğin “5xx veya p95 gecikmesi yüksek istekleri sakla, diğerlerini %5 örnekle.”

Maliyet açısından batch işlemcilerini, gzip sıkıştırmayı, histogram metriklerini (DDSketch/OTLP temporalları) ve yüksek kardinaliteli etiketlerden kaçınmayı düşünün. Güvenlik tarafında ise PII içeren alanları Collector’da attributes/transform işlemcileriyle maskeleme veya atma kuralları tanımlayarak uyumluluğu sağlayın.

Sorun giderme ve ipuçları

Çok sık görülen problem, Collector veya uygulama tarafında OTLP uç noktasının hatalı olmasıdır. Sağlık kontrolleri ve debug logları ile endpoint’in erişilebilir olduğundan emin olun. Trace zincirinin kopması genellikle bağlam yayılımı (W3C traceparent) eksikliğinden kaynaklanır; gateway/ingress, mesaj kuyrukları ve aracı servislerde propagation başlıklarını ilettiğinizden emin olun. Son olarak, container’larda saat senkronizasyonu (NTP) bozuksa iz süreleri anlamsız görünür; zaman senkronizasyonunu mutlaka doğrulayın.

Sonuç

OpenTelemetry; iz, metrik ve logları ortak bir çatı altında toplayarak mikroservislerinizi gözlemlenebilir kılar. Collector ile satıcı bağımsız mimari kurabilir, Tempo ve Loki ile uygun maliyetli ve güçlü bir görünürlük katmanı elde edebilirsiniz. Node.js ve FastAPI örnekleri üzerinden özetlediğimiz yaklaşım; üretimde örnekleme, maskeleme ve korelasyon stratejileriyle birleştirildiğinde, kök neden analizi ve performans iyileştirmelerini ciddi biçimde hızlandıracaktır.

5 Kasım 2025 Çarşamba

OpenTelemetry ile Node.js Uygulamalarında Dağıtık İzleme: OTLP, Grafana Tempo ve Prometheus Entegrasyonu

OpenTelemetry Nedir ve Neden Önemli?

Modern mikroservis mimarilerinde tek bir isteğin birçok servis, kuyruk ve veri deposu üzerinden akması sıradan bir durum haline geldi. Bu akıştaki gecikmeleri, hataları ve dar boğazları anlamanın en güvenilir yolu, dağıtık izleme (distributed tracing), metrik ve log verilerini bir arada toplayıp ilişkilendirmektir. OpenTelemetry (OTel), bu ihtiyacı standartlaştıran açık kaynak bir çatı sunar. Node.js projelerinde OTel kullanarak HTTP isteklerini, veritabanı çağrılarını ve iç fonksiyonlarınızı otomatik veya manuel olarak izleyebilir, verileri OTLP üzerinden Grafana Tempo ve Prometheus gibi sistemlere aktarabilirsiniz.

Mimari: SDK, Collector ve Gözlemleme Katmanı

Basit ve güvenilir bir kurulum için üç katman önerilir: (1) Uygulama içinde @opentelemetry/sdk-node ve otomatik enstrümantasyon paketleri çalışır. (2) Veriler OTLP ile OpenTelemetry Collector’a gönderilir. (3) Collector, gelen trace’leri Tempo’ya, metric’leri Prometheus’a, tercihen log’ları da Loki’ye yönlendirir. Böylece uygulama sadece bir hedefi bilir ve detayları Collector yönetir; yapılandırma değişiklikleri için uygulamayı yeniden dağıtmanız gerekmez.

Ön Koşullar ve Temel Kurulum

- Node.js 18+ önerilir, çünkü AsyncLocalStorage ile bağlam yayılımı daha stabil ve hızlıdır. Paket yöneticisi olarak npm, pnpm ya da yarn kullanabilirsiniz.

- Projenizde hizmet adını ve ortamı belirlemek için şu ortam değişkenlerini ayarlayın: OTEL_SERVICE_NAME, OTEL_RESOURCE_ATTRIBUTES=deployment.environment=prod. OTLP hedefi için Collector URL’niz genelde http://otel-collector:4318 (HTTP) veya 4317 (gRPC) olacaktır.

- OTel’i uygulamanın en erken aşamasında, sunucu başlatılmadan önce başlatın. Örneğin tracing.js dosyanızı ilk import eden dosya yapın; aksi halde bazı framework etkinlikleri enstrümante edilemez.

Otomatik ve Manuel Enstrümantasyon

Node.js tarafında @opentelemetry/auto-instrumentations-node HTTP, gRPC, Express, Fastify, MySQL, PostgreSQL, Redis gibi popüler bileşenleri otomatik izler. Bu sayede hiçbir kod yazmadan gelen istekler, giden HTTP çağrıları ve DB sorguları için span’ler oluşturulur. Kritik işlevlerinizde daha detaylı görünürlük istiyorsanız manuel enstrümantasyonla özel span’ler açıp önemli değişkenleri attribute olarak ekleyebilirsiniz. Örneğin sipariş tutarı, sepet boyutu veya kampanya kodu gibi iş metriklerini PII içermeyecek şekilde iliştirmek, kök nedeni çözmede büyük avantaj sağlar.

Örnek Yapılandırma Prensipleri

- Sampler: Üretimde yüzde 100 örnekleme pahalı olabilir. ParentBasedTraceIdRatio gibi oran bazlı sampler kullanın; giriş noktalarında yüzde 5-10, hata kodlarında ise koşullu olarak yüzde 100 örnekleme tercih edebilirsiniz.

- Propagator: Varsayılan W3C Trace Context yeterlidir. Hizmet zincirindeki tüm servislerin aynı propagatörü kullanması span bağlarının korunmasını sağlar.

- Resource Nitelikleri: service.name, service.version, deployment.environment, cloud.region gibi alanları doldurun. Sürüm numarası (örn. git SHA) hata takibinde altın değerindedir.

- OTLP Exporter: HTTP veya gRPC kullanılabilir. Kurumsal ağlarda HTTP genellikle daha sorunsuzdur. Timeouts ve yeniden deneme ayarlarını Collector’a bırakmak, uygulama üzerinde yükü azaltır.

OpenTelemetry Collector İpuçları

Collector, performans ve güvenilirlik için kritik bir bileşendir. Girişte otlp receiver, ortada batch ve attributes processor’ları, çıkışta tempo ve prometheus exporter’ları kullanılır. Batch, küçük span’lerin birikerek verimli gönderilmesini sağlar. Attributes processor ile gereksiz ya da hassas alanları (örn. e-posta, telefon) maskeleyebilir veya kaldırabilirsiniz. Tempo tarafında multi-tenant ihtiyaç varsa tenant başına service.name veya header tabanlı ayırma stratejisi kullanın.

Grafana Tempo ve Prometheus Entegrasyonu

Tempo, span verilerini ölçeklenebilir şekilde tutar ve Grafana ile mükemmel entegredir. Grafana’da “Explore” bölümünden trace ID ile arama yapabilir, isteklerin gecikme dağılımını görebilir ve sorunlu hizmeti hızlıca belirleyebilirsiniz. Metrikler için Prometheus, Node.js ve Collector’dan gelen ölçümleri toplayarak p95/p99 gecikme, hata oranı ve istek hacmini panolarda görselleştirir. Traces ile metrics arasında exemplar köprüleri kurduğunuzda, grafikteki bir pik noktasından ilgili trace’e tek tıkla bağlanabilirsiniz.

Performans, Maliyet ve Güvenlik

- Overhead: Otomatik enstrümantasyonun CPU/GC etkisi genellikle düşüktür, ancak sıcak yol (hot path) fonksiyonlarda manuel span açmayı sınırlayın. Toplayıcıda batch boyutlarını ve flush aralıklarını gözden geçirerek ağ trafiğini optimize edin.

- Maliyet: Oran bazlı örnekleme ve hata odaklı dinamik örnekleme ile depolama ve sorgu maliyetlerini kontrol altında tutun. Geliştirme ve staging ortamlarında daha yüksek oran, üretimde daha düşük oran kullanmak iyi bir dengedir.

- Gizlilik: PII ve gizli anahtarları span attribute’larına koymayın. Collector’da maskeleme kuralları ekleyin. Log ve trace korelasyonu yaparken veri minimizasyonuna dikkat edin.

Hata Ayıklama ve Yaygın Sorunlar

- Bağlam Kaybı: Özellikle eski Promise zincirlerinde veya üçüncü taraf kütüphanelerde bağlam kaybı olabilir. Node 18+ ve AsyncLocalStorage ile bu sorun büyük ölçüde azalır. Framework düzeyinde middleware sırasını kontrol edin.

- Eksik Span’ler: Uygulamada OTel başlatma dosyasının en önce import edildiğinden emin olun. Sunucu başlatma komutunuzda -r ./tracing.js gibi bir preload yaklaşımı kullanmak güvenilirdir.

- Gönderim Hataları: Collector’a ulaşamıyorsanız firewall veya servis keşfi sorunlarını kontrol edin. OTLP gRPC ile MTLS yapılandırıyorsanız sertifika yollarını ve SNI ayarlarını doğrulayın.

Sonuç

OpenTelemetry, Node.js uygulamalarınızda uçtan uca görünürlük sağlayarak sorun tespiti ve performans optimizasyonunu hızlandırır. Uygulama içinde hafif bir SDK, merkezde güçlü bir Collector ve gözlemleme katmanında Tempo/Prometheus kombinasyonu ile maliyet-etkin, taşınabilir ve geleceğe dönük bir çözüm elde edersiniz. Doğru örnekleme, sağlam kaynak nitelikleri ve sıkı gizlilik politikaları ile ekipler hem geliştirici deneyimini hem de kullanıcı memnuniyetini anlamlı biçimde artırabilir.

29 Ekim 2025 Çarşamba

OpenTelemetry ile Node.js Mikroservislerde Uçtan Uca Gözlemlenebilirlik: Adım Adım Kurulum

OpenTelemetry Nedir ve Neden Önemlidir?

OpenTelemetry (OTel), uygulamalarınızdan metrik, iz (trace) ve log verilerini standart bir formatla toplayıp farklı arka uç (backend) sistemlerine göndermenizi sağlayan, CNCF çatısı altındaki açık kaynak bir çatı projedir. Mikroservis mimarilerinde bir isteğin hangi servislerde gezdiğini, nerede yavaşladığını veya hata verdiğini anlamak için dağıtık izleme, performans metrikleri ve log korelasyonu kritik öneme sahiptir. OTel; SDK’lar, otomatik enstrümantasyon modülleri, Collector (aracı) ve OTLP adlı açık protokol ile bu süreci basitleştirir.

Hedef Mimari ve Bileşenler

Bu makalede bir Node.js (Express) servisinden izleri OpenTelemetry Collector’a, oradan da Grafana Tempo’ya taşıyacağız. Görselleştirme için Grafana kullanılacak. Metrikler için Prometheus veya Grafana Cloud tercih edilebilir; ancak odak noktamız uçtan uca izleme (tracing) kurulumu olacak. Basitçe akış şöyle: Uygulama (OTel SDK) → OTLP (gRPC) → OTel Collector → Tempo → Grafana.

Ön Koşullar

Node.js 18+ sürümü, Docker ve Docker Compose kurulu olmalı. Yerel ortamda çalışıyorsanız 4317 (OTLP gRPC) ve 3000 (Grafana) portlarının boş olduğundan emin olun. Örnekler Linux ve macOS için benzer; Windows’ta da WSL ile rahatça yürütülebilir.

1) Node.js Projesini Hazırlama

Önce basit bir Express API oluşturalım ve OpenTelemetry paketlerini ekleyelim. Yeni bir klasör açın ve terminalde şu komutları çalıştırın: npm init -y ardından npm i express @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/resources. Bu paketler sırasıyla temel OTel SDK, otomatik enstrümantasyon, OTLP gRPC exporter ve kaynak (service.name vb.) tanımları için gereklidir.

2) OpenTelemetry Yapılandırması (tracing.js)

Projenizin köküne tracing.js adlı bir dosya ekleyin ve aşağıdaki içeriği yerleştirin. Bu dosya Collector’a giden OTLP gRPC bağlantısını kurar ve otomatik enstrümantasyonu aktif eder: const { NodeSDK } = require('@opentelemetry/sdk-node'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { Resource } = require('@opentelemetry/resources'); const exporter = new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4317' }); const sdk = new NodeSDK({ resource: new Resource({ 'service.name': process.env.OTEL_SERVICE_NAME || 'orders-api', 'service.namespace': 'example', }), traceExporter: exporter, instrumentations: [getNodeAutoInstrumentations()], }); sdk.start().then(() => console.log('OTel tracing started')).catch(err => console.error(err)); process.on('SIGTERM', () => sdk.shutdown());

3) Express Uygulaması (app.js)

Express sunucusunu başlatmadan önce tracing’i import etmek önemlidir; aksi halde otomatik enstrümantasyon bazı modülleri kaçırabilir. app.js dosyası için örnek: require('./tracing'); const express = require('express'); const app = express(); app.get('/health', (req, res) => res.send('ok')); app.get('/orders/:id', async (req, res) => { // İş mantığı simülasyonu await new Promise(r => setTimeout(r, 50)); res.json({ id: req.params.id, status: 'ready' }); }); const port = process.env.PORT || 3001; app.listen(port, () => console.log('API listening on ' + port));

4) OpenTelemetry Collector ve Tempo

Collector, üretim ortamlarında veriyi merkezileştirip birden fazla hedefe yönlendirmek için idealdir. Aşağıdaki basit collector.yaml Tempo’ya iz aktarmaya yeter. Docker ile kullanırken dosyayı aynı klasöre koyun ve mount edin: receivers: otlp: protocols: grpc: exporters: otlp: endpoint: tempo:4317 tls: insecure: true service: pipelines: traces: receivers: [otlp] exporters: [otlp] Bu yapı, Collector’ın 4317 portundan OTLP gRPC ile aldığı izleri, aynı docker ağı içindeki tempo servisine yine OTLP ile iletir.

Basit bir docker-compose.yaml ile Tempo ve Collector’ı ayağa kaldırabilirsiniz. Özetle, otel-collector servisini otel/opentelemetry-collector:latest imajı ile çalıştırıp 4317 portunu publish edin; tempo için grafana/tempo imajını kullanın. Grafana’yı grafana/grafana ile 3000 portunda başlatın. Grafana içinden “Add data source” menüsünde Tempo’yu ekleyip Collector/Tempo adresini işaret edin.

5) Test ve Doğrulama

Node.js uygulamanızı node app.js ile başlatın. Ardından birkaç istek atın: curl http://localhost:3001/orders/123. Grafana’da Tempo veri kaynağını açıp “Explore” sekmesinde hizmet adınızla (ör. orders-api) arama yapın. Trace grafında isteklerin gecikme dağılımını, otomatik enstrümantasyon sayesinde HTTP client/server span’lerini ve hata durumlarını görebilirsiniz. Trace ayrıntılarında attributes altında http.method, http.route gibi alanlar hazır gelir.

Gelişmiş İpuçları ve En İyi Uygulamalar

Üretimde örnekleme (sampling) oranını dikkatle seçin. Başlangıç için parentbased_traceidratio ile %5–10 iyi bir denge sağlar. Node tarafında OTEL_TRACES_SAMPLER=parentbased_traceidratio ve OTEL_TRACES_SAMPLER_ARG=0.1 gibi değişkenler kullanabilirsiniz. Ağ ve depolama maliyetlerini kontrol altında tutmak için gereksiz etiketleri (attributes) azaltın, sadece iş değeri yüksek etiketleri aktarın.

Servisler arası çağrılarda bağlam aktarımı (context propagation) hayati önem taşır. Varsayılan W3C Trace Context çoğu senaryo için yeterlidir. Gateway veya API proxy katmanınız varsa, traceparent ve tracestate başlıklarının bozulmadığından emin olun. Mikroservis zincirlerinde bu başlıkların taşınmaması, izlerin kopuk görünmesine neden olur.

Metrik ve log’larla korelasyon kurmak için aynı resource attributes değerlerini (ör. service.name, service.namespace, deployment.environment) hem uygulama hem Collector tarafında tutarlı kullanın. Log yönünde OTel Logger ile Grafana Loki entegrasyonu, bir trace ID’sinden ilgili log satırına tek tıkla geçiş imkanı verir. Bu, MTTR’ı ciddi biçimde düşürür.

Güvenlik açısından üretimde OTLP trafiğini TLS ile şifreleyin ve Collector’ı egress katmanı olarak konumlandırın. Kubernetes’te DaemonSet veya sidecar modeliyle dağıtım yapabilir, her node’da yerel Collector çalıştırarak ağ gecikmesini azaltabilirsiniz. SLO takibi için kritik endpoint’lerinizde özel span adları ve durum kodu etiketleri kullanmak; hata bütçesi yönetimi ve kök neden analizlerinde büyük kolaylık sağlar.

Sonuç

OpenTelemetry, Node.js mikroservislerinizde gözlemlenebilirliği standart, taşınabilir ve ölçeklenebilir hale getirir. Collector ve Tempo ile kuracağınız hafif mimari hem yerelde hem de bulutta hızlıca devreye alınabilir. Bu rehberle temel taşıyıcıları ayağa kaldırdıktan sonra, metrik ve log entegrasyonlarını ekleyerek tam üç sütunlu gözlemlenebilirlik elde edebilir, üretim ortamında güvenle iterasyon yapabilirsiniz.