07.01.2026

Node.js’te İzlenebilirlik (Observability): Log, Metrik ve Trace’i Uyumlu Kurmak

Node.js uygulamalarında log, metrik ve dağıtık iz sürmeyi (trace) birlikte kurgulayarak hatayı hızlı bulma.

Modern Node.js uygulamalarında “çalışıyor” demek yetmiyor; ne olduğunu hızlı anlayabilmek gerekiyor. İzlenebilirlik (observability) üç temel sinyalin birlikte ele alınmasıdır: loglar, metrikler ve trace’ler. Bu yazıda, Node.js tarafında bu üçlüyü aynı dilde konuşturmanın pratik bir yolunu anlatıyorum.

1) Neden üçü birden?

  • Log: O anda ne oldu? (Bağlam, hata mesajı)
  • Metrik: Ne kadar oldu? (İstek sayısı, gecikme, hata oranı)
  • Trace: Nerede oldu? (Bir isteğin servisler/fonksiyonlar boyunca yolculuğu)

Tek başına log ile “koptu”yu görürsünüz; metrikle “arttı”yı görürsünüz; trace ile “hangi adımda”yı görürsünüz. En iyi sonuç, korelasyon ile gelir.

2) Yapılandırılmış log: metin değil veri

console.log yerine JSON log basın. Amaç: Logları sorgulanabilir kılmak.

Pino + request-id (korelasyon id) örneği:

import express from 'express';
import pino from 'pino';
import { randomUUID } from 'crypto';

const app = express();
const logger = pino({ level: process.env.LOG_LEVEL ?? 'info' });

// Her isteğe requestId ekle
app.use((req, res, next) => {
  req.requestId = req.headers['x-request-id'] ?? randomUUID();
  res.setHeader('x-request-id', req.requestId);
  next();
});

app.get('/health', (req, res) => {
  logger.info({ requestId: req.requestId, route: '/health' }, 'health check');
  res.json({ ok: true });
});

app.listen(3000);

İpucu: Loglara requestId, userId (varsa), route, duration_ms, error_code gibi alanları ekleyin. Bu alanlar sonradan altın değerinde olur.

3) Metrik: “sistem nasıl gidiyor?” sorusunun cevabı

Node.js için yaygın yaklaşım Prometheus formatında metrik yayımlamaktır. prom-client ile hızlıca başlayabilirsiniz.

import express from 'express';
import client from 'prom-client';

const app = express();

client.collectDefaultMetrics();

const httpDuration = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP request duration in seconds',
  labelNames: ['method', 'route', 'status'],
  buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 2, 5]
});

app.use((req, res, next) => {
  const end = httpDuration.startTimer();
  res.on('finish', () => {
    end({ method: req.method, route: req.route?.path ?? req.path, status: String(res.statusCode) });
  });
  next();
});

app.get('/metrics', async (_, res) => {
  res.set('Content-Type', client.register.contentType);
  res.send(await client.register.metrics());
});

app.get('/orders/:id', (req, res) => {
  // ...
  res.json({ id: req.params.id });
});

app.listen(3000);

Bu histogram sayesinde:

  • p95/p99 gecikmelerini,
  • belirli route’larda hata artışını,
  • deploy sonrası performans etkisini net görürsünüz.

4) Trace: “bu istek neden yavaş?” sorusunun cevabı

Dağıtık iz sürme için pratik standart: OpenTelemetry. Temel fikir: Her isteğe bir trace id atanır; DB sorgusu, dış servis çağrısı gibi adımlar “span” olarak kaydedilir.

Minimal kavramlar:

  • Trace: Bir isteğin uçtan uca hikayesi
  • Span: Hikayedeki adımlar (örn. “postgres query”, “payment provider call”)

Önemli nokta: Loglarınıza traceId/spanId koyarsanız, log ↔ trace arasında tek tıkla gezebilirsiniz (Grafana/Jaeger/Tempo gibi araçlarla).

5) Altın kural: Korelasyon olmadan observability eksik kalır

Şu üçlü aynı anda bulunmalı:

  • Log: requestId ve mümkünse traceId
  • Metrik: route/status gibi etiketler (label) + aşırı etiketlemeden kaçınma
  • Trace: dış çağrılar ve kritik bloklar için span’ler

Dikkat: Metriklerde userId, orderId gibi yüksek kardinaliteli label’lar sistemi şişirir. Bu tür detaylar log/trace tarafına daha uygundur.

6) Küçük bir kontrol listesi

  • JSON log + requestId
  • Hata loglarında stack trace + anlamlı error code
  • HTTP latency histogram (p95/p99 takip)
  • /metrics endpoint’i
  • TraceId’yi loglara ekleme
  • Prod’da örnekleme (sampling) ve PII maskeleme

İzlenebilirliği baştan kurduğunuzda, “prod’da oldu ama bende olmadı” cümlesi giderek tarihe karışır.