OpenTelemetry ile Dağıtık İzleme: Log, Metric ve Trace’i Tek Dilde Konuştur
Mikroservislerde performans ve hata kök nedenini OpenTelemetry ile log-metric-trace üçlüsünü birleştirerek yakala.
Neden OpenTelemetry?
Mikroservis mimarisinde “yavaşladı” şikayetinin cevabı çoğu zaman tek bir yerde değildir: API gateway, servis A, servis B, DB, üçüncü parti… Klasik log’larla zinciri takip etmek zorlaşır. OpenTelemetry (OTel), uygulamanın içinden trace (iz), metric (metrik) ve log sinyallerini standart bir formatla üretip istediğiniz backend’e (Jaeger/Tempo, Prometheus, Elastic, New Relic vb.) göndermenizi sağlar.
Bu yazıda hedef: bir isteğin uçtan uca yolculuğunu görmek, en yavaş halkayı bulmak ve “neden?” sorusunu kanıtla cevaplamak.
3 Sinyal: Trace, Metric, Log (Kısa ama kritik)
- Trace: Bir isteğin servisler arası akışı. Her adım bir span.
- Metric: Zaman içinde ölçümler (p95 latency, error rate, queue depth).
- Log: O anın bağlamı (hata mesajı, kullanıcı/tenant, sipariş id).
Ana kazanım: Bu üçlü aynı “correlation id” etrafında birleştiğinde, “log’da görünen hata hangi trace’in parçası?” sorusu saniyelere iner.
Somut Senaryo: Sipariş Akışında “Ara Sıra 2-3 Sn” Gecikme
Diyelim akış şöyle:
api→order-serviceorder-service→inventory-serviceorder-service→payment-provider
Şikayet: Bazen checkout 2-3 saniye uzuyor. Log’lar normal, DB CPU düşük. Neresi?
OTel trace ile:
payment-providerspan’ı: 120ms- DB span’ı: 30ms
- inventory-service span’ı: 2200ms
Sonra inventory tarafına inince ikinci bir bulgu:
GET /stock/{sku}çağrıları cache miss olduğunda dış sistemden 2 sn bekliyor.
Bu tür “ara sıra” problemler, yalnız metric’le genelde bulanık kalır; trace ile netleşir.
Uygulama: Node.js ile Minimal Enstrümantasyon
Aşağıdaki örnek, HTTP istekleri ve outbound çağrıları otomatik span’lara çevirir ve OTel Collector’a yollar.
1) Paketler
npm i @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http
2) telemetry.js
// telemetry.js
const { NodeSDK } = require("@opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const traceExporter = new OTLPTraceExporter({
// Collector endpoint
url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
});
const sdk = new NodeSDK({
traceExporter,
instrumentations: [getNodeAutoInstrumentations()],
serviceName: process.env.OTEL_SERVICE_NAME || "order-service"
});
sdk.start();
3) Uygulamayı telemetry ile başlat
OTEL_SERVICE_NAME=order-service \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces \
node -r ./telemetry.js index.js
Bu kadar. Birçok kütüphane (Express, http/https, pg, mysql, redis vb.) otomatik enstrümantasyonla span üretir.
OTel Collector: “Sinyal Router” gibi düşün
Collector, uygulamadan gelen telemetriyi alır, işler ve bir/çok hedefe yollar.
Basit bir collector config yaklaşımı:
- Receiver: OTLP (HTTP/gRPC)
- Processor: batch, sampling
- Exporter: Jaeger/Tempo, Prometheus, vb.
Collector kullanmanın artısı: uygulama kodunda backend bağımlılığı azaltır. Yarın Jaeger’dan Tempo’ya geçmek, çoğunlukla collector tarafında değişikliktir.
İyi Pratikler (Gerçek Hayatta İşe Yarayan)
- Sampling stratejisi belirleyin: Tüm trafiği taşımak pahalı olabilir. Örn. hata trace’lerini %100, başarılıları %5.
- Span attribute’larını standardize edin:
tenant_id,order_id,sku,providergibi alanlar arama gücünü artırır. - PII dikkat: E-posta/telefon/kart gibi verileri trace/log’a koymayın; maskeleyin.
- Metriklerle alarm, trace’le teşhis: Alarmı p95 latency/error rate ile yakalayın; kök nedeni trace’te bulun.
- Release karşılaştırması yapın:
service.versiontag’i ile “hangi sürüm yavaşladı?” sorusu kolaylaşır.
Sonuç
OpenTelemetry, “hangi servis yavaş?” tartışmasını veriye çevirir. Üstelik tek bir vendor’a kilitlenmeden. Küçük başlayın: önce kritik akış(lar)a trace ekleyin, sonra metrik/log korelasyonunu oturtun. Bir süre sonra üretimdeki sorunlar daha az tahmin, daha çok kanıt ile çözülür.