Jika kita bicara soal monitoring dan observability di aplikasi modern, maka logging adalah denyut nadinya. Tidak ada yang lebih menyebalkan daripada bug yang hanya muncul “kadang-kadang” tanpa log yang cukup untuk tracing—sebuah mimpi buruk bagi developer backend mana pun.
Biasanya, kita menambahkan logging di berbagai bagian aplikasi, dari controller, service layer, hingga data layer. Tapi, jika kamu mendesain API atau back-end yang scalable, kamu pasti ingin logging yang fleksibel, terstruktur, context-aware, dan minimal overheat.
Di artikel ini, kita akan bahas bagaimana membangun Logging Interceptor dengan Context Awareness—interceptor yang bisa mencatat dengan pintar, dapat membaca context (misal, user ID, request ID, source tracing), dan scalable tanpa membanjiri log dengan noise.
TL;DR
- Logging interceptor = solusi lintas-cutting concern untuk pencatatan request/response secara global.
- Context membantu log tetap informatif: user, endpoint, trace ID, dan lainnya bisa otomatis masuk log.
- Simulasi dibuat dengan bahasa Go, namun konsep dapat diaplikasikan di banyak bahasa (Java Spring, .NET Middleware, dsb).
- Disertai contoh kode, tabel perbandingan, dan diagram alur.
Apa itu Logging Interceptor?
Interceptor (atau kadang disebut middleware) adalah mekanisme yang memungkinkan kita melakukan sesuatu sebelum atau setelah request/goroutine dieksekusi—tanpa harus mengotak-atik kode di semua handler. Cocok untuk logging, validasi, rate limit, dsb.
Pola ini banyak ditemukan di framework modern:
- Go:
http.Handler
,grpc.UnaryInterceptor
- Java Spring:
HandlerInterceptor
,Filter
- .NET:
Middleware
Mengapa Pakai Context?
Salah satu tantangan log tradisional:
- Konteks hilang… Misal, “Internal Server Error on endpoint GET /order/123 by user X”, kalau log-nya global, user tidak kelihatan.
- Sulit menghubungkan trace antara microservice/module.
- Susah debug kasus tertentu, karena log yang terkelompok kurang rapi.
Dengan Context, kita bisa:
- Inject trace ID/request ID.
- Tambahkan user ID/session info.
- Pasangkan metadata seperti elapsed time.
- Lempar context ini ke seluruh handler/layer.
Studi Kasus: Logging Interceptor pada HTTP API (Golang)
Mari kita simulasikan dengan Go. Namun, kamu bisa menerapkan prinsip ini di framework lain.
1. Logging Utility Siap Context
package logger
import (
"context"
"log"
)
type contextKey string
const (
TraceIDKey contextKey = "trace_id"
UserIDKey contextKey = "user_id"
)
func WithTraceID(ctx context.Context, traceID string) context.Context {
return context.WithValue(ctx, TraceIDKey, traceID)
}
func WithUserID(ctx context.Context, userID string) context.Context {
return context.WithValue(ctx, UserIDKey, userID)
}
func LogWithContext(ctx context.Context, msg string, args ...interface{}) {
traceID, _ := ctx.Value(TraceIDKey).(string)
userID, _ := ctx.Value(UserIDKey).(string)
log.Printf("[TraceID:%s][UserID:%s] %s", traceID, userID, fmt.Sprintf(msg, args...))
}
2. Middleware: Logging Interceptor
package middleware
import (
"net/http"
"github.com/yourmodule/logger"
"github.com/google/uuid"
)
func LoggingInterceptor(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
traceID := uuid.New().String()
// Misalkan kita dapatkan userID dari header
userID := r.Header.Get("X-User-ID")
ctx := logger.WithTraceID(r.Context(), traceID)
if userID != "" {
ctx = logger.WithUserID(ctx, userID)
}
logger.LogWithContext(ctx, "Incoming request %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r.WithContext(ctx))
logger.LogWithContext(ctx, "Completed request %s %s", r.Method, r.URL.Path)
})
}
3. Usage di Main
mux := http.NewServeMux()
mux.HandleFunc("/hello", handlerWithLog)
logged := middleware.LoggingInterceptor(mux)
http.ListenAndServe(":8080", logged)
4. Handler di Bawah Bisa Tetap Context-Aware!
func handlerWithLog(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger.LogWithContext(ctx, "Process utama berjalan...")
// ... kode lainnya
fmt.Fprintln(w, "Hello World")
}
Simulasi Hasil Log
Mari lihat simulasi output logging kita:
Time | TraceID | UserID | Event | Info |
---|---|---|---|---|
13:01:02 | abc-123 | 999 | Incoming request | GET /hello |
13:01:02 | abc-123 | 999 | Process utama | … |
13:01:02 | abc-123 | 999 | Completed request | GET /hello |
Dengan context, semua log entry terkait satu permintaan akan punya TraceID & UserID yang sama.
Diagram Alur: Logging Interceptor
sequenceDiagram participant Client participant Interceptor participant Handler Client->>Interceptor: Kirim HTTP Request Interceptor->>Interceptor: Buat TraceID & baca UserID Interceptor->>Interceptor: Inject ke Context Interceptor->>Interceptor: Log "incoming request" Interceptor->>Handler: Lanjutkan ke Handler (dengan Context) Handler->>Interceptor: Selesai Handle Interceptor->>Interceptor: Log "completed request" Interceptor->>Client: Response
Kelebihan & Tantangan Logging Interceptor Context-Aware
Kelebihan | Tantangan |
---|---|
Tidak perlu kopi-paste logging di setiap handler | Distribusi context di background routine |
Siap scale-out, trace otomatis | Potensi issue bila context salah propagate |
Mudah debug satu sesi request end-to-end | Overhead kecil jika log sangat verbose |
Bisa extend (user agent, ip addr, dsb) | Pemahaman context di seluruh tim developer |
Best Practice
- Log seperlunya. Jangan log seluruh payload jika tidak dibutuhkan.
- Awas privacy. Jangan tulis sensitive info ke log.
- Inject ke context layer sedini mungkin—ideal di gateway/middleware.
- Favor struktur log JSON untuk parsing yang lebih mudah oleh ELK/Splunk.
Kesimpulan
Penerapan Logging Interceptor dengan Context adalah langkah sederhana namun vital untuk mendapatkan log yang bermakna, terstruktur, dan traceable. Dengan pattern ini, tracing masalah jadi jauh lebih produktif—no more “misteri di server log”—dan monitoring microservice jadi scalable.
Pattern ini kompatibel dengan hampir seluruh bahasa dan framework modern. Jadi engineer yang peduli observability dan debugging efisien? Segera refactor logger-mu berbasis context-aware!
Mau diskusi lebih lanjut? Drop pertanyaanmu di kolom komentar!
11 Apa Itu Skema GraphQL? Konsep dan Komponen
Artikel Terhangat
12 Menulis File Skema GraphQL Pertama Anda
07 Jul 2025
34 Logging Interceptor dengan Context
07 Jul 2025
33 Menulis Stream Interceptor Sendiri
07 Jul 2025
32 Menulis Unary Interceptor Sendiri
07 Jul 2025
31 Apa Itu Interceptor dalam gRPC?
07 Jul 2025

12 Menulis File Skema GraphQL Pertama Anda

34 Logging Interceptor dengan Context

33 Menulis Stream Interceptor Sendiri

32 Menulis Unary Interceptor Sendiri
