L
Observability & Monitoring • Literally Web ID

Distributed Tracing dan Observability Skala Masif dengan OpenTelemetry & Prometheus

⏱️ 15 menit baca • 📅 12 Oct 2026 • 👁️ 1 views
Distributed Tracing dan Observability Skala Masif dengan OpenTelemetry & Prometheus

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern yang bertransisi dari monolitik menuju layanan mikro terdistribusi (distributed microservices), kompleksitas operasional meningkat secara eksponensial. Sebuah permintaan HTTP tunggal yang masuk melalui edge caching Cloudflare, melewati WAF, nginx reverse proxy, menembus API Gateway, dan akhirnya didistribusikan ke puluhan backend service (Go, Node.js, PHP-FPM) serta berinteraksi dengan database cluster MySQL/MariaDB dan Redis cache, menciptakan jalur eksekusi asinkron yang sangat rumit.

Masalah Klasik: Keterbatasan Traditional Monitoring

Pendekatan pemantauan tradisional yang hanya mengandalkan metrik sistem (CPU utilization, RAM usage, Disk I/O) dan log teks mentah (syslog, application logs) mengalami kegagalan total ketika menghadapi masalah latensi intermiten (long-tail latency). Ketika seorang pengguna melaporkan bahwa transaksi checkout mengalami jeda 8 detik, tim Site Reliability Engineer (SRE) terjebak dalam teka-teki: Apakah bottleneck terjadi pada koneksi database Redis yang mengalami cache stampede, antrean queue di Supervisor yang tersumbat, atau blocking event loop pada aplikasi Node.js?

Sebelum vs Sesudah Penerapan OpenTelemetry & Prometheus

  • Sebelum: Debugging dilakukan secara reaktif. Tim harus membuka ratusan baris log mentah di file server, mencocokkan timestamp secara manual, melakukan guesswork, dan menghabiskan waktu berjam-jam (MTTR - Mean Time to Resolution yang tinggi) hanya untuk menemukan layanan mana yang bertanggung jawab atas kegagalan transaksi.
  • Sesudah: Menggunakan OpenTelemetry (OTel) untuk distributed tracing dan Prometheus untuk metrik berbasis time-series, setiap permintaan diberi trace ID unik yang melintasi batas jaringan (context propagation). SRE dapat langsung melihat waterfall chart di Grafana, mengidentifikasi secara presisi span mana yang memakan waktu 7.9 detik, dan segera mengeksekusi root-cause analysis dalam hitungan menit.

2. Konsep Inti & Deep Dive Arsitektur

OpenTelemetry adalah standar industri open-source yang bernaung di bawah Cloud Native Computing Foundation (CNCF), hasil penggabungan proyek OpenTracing dan OpenCensus. OTel menyediakan spesifikasi tunggal dan SDK universal untuk mengumpulkan metrics, logs, dan traces.

Alur Data (Data Pipeline) di Bawah Tendensi Skala Masif

[Client / Browser] ---> (Cloudflare Edge / WAF) ---> [Nginx Reverse Proxy]
                                                            |
                                                            v
[Grafana Dashboard] <--- [Prometheus TSDB] <--- [OpenTelemetry Collector]
        ^                                                   ^
        | (OTLP gRPC/HTTP)                                  |
[Jaeger / Tempo] <------------------------------------+----
                                                      |
                                        [Node.js / Go Microservices]
                                        (Auto & Manual Instrumentation)
  1. Instrumentation: Aplikasi Node.js atau Go menggunakan pustaka OTel SDK untuk menghasilkan Traces (terdiri dari Spans yang memiliki durasi, atribut, dan events) serta mengekspos metrik dalam format Prometheus.
  2. Context Propagation: Header HTTP khusus (traceparent, tracestate) disuntikkan ke setiap keluar-masuk permintaan HTTP antar layanan mikro, memastikan satu jejak (trace) tetap utuh lintas bahasa pemrograman dan infrastruktur jaringan.
  3. OpenTelemetry Collector: Berfungsi sebagai daemon pengumpul terpusat (Agent atau Gateway). Collector menerima data via protokol OTLP (gRPC pada port 4317 atau HTTP pada port 4318), melakukan batching, filtering, sampling, dan meneruskannya ke backend penyimpanan seperti Prometheus (untuk metrik) dan Grafana Tempo / Jaeger (untuk traces).

3. Perbandingan Komparatif / Analisis Pendekatan

Parameter Komparasi Jaeger Native SDK OpenTelemetry Collector + Prometheus / Tempo Zipkin (Legacy)
Standar Industri Spesifik Jaeger Standar CNCF Universal Spesifik lama Twitter
Dukungan Bahasa Terbatas Sangat Luas (Go, Node.js, PHP, Python, Java) Sedang
Overhead CPU/RAM Menengah Sangat Rendah (Optimized Go Collector) Tinggi pada skala besar
Keluaran Data Traces saja Metrics, Logs, dan Traces (Full Observability) Traces saja
Ekosistem & Integrasi Terbatas pada UI Jaeger Native integration dengan Grafana, Prometheus, S3 Terbatas

[!TIP]
Selalu gunakan OpenTelemetry Collector sebagai perantara (proxy) alih-alih mengirim data tracing langsung dari aplikasi ke penyimpanan backend. Hal ini mencegah lonjakan traffic mendadak melumpuhkan database tracing Anda, karena Collector dapat melakukan tail-based sampling dan backpressure handling.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum melangkah ke implementasi teknis, pastikan infrastruktur dasar berikut telah tersedia dan terverifikasi:

  • Sistem Operasi: Ubuntu 22.04 LTS / Debian 12 (Kernel Linux >= 5.15 untuk performa eBPF jika diperlukan).
  • Runtime: Go 1.22+, Node.js 20.x LTS.
  • Infrastruktur Pendukung: Nginx Reverse Proxy, Redis Cluster untuk caching, dan MySQL 8.0.
  • Port Jaringan yang Harus Dibuka:
    • 4317: OTLP gRPC receiver
    • 4318: OTLP HTTP receiver
    • 9090: Prometheus Server
    • 3000: Grafana Dashboard
  • Hak Akses: Akses root atau sudo untuk konfigurasi systemd service dan modifikasi iptables jika diperlukan.

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Setup OpenTelemetry Collector (otel-collector-config.yaml)

Buat file konfigurasi di /etc/otelcol/config.yaml:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 1s
    send_batch_size: 1024
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 20

exporters:
  prometheus:
    endpoint: "0.0.0.0:8889"
  otlp/tempo:
    endpoint: "tempo:4317"
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus]

Langkah 2: Instrumentasi Aplikasi Go (Backend API Service)

Inisialisasi modul Go dan buat file main.go yang mengimplementasikan OTel tracer provider:

package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"time"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
	trace "go.opentelemetry.io/otel/trace"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

var tracer = otel.Tracer("go-backend-service")

func initTracer(ctx context.Context) (*sdktrace.TracerProvider, error) {
	res, err := resource.New(ctx,
		resource.WithAttributes(
			semconv.ServiceNameKey.String("go-backend-service"),
			semconv.ServiceVersionKey.String("1.0.0"),
		),
	)
	if err != nil {
		return nil, err
	}

	conn, err := grpc.DialContext(ctx, "localhost:4317", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
	if err != nil {
		return nil, err
	}

	exporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithGRPCConn(conn))
	if err != nil {
		return nil, err
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithSampler(sdktrace.AlwaysSample()),
		sdktrace.WithResource(res),
		sdktrace.WithBatcher(exporter),
	)

	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

	return tp, nil
}

func handleCheckout(w http.ResponseWriter, req *http.Request) {
	ctx, span := tracer.Start(req.Context(), "HandleCheckout", trace.WithSpanKind(trace.SpanKindServer))
	defer span.End()

	// Mensimulasikan pemrosesan database
	processPayment(ctx)

	w.WriteHeader(http.StatusOK)
	w.Write([]byte(`{"status": "success\
🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server