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

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ı.