OpenTelemetry etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
OpenTelemetry 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.

10 Kasım 2025 Pazartesi

OpenTelemetry ile Node.js Uygulamasını İzleme: OTLP ve Jaeger ile 15 Dakikada Kurulum

OpenTelemetry nedir ve neden önemli?

Modern mikroservislerin başarısı; gecikme, hata oranı ve bağımlılık zincirini anlık olarak görebilmenize bağlıdır. OpenTelemetry (OTel), kodunuzu satıcı bağımsız bir şekilde enstrümante ederek traces, metrics ve logs toplamanıza izin veren açık bir standarttır. Bu sayede bugün Jaeger kullanırken, yarın Grafana Tempo veya başka bir araca geçmek zorunda kalsanız bile aynı veri modelini korursunuz.

Bu rehberde, Node.js tabanlı bir servisi OTLP (OpenTelemetry Protocol) ile enstrümante edip, yerelde Jaeger All-in-One üzerinde izleri görüntüleyeceğiz. Üretimde Tempo, Honeycomb, Datadog gibi hedeflere geçiş de aynı mantıkla yapılabilir.

Gereksinimler

- Node.js 18+
- Docker (opsiyonel ama tavsiye edilir)
- Terminal ve temel npm bilgisi

Adım 1: Jaeger All-in-One ile hızlı izleme ortamı

Jaeger All-in-One, lokalde hızlı deneme yapmak için idealdir. OTLP alıcısı varsayılan olarak kapalı gelir; bu yüzden aşağıdaki komutta onu açıyoruz:

docker run -d --name jaeger -e COLLECTOR_OTLP_ENABLED=true -p 16686:16686 -p 4317:4317 -p 4318:4318 jaegertracing/all-in-one:1.57

Bu komut ile:
- 16686 portundan Jaeger UI’ya erişirsiniz.
- 4317 (gRPC) ve 4318 (HTTP) portlarından OTLP verisi kabul edilir.
Tarayıcıdan http://localhost:16686 adresine gidip arayüzün geldiğini doğrulayın.

Adım 2: Node.js uygulamasını enstrümante etme

Yeni bir proje oluşturun ve gerekli paketleri kurun:

mkdir otel-node-demo && cd otel-node-demo
npm init -y
npm i express
npm i @opentelemetry/sdk-node @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http

Proje kökünde tracing.js dosyası oluşturun ve aşağıdaki minimal yapılandırmayı ekleyin:

const { NodeSDK } = require('@opentelemetry/sdk-node');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');

const exporter = new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces' });
const sdk = new NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'otel-node-demo',
  }),
  traceExporter: exporter,
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start().then(() => {
  process.on('SIGTERM', () => sdk.shutdown());
});

Basit bir Express sunucusu için app.js dosyasını ekleyin:

const express = require('express');
const app = express();
app.get('/hello', async (req, res) => {
  await new Promise(r => setTimeout(r, 50)); // Yapay gecikme
  res.json({ ok: true, ts: Date.now() });
});
app.listen(3000, () => console.log('API 3000 portunda'));

Uygulamayı enstrümantasyon ile birlikte çalıştırın:

node -r ./tracing.js app.js

Ardından birkaç istek atın:
curl http://localhost:3000/hello

Adım 3: İzleri Jaeger arayüzünde inceleme

Jaeger UI’da sol üstteki servis listesinden otel-node-demo’yu seçin ve Find Traces butonuna basın. Her HTTP isteği için birer trace oluştuğunu, otomatik enstrümantasyon sayesinde express, http gibi span’ların kendiliğinden toplandığını göreceksiniz. Gecikme (latency) dağılımı ve hatalı isteklerin oranı burada hızla görünür hale gelir.

Tempo mu, Jaeger mi?

Bu rehberde hızlı ilerlemek için Jaeger kullandık. Üretim ortamında Grafana Tempo, özellikle uzun saklama (S3/MinIO) ve Grafana ile sıkı entegrasyon avantajları sağlar. Node.js açısından fark yoktur; uygulama yine OTLP ile veri yollar. Sadece hedef uç nokta değişir. Örneğin Collector veya Agent üzerinden otlp exporter ile Tempo’nun 4317/4318 portlarına gönderebilirsiniz.

İpuçları ve en iyi uygulamalar

- Örnekleme (sampling): Varsayılan olarak oran %100 olabilir. Trafik yüksekse TRACE_SAMPLER=parentbased_traceidratio ve oran ayarlaması ile maliyeti düşürün.
- Dağıtık bağlam: Proksi veya API Gateway kullanıyorsanız traceparent başlıklarının korunduğundan emin olun. Aksi halde zincir kopar.
- Log korelasyonu: Pino/Winston logger’ınıza aktif trace ID’yi ekleyerek sorun giderme hızlanır. @opentelemetry/api içinden trace.getActiveSpan() ile ID alınabilir.
- Güvenlik: OTLP uç noktalarını sadece iç ağda açın ya da mTLS ile koruyun.
- Göç kolaylığı: Bugün Jaeger, yarın Tempo? Uygulama kodu değişmez; sadece uç nokta ve backend değişir. İşte OpenTelemetry’nin gücü budur.

Sonuç

OpenTelemetry ile Node.js servislerinizi dakikalar içinde gözlemlenebilir kılabilirsiniz. OTLP sayesinde backend bağımsız bir mimari kurar, yerelde Jaeger ile hızlıca dener, üretimde ise Tempo ve Grafana ile uçtan uca izlemeyi sürdürebilirsiniz. Bu yatırım, mikroservis karmaşıklığında hataları daha hızlı bulmanızı, performansı ölçmenizi ve son kullanıcı deneyimini iyileştirmenizi sağlar.

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.

25 Ekim 2025 Cumartesi

OpenTelemetry ile Node.js Mikroservislerinde Uçtan Uca İzleme: Adım Adım Kurulum ve İpuçları

Giriş

Mikroservis mimarisi yaygınlaştıkça, bir isteğin sistem içinde hangi servislerden geçtiğini net olarak görmek kritik hale geldi. Tam bu noktada OpenTelemetry (OTel), izleme (tracing), metrik ve log sinyallerini standart bir şekilde toplayıp farklı arka uçlara gönderebilmenizi sağlayan, satıcıdan bağımsız bir çatı sunuyor. Bu yazıda, Node.js tabanlı mikroservislerde OpenTelemetry ile uçtan uca izlemeyi nasıl kuracağınızı, OpenTelemetry Collector’ı nasıl konumlandıracağınızı ve Jaeger/Grafana gibi araçlarla nasıl görünürlük elde edeceğinizi adım adım anlatıyorum.

Neden OpenTelemetry?

OpenTelemetry; W3C TraceContext ile uyumlu bağlam taşıma, otomatik enstrümantasyon paketleri ve güçlü bir Collector katmanı sayesinde uygulamaya minimum müdahale ile geniş görünürlük sağlar. Tek bir SDK ile farklı hedeflere (Jaeger, Tempo, Zipkin, OTLP uyumlu APM’ler) veri gönderebilir, kolektör üzerinde örnekleme (sampling), maskeleme ve yönlendirme politikaları kurabilirsiniz. Özellikle ölçek büyüdüğünde, kolektör katmanında merkezi yönetim büyük avantaj sağlar.

Mimari ve Gereksinimler

Önerilen basit topoloji şu şekilde: Node.js servisleri OpenTelemetry SDK ile izleri OTLP (HTTP veya gRPC) üzerinden OpenTelemetry Collector’a yollar. Collector, gelen veriyi batch’ler ve seçilen bir arka uca (ör. Jaeger veya Grafana Tempo) aktarır. Görselleştirme için Jaeger UI veya Grafana kullanılabilir. Üretimde TLS ve kimlik doğrulama (ör. mTLS, token) eklemeniz güvenlik açısından önemlidir.

Adım 1: OpenTelemetry Collector Kurulumu

Collector’ı Docker veya Kubernetes üzerinde çalıştırabilirsiniz. Temel bir yapılandırmada otlp alıcısını (receiver) hem HTTP hem gRPC için etkinleştirir, batch işlemcisini performans için eklersiniz. Çıkış tarafında jaeger ya da otlp exporter ile Tempo/OTLP hedefinize gönderim yapabilirsiniz. Üretime geçerken limitler, kuyruklar ve hata tekrar denemeleri için memory_limiter ve retry işlemcilerini de eklemeniz önerilir.

Adım 2: Node.js Uygulamasında OpenTelemetry’yi Etkinleştirme

Node.js tarafında @opentelemetry/sdk-node ve @opentelemetry/auto-instrumentations-node paketleriyle hızlıca başlayabilirsiniz. Önerim, uygulama giriş noktasından önce çalışacak bir tracing-bootstrap dosyası oluşturmak ve süreç başında SDK’yı başlatmaktır. Exporter olarak @opentelemetry/exporter-trace-otlp-http veya gRPC sürümünü seçebilirsiniz. Çevresel değişkenlerle (OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, OTEL_TRACES_SAMPLER, OTEL_RESOURCE_ATTRIBUTES) yapılandırma esnekliğini koruyun. Örneğin servis adını, ortamı (prod/stage), sürümü ve k8s etiketlerini kaynak (resource) niteliklerine eklemek aramada büyük kolaylık sağlar.

Adım 3: Bağlam Taşıma ve Enstrümantasyon

Dağıtık izleme için en kritik konu, isteklerin bağlamının doğru taşınmasıdır. OpenTelemetry varsayılan olarak W3C TraceContext başlıklarını kullanır (traceparent, tracestate). HTTP istemcileriniz (axios, fetch, got) ve sunucu tarafı (Express, Fastify, NestJS) için otomatik enstrümantasyon paketlerini aktif ettiğinizde, gelen isteğin bağlamı çıkarılır ve giden isteklere eklenir. API ağ geçitleri, CDN’ler veya servis mesh bileşenleri (Envoy/Linkerd/Istio) üzerinde bu başlıkların korunmasını sağlayın.

Adım 4: Metrikler ve Loglar

İzler başlangıç için idealdir; ancak gecikme ve hata oranlarını anlık izlemek için metrikleri de açın. Node.js’te bir MeterProvider ile sayaç, histogram ve gözlemci ölçümlerini üretebilir, OTLP veya Prometheus’a gönderebilirsiniz. Log tarafında, uygulama loglarını bir log yönlendirici (örn. Promtail, Vector) üzerinden kolektöre veya doğrudan hedef sisteme iletmek pratik bir yaklaşımdır. İzlerle logları korele etmek için log satırına trace_id ve span_id eklemek altın değerdedir.

Adım 5: Görselleştirme ve Analiz

Jaeger ile başlangıç hızlıdır: Servis adınıza, işlem adlarına ve hata etiketlerine göre izleri filtreleyebilirsiniz. Grafana + Tempo kullanıyorsanız, izler ile metrikler arasında geçiş yaparak (exemplar’lar) sorunlu zaman dilimindeki istekleri yakalamak çok güçlü bir yöntemdir. Yavaş isteklerin hangi mikroserviste takıldığını, dış bağımlılıkların (veritabanı, cache, üçüncü parti API’ler) gecikmeye etkisini birkaç tıkla görürsünüz.

İleri Düzey: Sampling, Güvenlik ve Kubernetes

Üretimde her isteği izlemek pahalı olabilir. Başlangıçta parentbased_traceidratio ile yüzde bazlı head sampling kullanın; daha sonra Collector üzerinde tail_sampling ile hata kodlarına veya gecikmeye göre akıllı örnekleme kurun. Hassas verileri maskelemek için Collector’ın attributes işlemcisiyle veri temizleme ekleyin. Kubernetes’te resource algılayıcılarıyla pod/namespace etiketleri otomatik gelir; ayrıca auto-instrumentation için init container yaklaşımıyla uygulama imajlarınızı değiştirmeden OTel’i devreye alabilirsiniz.

Sorun Giderme İpuçları

İzler görünmüyorsa önce Collector loglarını kontrol edin; OTLP uç noktasına ulaşabildiğinizi ve doğru protokol (HTTP vs gRPC) kullandığınızı doğrulayın. Node.js tarafında SDK’yı uygulama kodundan önce başlattığınızdan emin olun. Reverse proxy veya API gateway APM başlıklarını siliyor olabilir; başlık geçiş kurallarını gözden geçirin. Gecikme yüksekse, Collector’da batch ayarlarını ve kuyruk limitlerini optimize edin.

Sonuç

OpenTelemetry, Node.js mikroservislerinizde uçtan uca görünürlük sağlayarak kök neden analizini hızlandırır, müşteri etkisini azaltır ve ekipler arası ortak bir gözlem dili sunar. Küçükten başlayın: Collector + izler + Jaeger, ardından metrikler, log korelasyonu ve akıllı örnekleme ile olgunlaştırın. Doğru etiketleme ve bağlam taşıma kurulduğunda, karmaşık bir dağıtık sistemde bile “ne, nerede, neden yavaş?” sorularının yanıtı birkaç dakika uzaklıkta olacaktır.

14 Ekim 2025 Salı

OpenTelemetry ile Mikroservislerde Dağıtık İzleme: Grafana Tempo ve OTEL Collector ile Hızlı Kurulum Rehberi

Giriş

Mikroservis mimarisine geçişle birlikte klasik log takibi, bir isteğin sistem içindeki yolculuğunu uçtan uca anlamak için yetersiz kalıyor. OpenTelemetry (OTel), uygulama metrikleri, loglar ve izleri (traces) için standartlaştırılmış bir yaklaşım sunarak bu boşluğu kapatıyor. Bu yazıda, Grafana Tempo ve OpenTelemetry Collector kullanarak 30 dakikada çalışır bir dağıtık izleme hattı kurmayı, uygulamaları enstrümante etmeyi ve üretime hazır ipuçlarını paylaşacağım.

Mimari ve Gereksinimler

Basit bir akış ile başlıyoruz: Uygulamalarınız OpenTelemetry SDK ile izleri üretir ve OTLP üzerinden OTel Collector’a gönderir. Collector, veriyi işleyip Tempo’ya aktarır. Görselleştirme için Grafana kullanırız. Aynı Collector hattına logları da bağlayabilir, korelasyon için traceID’yi loglara ekleyebilirsiniz.

Gereksinimler: Docker veya Kubernetes bilgisi, temel ağ/TLS kavrayışı ve uygulamalarınızda enstrümantasyon için Node.js/Java/Python’dan biri.

Adım 1: Uygulamanızda OpenTelemetry SDK’yı Etkinleştirin

Amaç, her servisin bir service.name etiketiyle izlerini göndermesi. Örnek olarak Node.js verelim. Kurulum:
npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-otlp-grpc
Basit bootstrap (otel.js) içinde şunları ayarlayın: hizmet adı, OTLP gRPC endpoint’i (collector:4317), Resource etiketleri (deployment.environment, service.version) ve BatchSpanProcessor. Uygulamayı bu bootstrap ile başlatın: node -r ./otel.js server.js.

Java (Spring Boot) tarafında opentelemetry-javaagent.jar ile kod değişikliği olmadan başlamak mümkün: java -javaagent:opentelemetry-javaagent.jar -Dotel.service.name=orders -Dotel.exporter.otlp.endpoint=http://collector:4318 -jar app.jar

Python (FastAPI) için benzer şekilde opentelemetry-distro ve otlp exporter kurup OTEL_EXPORTER_OTLP_ENDPOINT ve OTEL_SERVICE_NAME çevre değişkenlerini tanımlayabilirsiniz.

Adım 2: OpenTelemetry Collector Konfigürasyonu

Collector, veriyi merkezi olarak alır, zenginleştirir ve hedeflere yollar. Minimal bir topology şöyle olabilir:
- Receivers: otlp (grpc ve http),
- Processors: batch, attributes (ör. ortam bilgisi ekleme), tailsampling (isteğe bağlı),
- Exporters: otlp veya http tempo exporter (Grafana Tempo’ya),
- Extensions: health_check (durum kontrolü).

Basit bir YAML iskeleti (satır sonları korunarak kullanın):
receivers:
  otlp:
    protocols:
      grpc:
      http:
processors:
  batch:
exporters:
  otlp:
    endpoint: http://tempo:4317
    tls:
      insecure: true
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]

Adım 3: Tempo ve Grafana’yı Hızlıca Ayağa Kaldırın

Docker Compose ile tek makinede deneme yapmak kolaydır. Örnek içerik:
version: "3.9"
services:
  tempo:
    image: grafana/tempo:latest
    ports: ["3200:3200", "4317:4317"]
  otel-collector:
    image: otel/opentelemetry-collector:latest
    ports: ["4317:4317", "4318:4318"]
    volumes: ["./otel-collector.yaml:/etc/otelcol/config.yaml"]
    command: ["--config=/etc/otelcol/config.yaml"]
  grafana:
    image: grafana/grafana:latest
    ports: ["3000:3000"]

Grafana arayüzüne (http://localhost:3000) girip Tempo’yu veri kaynağı olarak ekleyin. Sonrasında Explorations bölümünden trace araması yapabilir, service.name, http.target veya status.code gibi etiketlerle filtreleyebilirsiniz.

Adım 4: Örnek İşlem ve Trace Korelasyonu

Bir müşteri sipariş akışı düşünelim: api-gateway → orders → payments → notifications. Gateway, gelen isteğe traceparent üretir. Orders servisi DB işlemini bir span olarak işaretler; payments servisi harici ödeme sağlayıcısına giden HTTP çağrısını ayrı bir span olarak ekler. Bildirim servisi e-posta/SMS entegrasyonunu başka bir span’a yazar. Grafana Tempo üzerinde tek bir TraceID ile tüm zinciri adım adım görebilirsiniz.

Log korelasyonu için, uygulamanızın log satırlarına trace_id ve span_id ekleyin. Böylece bir hata logundan direkt ilgili trace’e atlayarak kök neden analizi (RCA) yapabilirsiniz.

Adım 5: Örnekleme (Sampling) ve Maliyet Kontrolü

Üretimde her isteği izlemek pahalı olabilir. Başlangıç için ParentBased + TraceIdRatio sampling uygundur: giriş isteklerinin %5’i örneklenir, bu karar alt çağrılara taşınır. Trafiğiniz zirvede arttığında Collector’ın tail sampling özelliğini kullanarak hatalı veya yavaş istekleri önceliklendirebilirsiniz (ör. duration > 500ms veya status.code != OK olanlar).

Güvenlik ve Uyum

OTLP trafiğini TLS ile koruyun. gRPC için 4317, HTTP için 4318 portlarını güvenlik gruplarıyla sınırlandırın. İzlerde kişisel veriyi (PII) tutmaktan kaçının; attributes processor ile maskeleme yapabilir veya whitelisting uygulayabilirsiniz. Harici servislere giden isteklerde başlıkları (headers) kayda geçirmeden önce ayıklayın.

Kubernetes’te Çalıştırma İpuçları

Collector’ı DaemonSet (node başına agent) veya Deployment (merkezi gateway) olarak çalıştırabilirsiniz. Latensi duyarlı servisler için aynı node’daki agent’a göndermek, gecikmeyi düşürür. resource etiketlerine kubernetes.namespace.name ve pod.name ekleyerek grafana panellerinde anlamlı filtreler elde edin.

Hata Ayıklama ve Ölçüm

Collector’ın health endpoint’ini izleyin, span queue doluluklarını kontrol edin. Uygulama tarafında enstrümantasyonun devreye girip girmediğini anlamak için başlangıçta console exporter ile kısa süreli test yapabilirsiniz. Grafana’da Exemplars kullanarak metrikteki bir anomaliyi doğrudan ilgili trace’e bağlamak, teşhisi hızlandırır.

Sonuç

OpenTelemetry + Tempo + Collector üçlüsü, mikroservislerde uçtan uca görünürlük sağlamak için güçlü ve esnek bir temel sunuyor. İlk kurulum basittir; ilerleyen aşamalarda örnekleme, maskeleme ve korelasyon stratejileri ile hattınızı olgunlaştırabilirsiniz. Bugün küçük başlayın: bir servisi enstrümante edin, Collector ve Tempo’yu çalıştırın, ardından en çok sorun yaşadığınız akışa odaklanarak görünürlüğü sistem geneline genişletin.

12 Ekim 2025 Pazar

OpenTelemetry ile Node.js Uygulamalarında Dağıtık İzleme: Jaeger ile 15 Dakikada Kurulum

OpenTelemetry nedir ve neden şimdi?

Modern uygulamalar mikroservisler, HTTP çağrıları, mesaj kuyrukları ve veritabanı etkileşimleriyle dolu. Bir isteğin nerede yavaşladığını veya neden hata verdiğini anlamak için klasik loglar tek başına yetmiyor. OpenTelemetry (OTel), dil bağımsız bir standart ve SDK seti olarak uygulama içinde otomatik enstrümantasyon sağlar; iz (trace), span, metrik ve log verilerini toplayıp OTLP gibi açık protokollerle istediğiniz araca yollar. Bu rehberde, Node.js bir servise OTel entegre ederek izleri Jaeger üzerinden görselleştireceğiz.

Hedef

Amaç: Node.js uygulamanızdaki HTTP isteklerinin uçtan uca izlenmesini 15 dakikada etkinleştirmek. İzleri toplamak için OpenTelemetry Node SDK’sını kullanacağız, çıktıyı OTLP üzerinden gönderecek ve Jaeger All-in-One ile arayüzde görüntüleyeceğiz.

Önkoşullar

- Node.js 16+ ve npm yüklü olmalı. - Docker çalışıyor olmalı. - Uygulama Express, Fastify veya yerleşik HTTP modülü kullanıyor olabilir; OTel, otomatik enstrümantasyonla bu kütüphaneleri tanır.

Adım 1: Paketleri yükleyin

Projeye OpenTelemetry bağımlılıklarını ekleyin: npm i @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/exporter-trace-otlp-http

Bu paketler; API yüzeyi, Node SDK, otomatik enstrümantasyon, kaynak (resource) nitelikleri ve OTLP HTTP trace exporter içerir. İhtiyaca göre gRPC tabanlı exporter da tercih edebilirsiniz fakat yerelde HTTP pratik ve hızlıdır.

Adım 2: Tracing başlatıcısını oluşturun

Proje köküne tracing.js isminde bir dosya ekleyin ve SDK’yı minimum ayarlarla başlatın. Ana fikir: servis adını tanımlayın, OTLP exporter’ı 4318 portuna yönlendirin ve otomatik enstrümantasyon modüllerini etkinleştirin.

Örnek yapılandırma (özet): const { NodeSDK } = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); const sdk = new NodeSDK({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: 'orders-api', [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0' }), traceExporter: new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces' }), instrumentations: [getNodeAutoInstrumentations()] }); sdk.start(); process.on('SIGTERM', () => sdk.shutdown());

Burada service.name gelecekteki sorgular için kritik; Jaeger’de projeyi bu ad üzerinden bulacaksınız. Versiyon alanı, sürüm bazlı karşılaştırmalar için faydalıdır.

Adım 3: Uygulamayı OTel ile çalıştırın

Node sürecini tracing başlatıcısı ile preload ederek başlatın: node -r ./tracing.js app.js

Eğer bir test isteği göndermek isterseniz, uygulama ayağa kalktıktan sonra örneğin curl http://localhost:3000/health gibi basit bir çağrı yapın. OTel, HTTP istemci ve sunucu katmanlarını, Express route’larını ve veritabanı sürücülerini otomatik olarak span’lere dönüştürür.

Adım 4: Jaeger All-in-One’ı başlatın

Jaeger’i tek komutla çalıştırabilirsiniz. Bu imaj, OTLP HTTP alıcısı ve web arayüzünü içerir: docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one:1.56

- 16686: Jaeger UI portu. - 4318: OTLP HTTP endpoint’i. Uygulamanızdaki exporter URL’si ile eşleşir. Arayüze tarayıcıdan erişip (localhost:16686) “services” alanında orders-api servisini seçerek izleri görüntüleyebilirsiniz.

Adım 5: Manuel span eklemek (opsiyonel)

Otomatik enstrümantasyon çoğu senaryo için yeterli olsa da domain mantığınızı daha iyi anlamak için manuel span eklemek değerlidir. Örneğin kritik bir iş kuralını ölçmek için: const { context, trace } = require('@opentelemetry/api'); const tracer = trace.getTracer('orders-business'); await tracer.startActiveSpan('price-calculation', span => { // iş mantığı ... span.setAttribute('discount.applied', true); span.end(); });

Bu şekilde, Jaeger’de sadece altyapı çağrılarını değil, iş süreçlerinizi de okunaklı şekilde takip edebilirsiniz.

Üretim için en iyi uygulamalar

- Örnekleme (sampling): Trafiğiniz yüksekse, varsayılan oranı düşürün. Çevresel değişkenle kontrol etmek pratik: OTEL_TRACES_SAMPLER=traceidratio ve OTEL_TRACES_SAMPLER_ARG=0.1 (yüzde 10). - Kaynak nitelikleri: Ortam bilgilerini ekleyin: deployment.environment=prod, cloud.region=eu-central-1. - Veri güvenliği: Hassas verileri span attribute veya event’lerde taşımayın. Maskleme/sansürleme katmanı ekleyin. - Bağımlılık izleme: HTTP client timeouts, retry politikaları ve hataları span event’lerinde açıkça belirtin. - Başlatma düzeni: Tracing dosyanızı uygulama kodundan önce yüklediğinizden emin olun; aksi halde ilk istekler enstrümanlanmayabilir.

Sorun giderme

- İzler gelmiyor: Exporter URL’sini ve portu doğrulayın (http://localhost:4318/v1/traces). - CORS/agent hatası: Sunucu tarafında çalıştığınızdan emin olun; tarayıcı için farklı SDK gerekir. - Servis görünmüyor: service.name niteliği boşsa Jaeger listede göstermeyebilir. - Ağ çakışmaları: 4318 portu başka bir süreç tarafından kullanılıyorsa, Jaeger’i farklı portla çalıştırın ve exporter URL’sini eşitleyin.

Sonuç

OpenTelemetry ile Node.js uygulamanıza dakikalar içinde dağıtık izleme ekleyebilir, Jaeger üzerinden gecikmeleri, hata oranlarını ve bağımlılık zincirlerini şeffaf biçimde görebilirsiniz. Daha ileri kullanımda OpenTelemetry Collector ekleyip verileri birden fazla hedefe (ör. Tempo, Zipkin) yönlendirebilir; metrik ve log’ları aynı bağlamda zenginleştirerek tam kapsamlı gözlemlenebilirlik elde edebilirsiniz. Başlangıç için bu kurulum, üretimde dahi temel ihtiyaçları karşılayacak kadar hafif ve esnektir.

6 Eylül 2025 Cumartesi

Docker ve OpenTelemetry ile Node.js Uygulamasında Dağıtık İzleme: Adım Adım Kurulum Kılavuzu

Giriş

Modern mikroservis mimarilerinde bir isteğin sistem içinde nasıl yol aldığını anlamak, performans sorunlarını çözmek ve kök neden analizi yapmak için dağıtık izleme artık bir zorunluluk. OpenTelemetry (OTel), dil bağımsız açık standartları ve zengin SDK’ları ile Node.js uygulamalarınızda izleme (tracing) kurulumunu kolaylaştırır. Bu yazıda, Docker + OpenTelemetry Collector + Jaeger kullanarak Node.js tabanlı bir serviste uçtan uca izlemeyi adım adım kuracağız. Amaç, üretime yakın bir geliştirme deneyimi sağlamak, gecikmeleri ölçmek ve bağımlılıkları görünür kılmaktır.

Mimari ve Bileşenler

Kuracağımız basit topolojide üç temel bileşen bulunuyor: 1) Otomatik enstrümantasyonla iz verisi üreten Node.js servisi, 2) OTLP üzerinden iz kabul edip yöneten OpenTelemetry Collector, 3) Sorgulama ve görselleştirme için Jaeger. Collector, gelecekte Grafana Tempo, Honeycomb veya Zipkin gibi hedeflere geçişi kolaylaştıran bir ara katman görevi görür.

Node.js Projesini Hazırlama

Yeni bir proje başlatın ve gerekli bağımlılıkları kurun. Örnek bir Express API üzerinden gideceğiz, fakat otomatik enstrümantasyon HTTP, gRPC, MySQL, Redis gibi birçok paketi destekler.

# Projeyi başlat
npm init -y

# Express ve OpenTelemetry paketleri
npm i express
npm i @opentelemetry/sdk-node @opentelemetry/api @opentelemetry/resources \
@opentelemetry/semantic-conventions @opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-otlp-grpc

Ardından uygulama girişinde OpenTelemetry’yi başlatacak bir dosya oluşturun. Bu dosya, servis adı ve ortam gibi meta bilgileri de ekler.

// tracing.js
'use strict';
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-otlp-grpc');

const sdk = new NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'node-api',
    [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: process.env.NODE_ENV || 'dev',
  }),
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://otel-collector:4317'
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start()
  .then(() => console.log('OpenTelemetry başlatıldı'))
  .catch((err) => console.error('OTel hatası:', err));

process.on('SIGTERM', () => {
  sdk.shutdown().finally(() => process.exit(0));
});

Basit bir Express sunucusu ekleyelim. tracing.js, uygulamadan önce yüklenmelidir ki tüm modüller doğru enstrümante edilsin.

// index.js
'use strict';
require('./tracing'); // OTel ön yükleme

const express = require('express');
const app = express();

app.get('/health', (req, res) => {
  res.json({ ok: true, ts: Date.now() });
});

app.get('/slow', async (req, res) => {
  await new Promise(r => setTimeout(r, 300)); // yapay gecikme
  res.send('yavaş yanıt');
});

app.listen(3000, () => console.log('API 3000 portunda'));

OpenTelemetry Collector ve Jaeger ile Docker Compose

Collector, uygulamadan gelen OTLP verilerini alıp Jaeger’a iletecek. Aşağıda temel bir docker-compose yapısı ve Collector konfigürasyonu bulunuyor.

# docker-compose.yml
version: '3.9'
services:
  api:
    build: .
    command: node index.js
    environment:
      NODE_ENV: dev
      OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
      OTEL_TRACES_SAMPLER: parentbased_traceidratio
      OTEL_TRACES_SAMPLER_ARG: '0.5'
    ports:
      - "3000:3000"
    depends_on:
      - otel-collector

  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.103.0
    command: ["--config=/etc/otelcol-config.yaml"]
    volumes:
      - ./otelcol-config.yaml:/etc/otelcol-config.yaml:ro
    ports:
      - "4317:4317"   # OTLP gRPC
      - "4318:4318"   # OTLP HTTP (opsiyonel)
    depends_on:
      - jaeger

  jaeger:
    image: jaegertracing/all-in-one:1.57
    ports:
      - "16686:16686" # Jaeger UI

Collector’ın konfigürasyon dosyası, OTLP alıcıyı etkinleştirir ve verileri Jaeger’a yollar. İleride Zipkin, Tempo veya başka hedeflere ek ihracatçılar tanımlayabilirsiniz.

# otelcol-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
      http:

exporters:
  jaeger:
    endpoint: jaeger:14250
    tls:
      insecure: true

processors:
  batch:
    timeout: 1s
    send_batch_size: 512

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [jaeger]

Çalıştırma ve Doğrulama

Proje köküne basit bir Dockerfile ekleyin. Node tabanlı minimal bir imaj, üretime giden yolda iyi bir başlangıçtır.

# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]

Artık ortamı ayağa kaldırabilirsiniz. Aşağıdaki komut, API, Collector ve Jaeger’ı birlikte çalıştırır.

docker compose up --build

Tarayıcıdan http://localhost:16686 adresine gidip Jaeger UI’ı açın. Service menüsünde “node-api” servis adını göreceksiniz. Ayrıntılı izler için bir iki istek atın:

curl http://localhost:3000/health
curl http://localhost:3000/slow

Jaeger üzerinden isteklerin gecikme dağılımını, span ağaçlarını, endpoint bazlı hataları ve bağımlılık grafini analiz ederek performans darboğazlarını hızla teşhis edebilirsiniz.

En İyi Uygulamalar ve İpuçları

Örnek konfigürasyonda örnekleme oranını yüzde 50 olarak ayarladık. Üretimde, trafik seviyesine göre oranı düşürmek ve belirli endpoint’lerde dinamik örnekleme uygulamak mantıklıdır. Ayrıca, Resource etiketlerine versiyon, bölge ve takım bilgisi eklemek arama ve filtrelemeyi kolaylaştırır. Kolektörde attributes veya transform işlemcileri ile PII verileri kırpma/anonimleştirme adımları ekleyebilirsiniz. Gecikmeleri daha iyi yorumlamak için kritik yerlerde manuel span eklemek (ör. yoğun CPU işlemi, harici API çağrıları) fayda sağlar.

Güvenlik açısından Collector ile uygulama arasındaki trafiği mTLS ile şifrelemek ve dış ağlara ihracatta TLS’i etkinleştirmek önemlidir. Gözlemlenebilirlik verisi de kritiktir; erişim kontrolü, saklama süresi ve maliyet optimizasyonu (ör. örnekleme, toplu gönderim ayarları) planlanmalıdır. CI/CD’de, tracer başlatma hatalarını görünür kılmak için sağlık kontrolleri ve basit duman testleri ekleyin.

Sonuç

OpenTelemetry, Node.js servisleriniz için satıcı bağımsız, geleceğe dönük bir izleme altyapısı kurmanızı sağlar. Docker ile izleme yığınını dakikalar içinde ayağa kaldırabilir, Collector aracılığıyla hedef sistemleri esnekçe değiştirebilir, Jaeger ile sorunları hızla teşhis edebilirsiniz. Bugünkü kurulum, üretime geçişte ihtiyaç duyacağınız dinamik örnekleme, ek işlemciler, metrik ve log toplama gibi yeteneklerin de temelini oluşturur. İlk adımı attınız; şimdi span’ları zenginleştirip gerçek kullanıcı senaryolarını görünür kılma zamanı.