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.