İçeriğe geç
IN DEVELOPMENTNode.jsTypeScriptGoPostgreSQLRabbitMQRedisElasticsearchKibanaJSON SchemaExpressDockerPrometheusJaegerGrafanaMakefile

Observability Hub: Event-Driven Gözlemlenebilirlik Platformu

Node.js mikroservislerinin RabbitMQ üzerine yapılandırılmış event'ler yayımladığı; 20 goroutine'lik worker pool'a sahip Go collector'ın bu event'leri PostgreSQL, Redis ve Elasticsearch'e aktardığı — TypeScript ve Go ekosistemlerinde JSON Schema sözleşmeleriyle tip güvenliğinin zorunlu tutulduğu dağıtık, event-driven log toplama platformu.

Galeri

Problem Tanımı

Dağıtık mikroservis sistemlerinde, log üreten servisler ile bu logları tüketen altyapı arasında doğal bir sözleşme yoktur. Sonuç: farklı servisler farklı formatlarda log yazar, servis sınırları geçildiğinde istek bağlamı (correlation) kaybolur ve bir producer'ın ürettiğinin collector tarafından ayrıştırılabilir olacağının garantisi yoktur. Zorluk; log üreten servisleri bloke etmeden, veri sözleşmesinin her iki uçta da zorunlu tutulduğu bir sistem tasarlamaktı.

Rolüm: Lead Developer & Architect

Mikroservislerde gözlemlenebilirlik; sisteme akan verinin yapılandırılmış, doğrulanmış ve tutarlı biçimde depolandığı durumlarda anlam kazanır. Merkezi bir şema sözleşmesi olmadan her servis kendi formatında log üretir — bu durum ayrıştırma hatalarına, istek bağlamının (correlation) servis sınırlarında kaybolmasına ve güvenilmez bir gözlemlenebilirlik katmanına yol açar.

Observability Hub bu sorunu katmanlı bir mimariye dönüştürerek çözdü: paylaşılan @observability-hub/observability paketi, tüm Node.js servislerine Circuit Breaker korumalı RabbitMQ publisher, Correlation ID middleware ve Prometheus metrikleri sağlar. 20 goroutine'lik worker pool'a sahip Go collector bu event'leri tüketerek üç depolama hedefine (PostgreSQL, Redis, Elasticsearch) dağıtır; kendi Prometheus metriklerini yayımlar ve hatalı mesajları Dead Letter Queue ile izole eder.

Mimari ve Geliştirme Süreci

A. Mesaj Sözleşmeleri ve Tip Güvenliği

Diller arası (Cross-language) şema zorunluluğu

Event yapılarını (Loglar, Metrikler, Trace'ler) tanımlamak için JSON Schema Draft 7+ kullanıldı. Bu şemalardan, kesin TypeScript interfaceleri ve json/validate etiketlerine (tags) sahip Go struct'ları türetildi. Paylaşılan @observability-hub/event-contracts paketi sayesinde veriyi üreten (producer) ve tüketen (consumer) uçların tam olarak aynı formata uyması garanti altına alındı.

B. Yüksek Performanslı Validasyon Hattı

Saniyede 35.000'i aşan işlem kapasitesi

Milisaniyelik gecikmeleri önlemek adına, 35.714 validasyon/saniye yapabilen Simple Validator ve 8.333 işlem/saniye yapabilen Schema Validator geliştirildi. Sistem; alan bazlı (field-level) hata raporlama, şema tiplerini otomatik tanıma ve toplu işlem (batch validation) özellikleriyle çalışmaktadır.

C. Go Collector Servisi

Worker pool, çok-hedefli fan-out ve hata izolasyonu

Collector, yapılandırılabilir sayıda goroutine başlatır (varsayılan: 20); tüm worker'lar aynı RabbitMQ deliveries channel'ından yarışarak okur — koordinasyon overhead'i sıfırdır. Her mesaj üç hedefe iletilir: Redis cache hit ratio'ya göre batch boyutunu dinamik olarak ayarlayan Adaptive Batch Optimizer aracılığıyla PostgreSQL'e pq.CopyIn batch yazımı; EventID+CorrelationID ile 24 saatlik TTL'li Redis deduplication ve servis başına metadata cache; Elasticsearch'e ise fire-and-forget goroutine ile asenkron index — böylece ES'in geçici olarak erişilemez olması RabbitMQ ack'ini hiçbir zaman bloke etmez. JSON unmarshal başarısız olan mesajlar Nack(false, false) ile Dead Letter Queue'ya düşer, sonsuz retry döngüsü oluşmaz.

D. Versiyonlama ve Log Client Kütüphanesi

Kesintisiz geriye dönük uyumluluk

Eski log yapılarının sistemi bozmaması için Migration altyapısıyla SemVer (Semantic Versioning) tabanlı sıkı bir mesaj versiyonlama stratejisi kurgulandı. Express tabanlı servisler için geliştirilen yeniden kullanılabilir @observability-hub/log-client kütüphanesi, correlation ID'lerin enjekte edilmesi gibi süreçleri otomatik hale getirdi.

E. Depolama Mimarisi ve Gözlemlenebilirlik Yığını

Üç katmanlı depolama: kalıcılık, hız ve arama

**PostgreSQL** sistemin gerçek kaynağıdır (source of truth). Collector, tekil INSERT'ler yerine pq.CopyIn (COPY protokolü) ile batch olarak yazar; bu sayede round-trip sayısı dramatik biçimde azalır. **Redis** collector içinde çift rol üstlenir: EventID+CorrelationID anahtarıyla 24 saatlik TTL'li deduplication yaparak aynı event'in iki kez yazılmasını önler; servis başına metadata cache'leyerek Adaptive Batch Optimizer'ın çalışma zamanında batch boyutunu ekstra DB sorgusu açmadan ayarlamasını sağlar. **Elasticsearch** arama katmanıdır — event'ler servis ve aya göre ayrılmış (logs-{servis}-{YYYY-MM}) index'lere asenkron olarak yazılır; ES'e yazan goroutine RabbitMQ ack'inden bağımsız çalıştığı için ES kesintisi ana pipeline'ı durdurmaz.

Dayanıklılık: circuit breaker, DLQ ve graceful shutdown

Node.js @observability-hub/observability paketi içindeki log publisher'a CLOSED/OPEN/HALF_OPEN döngülü bir Circuit Breaker entegre edildi. RabbitMQ erişilemez hale geldiğinde N başarısız denemeden sonra devre açılır; sonraki log çağrıları timeout'a girmek yerine hızlıca başarısız döner — hataların HTTP handler'larına zincirleme yayılması engellenir. Collector tarafında ise bozuk mesajlar DLQ'ya izole edilir, sonsuz retry döngüsü oluşmaz. Kapatma sinyali (SIGINT/SIGTERM) geldiğinde 10 saniyelik drain penceresi uçuşta tüm worker'ların bitmesini ve kalan batch'in flush edilmesini bekler.

Dağıtık izleme ve metrik görünürlüğü

**Jaeger**, @obs/observability tracing modülü aracılığıyla her isteği servis sınırları boyunca izler — tek bir trace ID, gecikmenin nerede biriktiğini ortaya koyar. **Prometheus**, collector düzeyindeki metrikleri (messages_processed, flush_duration_seconds, cache_hit_ratio, batch_size_optimized) ve her Node.js servisinin istek/hata oranlarını toplar. **Grafana** bunları tek bir gerçek zamanlı dashboard'da birleştirir. **RabbitMQ** event omurgası olarak producer'ları collector'dan tamamen ayırır — trafik artışları kuyruğa tamponlanır, mikroservislere geri baskı oluşmaz.

Sonuç: Ölçülebilir fayda

Veri sözleşmesi zorunluluğu, hata izolasyonu ve çok hedefli depolama fan-out'unun sonradan eklenen özellikler değil, birinci sınıf mimari kararlar olduğu, production kalitesinde bir gözlemlenebilirlik pipeline'ı ortaya kondu.

  • Producer ve collector'da çift taraflı zorunlulukla log, trace ve metrik event tiplerinde %100 şema kapsamı sağlandı.
  • TypeScript Simple Validator 35.714 ops/sn'de benchmark edildi; Go collector ise batch yazma optimizasyonuyla sürekli yük altında stabil throughput sürdürdü.
  • Bağımsız hata modlarıyla üç-hedef fan-out (PostgreSQL + Redis + Elasticsearch): ES node'u düşse dahi mesaj ack'i etkilenmez.
  • Jaeger ve enjekte edilen correlation ID'ler sayesinde servis sınırları boyunca tam istek izlenebilirliği sağlandı.

Mühendislik Kararları

Architecture Diagram

📊 Gözlemlenebilirlik

💾 Depolama Katmanı

⚙️ Go Collector

🐰 RabbitMQ

🔗 Paylaşılan Paketler

📦 Node.js Mikroservisler

log publish

log publish

log publish

schema validate

AMQP publish

trace span

logs.# routing key

Nack false false

consume

COPY batch

dedup + metadata cache

async goroutine

counter metrics

scrape

user-service
:8081

order-service
:8080

product-service
:8082

@obs/observability
Circuit Breaker · Correlation ID
Prometheus Middleware

@obs/event-contracts
JSON Schema Draft 7
log · metric · trace

logs.topic
topic exchange

logs.collector
durable, autoAck: false

dlq.logs
dead letter queue

Worker Pool
20 goroutine, shared channel

DBStorage
Adaptive Batch Optimizer
Redis Dedup Check

PostgreSQL
pq.CopyIn bulk insert
batch flush

Redis
EventID dedup 24h TTL
metadata cache

Elasticsearch
logs-service-YYYY-MM
async goroutine

Prometheus
:9090/metrics

Grafana
:3000

Jaeger
:16686