Hizmetler Hosting & Sunucu Araçlar Blog Ara Kurumsal EnglishEN
Teklif Alın

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