L
Observability & Monitoring • Literally Web ID

Implementasi Observability End-to-End dengan Prometheus, Grafana, dan OpenTelemetry

⏱️ 18 menit baca • 📅 15 Oct 2026 • 👁️ 1 views
Implementasi Observability End-to-End dengan Prometheus, Grafana, dan OpenTelemetry

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap infrastruktur web modern saat ini, kompleksitas sistem telah meningkat secara eksponensial. Monolit tradisional telah digantikan oleh arsitektur microservices, serverless functions, dan infrastruktur cloud-native yang dinamis di atas orkestrator seperti Kubernetes. Di balik skalabilitas dan fleksibilitas ini, tersembunyi tantangan operasional yang masif: hilangnya visibilitas menyeluruh (end-to-end visibility). Ketika sebuah request HTTP dari pengguna mengalami latensi tinggi atau gagal dengan kode status 500, melacak akar masalahnya di antara puluhan layanan backend, proxy Nginx, database MySQL/MariaDB, message queue Redis, hingga layanan pihak ketiga melalui CDN Cloudflare ibarat mencari jarum di dalam tumpukan jerami.

Secara tradisional, para Site Reliability Engineers (SRE) dan System Administrators mengandalkan pendekatan reaktif. Log server dibaca satu per satu menggunakan grep atau dikumpulkan ke dalam tumpukan Elasticsearch yang sering kali memakan resource RAM sangat besar. Metrik dipantau secara terisolasi—CPU naik, tetapi tidak diketahui proses atau query SQL mana yang memicu lonjakan tersebut. Hal ini mengakibatkan Mean Time To Resolution (MTTR) yang tinggi, tingginya tingkat frustrasi tim teknik, dan penurunan kepuasan pengguna akhir yang berujung pada kerugian finansial.

[!WARNING] Memantau server web, database, dan aplikasi secara terpisah tanpa context propagation lintas jaringan dan proses adalah resep pasti kegagalan saat insiden produksi berskala besar terjadi.

Perbandingan kondisi Sebelum vs Sesudah penerapan arsitektur Observability berbasis Prometheus, Grafana, dan OpenTelemetry (OTel):

  • Sebelum Observability Terpadu:

    • Deteksi masalah bergantung pada keluhan pelanggan (user reporting).
    • Debugging dilakukan secara manual dengan menebak-nebak log file dari berbagai server.
    • Metrik sistem (CPU/RAM) terputus dari metrik performa aplikasi (throughput/latency).
    • Tidak ada visibilitas terhadap jejak eksekusi (trace) lintas microservices.
    • MTTR bisa memakan waktu berjam-jam hingga hari.
  • Sesudah Implementasi OpenTelemetry, Prometheus, & Grafana:

    • Deteksi anomali terjadi secara otomatis secara real-time via alerting rules.
    • Root-cause analysis dapat diselesaikan dalam hitungan menit menggunakan distributed tracing.
    • Metrik infrastruktur, web server, database, dan aplikasi berkorelasi dalam satu dashboard Grafana tunggal.
    • Penelusuran lifecycle request dari ujung edge Cloudflare hingga database terekam sempurna.
    • MTTR turun drastis hingga di bawah 10 menit.

2. Konsep Inti & Deep Dive Arsitektur

Observability modern berdiri di atas tiga pilar utama (The Three Pillars of Observability): Metrics, Logs, dan Traces. Namun, tanpa standarisasi dan korelasi yang tepat, ketiga pilar ini tetap menjadi pulau-pulau data yang terisolasi. OpenTelemetry hadir sebagai standar industri yang didukung Cloud Native Computing Foundation (CNCF) untuk menyatukan pengumpulan telemetry data tersebut.

Berikut adalah alur data (data flow) dari arsitektur Observability End-to-End yang kita bangun:

+-----------------------------------------------------------------------------------------+
|                                 USER / CLIENT BROWSER                                   +
+-----------------------------------------------------------------------------------------+
                                             |
                                             v
+-----------------------------------------------------------------------------------------+
|                            CLOUDFLARE CDN / EDGE CACHING                                +
+-----------------------------------------------------------------------------------------+
                                             |
                                             v
+-----------------------------------------------------------------------------------------+
|                         NGINX REVERSE PROXY & WEB SERVER                                +
|         (Exporting Nginx Prometheus Exporter metrics & OTel Trace Headers)               +
+-----------------------------------------------------------------------------------------+
                   |                                                 |
                   v                                                 v
+------------------------------------+             +--------------------------------------+
|     GO / PHP / NODE.JS BACKEND     |             |      MYSQL / REDIS / STORAGE         |
|  (Instrumented with OTelemetry SDK |             |    (Exposing native performance      |
|   & exposing Prometheus /metrics)  |             |      metrics via exporters)          |
+------------------------------------+             +--------------------------------------+
                   |                                                 |
                   +-----------------------+-------------------------+
                                           |
                                           v
+-----------------------------------------------------------------------------------------+
|                               OPENTELEMETRY COLLECTOR                                   |----+
|            (Receives OTLP traces, processes, samples, and exports data)                 |    |
+-----------------------------------------------------------------------------------------+
     |                                                                                    |
     v (Scrapes metrics)                                                                  v (Exports traces)
+-----------------------------------+                                     +-------------------+
|            PROMETHEUS             |                                     |      JAEGER /     |
|    (Time-Series Database & TSDB)  |                                     |    TEMPO TRACING  |
+-----------------------------------+                                     +-------------------+
     |                                                                                    |
     +---------------------------------------+--------------------------------------------+
                                             |
                                             v
+-----------------------------------------------------------------------------------------+
|                                     GRAFANA UI                                          | 
|                   (Unified Dashboards, Visual Traces, & Alerting Rules)                 |
+-----------------------------------------------------------------------------------------+

Penjelasan Alur Komponen Under the Hood:

  1. Edge & Web Server Layer: Cloudflare meneruskan request ke Nginx. Nginx mencatat metrik koneksi aktif, hit/miss cache, dan meneruskan W3C Trace Context headers (traceparent) ke aplikasi backend.
  2. Application Backend Layer: Aplikasi backend (dibangun dengan Go, Node.js, atau PHP) menerima request, mendekode header OTel, mengeksekusi query database MySQL dan operasi cache Redis, lalu mencatat span waktu eksekusi menggunakan OpenTelemetry SDK.
  3. Collection Layer: Prometheus secara periodik melakukan scraping (tarik data) dari endpoint /metrics yang diekspos oleh aplikasi dan exporter infrastruktur. Sementara itu, aplikasi mengirimkan traces secara asinkron menggunakan protokol OTLP (OpenTelemetry Protocol) ke OpenTelemetry Collector.
  4. Storage & Visualization Layer: Prometheus menyimpan metrik deret waktu (time-series), sedangkan Tempo/Jaeger menyimpan data traces. Grafana bertindak sebagai lapisan visualisasi tunggal (single pane of glass) yang menarik data dari Prometheus dan Tempo untuk disajikan dalam bentuk dashboard interaktif.

3. Perbandingan Komparatif / Analisis Pendekatan

Sebelum memutuskan arsitektur pengumpulan metrik dan tracing, penting untuk memahami trade-off antara berbagai pendekatan yang tersedia di ekosistem production-grade.

Parameter Perbandingan Prometheus Pull Model + OTel Collector Push Model (StatsD / Telegraf Agent) APM Proprietary (Datadog / New Relic)
Arsitektur Pengumpulan Pull (Server menarik data dari target) Push (Target mengirim data ke agens/server) Agen proprietary di setiap instance
Konsumsi CPU & RAM Target Sangat Rendah (Target hanya mengekspos endpoint HTTP) Rendah hingga Menengah (Agens aktif di setiap server) Tinggi (Agen melakukan instrumentasi mendalam & buffering)
Skalabilitas Jaringan Sangat baik untuk lingkungan internal & Kubernetes Baik, namun rentan backpressure saat lonjakan traffic Sangat mudah, tetapi bergantung pada koneksi internet/cloud
Biaya Operasional (TCO) Open Source (Biaya infrastruktur penyimpanan mandiri) Open Source (Biaya pemeliharaan server agens) Sangat Tinggi (Berbasis volume data / per host)
Vendor Lock-in Tidak ada (Standar CNCF terbuka) Rendah hingga Sedang Sangat Tinggi
Kompleksitas Konfigurasi Menengah ke Atas (Membutuhkan pemahaman Prometheus config) Rendah ke Menengah Sangat Rendah (Plug-and-play)

[!TIP] Untuk perusahaan enterprise yang mengutamakan kontrol data privasi, efisiensi biaya jangka panjang, dan kepatuhan regulasi (compliance), kombinasi Prometheus + OpenTelemetry + Grafana adalah standar emas industri yang tidak tertandingi.

4. Prasyarat Sistem & Persiapan Lingkungan

Untuk mengimplementasikan panduan ini secara nyata, siapkan lingkungan dengan spesifikasi minimum berikut:

  • Sistem Operasi: Ubuntu Server 22.04 LTS / 24.04 LTS (atau Debian 12)
  • Hardware: Minimal 2 vCPU, 4 GB RAM, 50 GB SSD NVMe
  • Akses: Hak akses root atau sudo penuh
  • Dependensi Dasar: curl, wget, git, docker, docker-compose-v2

Verifikasi bahwa Docker dan Docker Compose telah terpasang dengan benar pada sistem Anda dengan menjalankan perintah terminal berikut:

docker --version
docker compose version

Pastikan port-port esensial berikut tidak terblokir oleh firewall UFW lokal:

  • 9090 (Prometheus)
  • 3000 (Grafana)
  • 4317 / 4318 (OpenTelemetry Collector OTLP gRPC/HTTP)
  • 8080 (Aplikasi Backend Contoh)
  • 9113 (Nginx Prometheus Exporter)

Konfigurasi firewall UFW yang disarankan:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3000/tcp
sudo ufw allow 9090/tcp
sudo ufw enable

5. Panduan Implementasi Langkah demi Langkah

Kita akan membangun seluruh ekosistem observability menggunakan Docker Compose agar dapat direplikasi dengan mudah di lingkungan staging maupun production. Buat direktori kerja baru dan masuk ke dalamnya:

mkdir -p /opt/observability-stack && cd /opt/observability-stack

Langkah 5.1: Konfigurasi Docker Compose (docker-compose.yml)

Buat file docker-compose.yml dengan konfigurasi lengkap berikut:

version: '3.8'

networks:
  obs-net:
    driver: bridge

volumes:
  prometheus_data:
  grafana_data:
  tempo_data:

services:
  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.95.0
    container_name: otel-collector
    restart: unless-stopped
    command: ["--config=/etc/otel-collector-config.yaml"]
    volumes:
      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
    ports:
      - "4317:4317" # OTLP gRPC receiver
      - "4318:4318" # OTLP HTTP receiver
    networks:
      - obs-net

  prometheus:
    image: prom/prometheus:v2.50.1
    container_name: prometheus
    restart: unless-stopped
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    networks:
      - obs-net

  tempo:
    image: grafana/tempo:2.3.1
    container_name: tempo
    restart: unless-stopped
    command: [ "-config.file=/etc/tempo.yaml" ]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
      - tempo_data:/tmp/tempo
    ports:
      - "3200:3200" # Tempo HTTP
      - "4317"      # OTLP via gRPC
    networks:
      - obs-net

  grafana:
    image: grafana/grafana:10.4.0
    container_name: grafana
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=securepassword123
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    ports:
      - "3000:3000"
    networks:
      - obs-net

Langkah 5.2: Konfigurasi OpenTelemetry Collector (otel-collector-config.yaml)

File ini mengatur bagaimana collector menerima, memproses, dan meneruskan data telemetry.

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

exporters:
  otlp/tempo:
    endpoint: "tempo:4317"
    tls:
      insecure: true

  logging:
    verbosity: detailed

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

Langkah 5.3: Konfigurasi Prometheus (prometheus.yml)

Konfigurasi target scrape untuk mengumpulkan metrik dari sistem, Nginx, dan aplikasi backend.

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:8888']

  - job_name: 'web-backend'
    static_configs:
      - targets: ['host.docker.internal:8080']

Langkah 5.4: Konfigurasi Grafana Tempo (tempo.yaml)

server:
  http_listen_port: 3200

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317

ingester:
  trace_idle_period: 10s
  max_block_bytes: 1_000_000
  max_block_duration: 5m

storage:
  trace:
    backend: local
    local:
      path: /tmp/tempo/blocks
    wal:
      path: /tmp/tempo/wal

compactor:
  compaction:
    block_retention: 48h

Langkah 5.5: Grafana Datasource Provisioning

Buat direktori provisioning Grafana:

mkdir -p /opt/observability-stack/grafana/provisioning/datasources

Buat file /opt/observability-stack/grafana/provisioning/datasources/ds.yml:

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: false

  - name: Tempo
    type: tempo
    access: proxy
    url: http://tempo:3200
    jsonData:
      httpMethod: GET
      tracesToLogsV2:
        datasourceUid: 'Prometheus'
      serviceMap:
        datasourceUid: 'Prometheus'

Langkah 5.6: Implementasi Aplikasi Backend Go Terinstrumentasi (main.go)

Sebagai contoh nyata backend web berperforma tinggi, berikut kode aplikasi Go lengkap yang mengintegrasikan OpenTelemetry SDK, Prometheus metrics exporter, serta simulasi operasi database dan cache.

package main

(
	"context"
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
	trace "go.opentelemetry.io/otel/trace"
	"google.golang.org/grpc"
)

var (
	httpRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "http_requests_total",
			Help: "Total HTTP requests processed.",
		},
		[]string{"method", "endpoint", "status"},
	)
	httpRequestDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "http_request_duration_seconds",
			Help:    "HTTP request latency distribution.",
			Buckets: prometheus.DefBuckets,
		},
		[]string{"method", "endpoint"},
	)
)

func init() {
	prometheus.MustRegister(httpRequestsTotal)
	prometheus.MustRegister(httpRequestDuration)
}

func initTracer() (*sdktrace.TracerProvider, error) {
	ctx := context.Background()
	exporter, err := otlptracegrpc.New(ctx,
		otlptracegrpc.WithInsecure(),
		otlptracegrpc.WithEndpoint("localhost:4317"),
		otlptracegrpc.WithDialOption(grpc.WithBlock()),
	)
	if err != nil {
		return nil, err
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String("production-web-backend"),
		)),
	)
	otel.SetTracerProvider(tp)
	return tp, nil
}

func handleHome(w http.ResponseWriter, r *http.Request) {
	start := time.Now()
	ctx, span := otel.Tracer("web-backend").Start(r.Context(), "GET /api/v1/resource", trace.WithSpanKind(trace.SpanKindServer))
	defer span.End()

	// Simulasi operasi database MySQL
	func() {
		_, dbSpan := otel.Tracer("web-backend").Start(ctx, "SELECT * FROM users")
		defer dbSpan.End()
		dbSpan.SetAttributes(attribute.String("db.system", "mysql"), attribute.String("db.statement", "SELECT * FROM users WHERE id = ?"))
		time.Sleep(45 * time.Millisecond)
	}()

	// Simulasi operasi Redis cache
	func() {
		_, cacheSpan := otel.Tracer("web-backend").Start(ctx, "REDIS GET session_token")
		defer cacheSpan.End()
		cacheSpan.SetAttributes(attribute.String("cache.system", "redis"), attribute.String("cache.operation", "GET"))
		time.Sleep(10 * time.Millisecond)
	}()

	status := "200"
	span.SetAttributes(attribute.Int("http.status_code", 200))
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(`{"status": "success", "message": "Observability pipeline active"}`))

	duration := time.Since(start).Seconds()
	httpRequestsTotal.WithLabelValues("GET", "/api/v1/resource", status).Inc()
	httpRequestDuration.WithLabelValues("GET", "/api/v1/resource").Observe(duration)
}

func main() {
	tp, err := initTracer()
	if err != nil {
		log.Fatalf("Failed to initialize tracer: %v", err)
	}
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Printf("Error terminating TracerProvider: %v", err)
		}
	}()

	http.HandleFunc("/api/v1/resource", handleHome)
	http.Handle("/metrics", promhttp.Handler())

	fmt.Println("Backend server running on port 8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalf("HTTP server failed: %v", err)
	}
}

6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah beberapa komponen kode paling krusial di atas:

  1. OpenTelemetry Tracer Provider Initialization (initTracer): Baris otlptracegrpc.New(...) menginisialisasi koneksi gRPC ke OpenTelemetry Collector pada port 4317. Penggunaan WithInsecure() mengizinkan komunikasi tanpa sertifikat TLS (ideal untuk jaringan internal docker bridge). Jika Anda berada di lingkungan produksi berbasis cloud publik yang memerlukan enkripsi murni antar-node, pastikan mengaktifkan WithTLSCredentials. Parameter WithBatcher sangat penting untuk mencegah bottleneck performa aplikasi; alih-alih mengirim setiap trace secara sinkron yang memblokir thread utama HTTP, trace dikumpulkan ke dalam batch memori sebelum dikirimkan secara asinkron.

  2. Context Propagation & Span Child Hierarchy (handleHome): Perhatikan bagaimana otel.Tracer(...).Start(ctx, ...) digunakan untuk mendeklarasikan Child Span (SELECT * FROM users dan REDIS GET). Ini membentuk pohon hierarki eksekusi (trace tree). Atribut kustom seperti db.system dan db.statement dimasukkan ke dalam span agar saat divisualisasikan di Grafana Tempo, SRE dapat langsung melihat query SQL eksak apa yang dieksekusi oleh backend beserta durasi milidetiknya.

  3. Prometheus Metrics Collector: Deklarasi httpRequestsTotal menggunakan CounterVec dengan label dimensi method, endpoint, dan status. Penggunaan high-cardinality labels (seperti memasukkan ID pengguna atau UUID request ke dalam label Prometheus) adalah anti-pattern fatal yang dapat menyebabkan memory explosion pada TSDB Prometheus. Pastikan label hanya berisi nilai berketetapan rendah (low-cardinality).

7. Skenario Produksi & Studi Kasus Dunia Nyata

Dalam skenario produksi nyata dengan beban traffic tinggi (misal: 10.000 Request Per Second / RPS pada platform e-commerce saat flash sale), sistem monitoring rentan mengalami overload jika tidak ditangani dengan strategi yang benar.

Studi Kasus: Mengatasi Lonjakan Latensi pada API Checkout

  1. Gejala: Grafana menampilkan lonjakan mendadak pada metrik http_request_duration_seconds untuk endpoint /api/v1/checkout dari rata-rata 50ms menjadi 3.2 detik.
  2. Investigasi via Grafana:
    • SRE membuka dashboard Prometheus untuk melihat apakah terjadi saturasi CPU atau RAM pada host backend. Ternyata utilisasi CPU masih di bawah 45%. Artinya masalah bukan pada keterbatasan sumber daya komputasi fisik.
    • SRE beralih ke menu Explore di Grafana, memilih datasource Tempo, dan memfilter traces berdasarkan durasi > 2s dan status 500/200.
    • Visualisasi Flame Graph dari Tempo langsung memperlihatkan bahwa bottleneck terjadi pada span REDIS GET inventory_lock yang memakan waktu 2.8 detik akibat terjadinya Redis connection pool exhaustion dan lock contention.
  3. Resolusi Cepat:
    • Tim infrastruktur segera meningkatkan ukuran connection pool Redis pada file konfigurasi aplikasi dan menambah replica node Redis Sentinel.
    • Metrik latency kembali normal dalam waktu kurang dari 3 menit setelah penerapan konfigurasi baru, dibuktikan langsung oleh penurunan grafik latensi di Grafana.

8. Common Pitfalls, Anti-Patterns & Solusi

Berikut adalah kesalahan fatal yang sering dilakukan oleh pengembang maupun administrator saat mengimplementasikan observability:

  • Anti-Pattern 1: Menggunakan High-Cardinality pada Label Prometheus

    • Masalah: Menyimpan alamat IP klien, email pengguna, atau ID transaksi unik ke dalam label metrik Prometheus. Hal ini menyebabkan jumlah deret waktu (time-series) membengkak jutaan kali lipat, menghabiskan seluruh memori RAM server Prometheus, dan berujung pada crash total (OOM Killed).
    • Solusi: Simpan data unik tersebut di dalam Log atau Traces (OpenTelemetry), bukan di dalam metrik Prometheus.
  • Anti-Pattern 2: Tidak Mengatur Sampling Rate pada Distributed Tracing

    • Masalah: Mengirimkan 100% dari seluruh trace produksi (1:1 sampling) ke Tempo Collector pada traffic tinggi. Ini menyebabkan saturasi bandwidth jaringan yang masif dan biaya penyimpanan disk yang tidak terkontrol.
    • Solusi: Terapkan Head-based atau Tail-based sampling di OpenTelemetry Collector (misal: hanya mengambil 5% dari request normal, namun mengambil 100% dari request yang menghasilkan error atau latensi > 1 detik).
  • Anti-Pattern 3: Mengabaikan Keamanan Endpoint Metrik

    • Masalah: Mengekspos endpoint /metrics atau /debug/pprof ke publik tanpa autentikasi, membiarkan penyerang memetakan struktur internal aplikasi.
    • Solusi: Batasi akses endpoint metrik hanya untuk IP internal Prometheus melalui konfigurasi Nginx reverse proxy atau gunakan mTLS.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memastikan sistem observability kita sendiri tidak menjadi beban bagi aplikasi utama, lakukan pengujian beban (load testing) menggunakan tool industri seperti k6 atau wrk.

Buat file skrip k6 (load-test.js) untuk menguji aplikasi Go kita:

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 50 },  // Ramp-up ke 50 VUs
    { duration: '1m', target: 200 },  // Pertahankan beban 200 VUs
    { duration: '30s', target: 0 },   // Ramp-down
  ],
};

export default function () {
  const res = http.get('http://localhost:8080/api/v1/resource');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 100ms': (r) => r.timings.duration < 100,
  });
  sleep(0.1);
}

Jalankan benchmark:

k6 run load-test.js

Parameter Tuning Lanjutan untuk Produksi:

  1. Prometheus TSDB Retention: Atur batas retensi penyimpanan data metrik agar disk tidak penuh secara tidak terkendali dengan menambahkan flag --storage.tsdb.retention.time=15d pada argumen Prometheus.
  2. OTel Collector Memory Limiter: Tambahkan prosesor memory_limiter pada otel-collector-config.yaml untuk mencegah OTel Collector mengalami crash akibat lonjakan memori mendadak.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan sistem observability ini ke lingkungan live production, pastikan Anda telah memverifikasi seluruh item dalam checklist berikut:

  • Semua kontainer Docker berjalan dengan kebijakan restart: unless-stopped.
  • Endpoint /metrics dan OTLP port terlindung dari akses publik eksternal (menggunakan firewall atau private Docker network).
  • Konfigurasi Retention Time Prometheus dan Tempo telah disesuaikan dengan kapasitas disk server.
  • Dashboard Grafana telah dilengkapi dengan Alerting Rules krusial (Notifikasi Telegram/Slack saat error rate > 1% atau latensi p99 > 500ms).
  • Uji coba pemulihan bencana (Disaster Recovery) pada database metrics dan penyimpanan traces telah dilakukan.

Dengan mengintegrasikan Prometheus untuk metrik, Grafana untuk visualisasi terpadu, dan OpenTelemetry untuk distributed tracing secara tepat, organisasi Anda tidak lagi menerbangkan pesawat dalam kabut tebal. Setiap anomali performa dapat dideteksi sebelum berdampak buruk pada pengguna akhir, memastikan ketersediaan sistem (high availability) di level enterprise tercapai dengan sempurna.

🏷️ Tags: #Devops #Sre #Opentelemetry #Prometheus #Grafana