performans izleme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
performans izleme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

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.

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.