Monolitik uygulamada tek log dosyasıyla idare ederdiniz. 20 mikroservis arasında gezinen bir isteği takip etmek için ise distributed tracing şart. OpenTelemetry (OTel), CNCF''in trace/metric/log standardıdır — vendor-agnostic, tüm diller destekli.

Temel Kavramlar

İlgili rehberler: Yazılım geliştirme süreçleri · PostgreSQL optimizasyonu · Git ileri seviye komutlar · Redis nedir, nasıl kullanılır · Docker ile deploy

  • Trace: Bir isteğin tüm yolculuğu (root span + çocukları)
  • Span: Trace içindeki tek bir iş birimi (DB çağrısı, HTTP request)
  • Trace context: Servisler arası geçen ID (W3C traceparent header)
  • Exporter: Trace''i backend''e gönderen (Jaeger, Zipkin, OTLP)

Node.js Auto-Instrumentation

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

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

sdk.start();

process.on('SIGTERM', () => sdk.shutdown());
# server.js'i çalıştırırken tracing.js'i önce yükle
node -r ./tracing.js server.js
Bilgi
Auto-instrumentation otomatik olarak Express, HTTP, pg, MySQL, Redis, AWS SDK, gRPC vs. için span açar — kod değişikliği gerekmez.

Manuel Span

const { trace, SpanStatusCode } = require('@opentelemetry/api');
const tracer = trace.getTracer('webapp');

async function calculateReport(userId) {
    return tracer.startActiveSpan('calculate-report', async span => {
        span.setAttribute('user.id', userId);
        try {
            const data = await fetchData(userId);
            span.setAttribute('data.count', data.length);
            const result = processData(data);
            span.setStatus({ code: SpanStatusCode.OK });
            return result;
        } catch (err) {
            span.recordException(err);
            span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
            throw err;
        } finally {
            span.end();
        }
    });
}

Context Propagation

Bir servis başka bir servise HTTP çağrısı yaptığında traceparent header otomatik eklenir. Receiver service bu header''ı okuyup aynı trace''e devam eder.

# Otomatik eklenen header
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
# versiyon-trace_id-span_id-flags

OTel Collector

Her servisin doğrudan Jaeger''a göndermesi yerine, aradaki Collector trace''i toplar, sample''lar, zenginleştirir ve backend''e gönderir. Mimaride fan-out noktası.

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc: { endpoint: 0.0.0.0:4317 }
      http: { endpoint: 0.0.0.0:4318 }

processors:
  batch: {}
  tail_sampling:
    policies:
      - name: errors
        type: status_code
        status_code: { status_codes: [ERROR] }
      - name: slow
        type: latency
        latency: { threshold_ms: 500 }
      - name: baseline
        type: probabilistic
        probabilistic: { sampling_percentage: 1 }

exporters:
  otlp/jaeger:
    endpoint: jaeger:4317
    tls: { insecure: true }
  logging: {}

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, tail_sampling]
      exporters: [otlp/jaeger, logging]

Jaeger UI

Jaeger''ı Docker ile tek container olarak kaldırabilirsiniz. Trace''leri service, operation, duration, tag ile arar ve zaman akışını grafiksel gösterir.

docker run -d --name jaeger \
    -p 4317:4317 \
    -p 16686:16686 \
    jaegertracing/all-in-one:latest
# UI: http://localhost:16686

Sampling Stratejisi

  • Head sampling: istek başında karar, ucuz ama hata trace''lerini kaçırabilir
  • Tail sampling: tüm trace''i topla, sonra karar ver (collector''da). Hatalar her zaman saklanır
  • Probabilistic: %1-5 örneklem genelde yeter
  • Rate-limiting: saniyede max N trace

Metric ve Log Entegrasyonu

OTel sadece trace değil — metric (Prometheus alternative) ve log''ları da aynı SDK ile export eder. 3''ü birlikte: bir span''den ilgili log''lara ve metric''lere atlamak mümkün (Observability 2.0).

Vendor Seçimi

  • Self-hosted: Jaeger, Tempo + Grafana, SigNoz
  • SaaS: Datadog APM, New Relic, Honeycomb, Lightstep
  • OTel''in en büyük faydası: vendor-agnostic — exporter değiştirerek vendor değiştirebilirsin

Modern Yazılım Geliştirme ve DevOps Pratikleri

Profesyonel yazılım geliştirme süreci üç pillar üzerine kuruludur: kaynak kontrolü (Git + GitHub/GitLab pull request akışı, code review zorunlu), CI/CD pipeline (otomatik test + lint + build + deploy), ve gözlemlenebilirlik (Sentry/Datadog/Grafana ile log, metric, trace toplama). Test piramidi (unit > integration > e2e) ile kod kalitesini garantilemek, mikroservis mimarisinde Docker container ve Kubernetes orkestrasyonu kullanmak, REST veya GraphQL API tasarımında OpenAPI/GraphQL Schema sözleşmesi tutmak modern standardlardır. Yazılım geliştirme yaşam döngüsü boyunca (gereksinim → tasarım → implementasyon → test → deploy → bakım) Agile/Scrum sprintleri 1-2 hafta, DevOps takımları sürekli teslim (continuous delivery) prensibiyle çalışır.

Distributed tracing kurulumu

OpenTelemetry, Jaeger/Tempo kurulumu ve mikroservis observability için iletişime geçin

WhatsApp