Belajar Golang - Observability, Logging & Tracing
Episode 14 of 19

Belajar Golang - Observability, Logging & Tracing

Episode ini menjadikan aplikasi Go observable: logging terstruktur dengan zap, logrus, atau zerolog, tracing terdistribusi dengan OpenTelemetry, dan metrik terstruktur dengan Prometheus client, lengkap dengan contoh integrasi dan ekspor endpoint.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Saat aplikasi berjalan di production, kalian tidak bisa menempelkan debugger. Satu-satunya cara memahami perilaku adalah observability: log, metrik, dan trace yang bisa dipertanyakan. Go memiliki ekosistem observability yang matang dan terintegrasi dengan toolchain resminya.

Episode 14 membahas tiga pilar: logging terstruktur dengan zap, logrus, atau zerolog; tracing terdistribusi dengan OpenTelemetry; dan metrik terstruktur dengan Prometheus client. Di akhir episode, kalian bisa menjawab pertanyaan "apa yang terjadi dengan layanan saya" secara kuantitatif.

Logging Terstruktur

Mengapa Bukan fmt.Println

Log teks polos sulit dianalisis mesin. Log terstruktur menyimpan pasangan kunci-nilai sehingga bisa difilter dan diagregasi oleh Elasticsearch, Loki, atau CloudWatch. zerolog adalah pilihan populer karena sangat cepat dan berorientasi zero-allocation.

Menambah zerolog
go get github.com/rs/zerolog/log
Log terstruktur dengan zerolog
package main
 
import "github.com/rs/zerolog/log"
 
func main() {
	log.Info().
		Str("service", "api").
		Int("port", 8080).
		Msg("server mulai berjalan")
}

Output berupa JSON: setiap field menjadi kunci yang bisa dicari. zap dari Uber dan logrus menawarkan fitur serupa dengan gaya API yang berbeda. Konsistensi satu library di seluruh tim lebih penting daripada pilihan library-nya.

Level Logging

Atur level melalui environment variable: debug untuk development, info di staging, dan warn di production. Hindari log level debug yang terlalu detail di production karena biaya disk dan CPU.

Level dari environment
log.Logger = log.With().Timestamp().Logger()
log.Warn().Str("event", "retry").Int("attempt", 2).Msg("coba ulang")

Tracing Terdistribusi dengan OpenTelemetry

Konsep Trace dan Span

Dalam arsitektur microservices, sebuah request melewati banyak service. Trace menghubungkan seluruh operasi ini, dan span adalah satu unit kerja di dalamnya. OpenTelemetry adalah standar terbuka untuk menghasilkan dan mengumpulkan telemetri ini.

Menambah OpenTelemetry
go get go.opentelemetry.io/otel
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp

Instrumentasi Handler HTTP

Contoh instrumentasi HTTP dengan middleware OpenTelemetry:

Tracer HTTP
package main
 
import (
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/trace"
)
 
func main() {
	tracer := otel.Tracer("service-api")
 
	_ = trace.SpanFromContext
	_, span := tracer.Start(ctx, "proses-pengguna")
	defer span.End()
}

Span membawa atribut seperti nama operasi dan status. Setiap span memiliki trace ID yang sama untuk satu request, sehingga alat visualisasi seperti Jaeger atau Grafana Tempo bisa menampilkan perjalanan lengkap request antar service.

Propagasi Konteks

Agar trace menyambung antar service, header seperti traceparent harus diteruskan. OpenTelemetry menangani propagasi ini lewat middleware HTTP otomatis. Di sisi klien, paket net/http diinstrumentasi dengan otelhttp sehingga setiap request keluar otomatis membawa konteks.

Metrik dengan Prometheus Client

Counter, Gauge, dan Histogram

Prometheus client untuk Go menyediakan tiga tipe metrik utama: Counter untuk nilai yang hanya naik seperti jumlah request, Gauge untuk nilai yang naik-turun seperti koneksi aktif, dan Histogram untuk distribusi durasi.

Menambah Prometheus client
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp

Mencatat dan Mengekspor Metrik

Metrik request counter
package main
 
import (
	"net/http"
 
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)
 
var jumlahRequest = prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Name: "http_requests_total",
		Help: "Total request HTTP per route",
	},
	[]string{"route"},
)
 
func main() {
	prometheus.MustRegister(jumlahRequest)
	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":8080", nil)
}

Endpoint /metrics diekspor dalam format Prometheus dan dikumpulkan oleh scraper. Grafana lalu memvisualisasikan metrik ini menjadi dashboard. Untuk memeriksa endpoint secara lokal, curl localhost:8080/metrics menampilkan seluruh metrik dalam format teks Prometheus.

RED dan USE Method

Saat memilih metrik, pakai kerangka RED (Rate, Errors, Duration) untuk service: berapa request per detik, berapa yang error, dan berapa durasinya. Kerangka USE (Utilization, Saturation, Errors) berlaku untuk resource seperti CPU dan memori. Keduanya memastikan kalian mengukur hal yang benar.

Penutup

Episode 14 menjadikan aplikasi Go kalian observable: logging terstruktur dengan zerolog, zap, atau logrus dalam format JSON; tracing terdistribusi dengan OpenTelemetry dan propagasi konteks; serta metrik Counter, Gauge, dan Histogram dengan Prometheus client yang diekspor lewat /metrics.

Inti yang harus dibawa pulang:

  • Log terstruktur berbentuk JSON agar bisa diagregasi mesin.
  • Level log dikendalikan environment: debug, info, warn, error.
  • Trace menghubungkan operasi lintas service lewat span.
  • OpenTelemetry adalah standar terbuka untuk tracing.
  • Prometheus mengekspor metrik Counter, Gauge, dan Histogram.
  • Gunakan metode RED dan USE untuk memilih metrik yang tepat.

Di episode 15 selanjutnya kita akan membahas resilience, graceful shutdown, dan health checks — menutup service dengan elegan lewat context dan OS signals, menyediakan health checks dan readiness probes untuk Kubernetes, serta circuit breaker dan retry policy untuk panggilan eksternal yang tidak stabil.

Belajar Golang - Observability, Logging & Tracing | Belajar Golang