Format Log Kustom #
Format log default Nginx sudah cukup untuk kebutuhan dasar, tapi seiring aplikasi berkembang, kamu akan butuh informasi lebih di log — response time backend, status cache, request ID, atau bahkan field dari header aplikasi. Nginx memudahkan ini dengan log_format yang bisa menggunakan variabel apapun.
Menambahkan Field Performa #
Format yang paling sering dikustomisasi menambahkan data timing untuk analisis performa:
http {
log_format performance '$remote_addr [$time_local] '
'"$request" $status '
'$body_bytes_sent '
'$request_time ' # Total waktu dari terima request hingga kirim response
'$upstream_response_time ' # Waktu backend memproses
'$upstream_cache_status'; # HIT/MISS/BYPASS
access_log /var/log/nginx/access.log performance;
}
Dengan format ini, kamu bisa langsung melihat apakah request lambat karena backend lambat ($upstream_response_time tinggi) atau karena masalah network ke klien (selisih $request_time dan $upstream_response_time besar).
Format JSON untuk Log Aggregator #
Jika menggunakan sistem log terpusat (ELK Stack, Grafana Loki, Datadog, Splunk), format JSON jauh lebih mudah diparsing daripada format teks:
http {
log_format json_combined escape=json
'{'
'"timestamp":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request_method":"$request_method",'
'"request_uri":"$uri",'
'"query_string":"$args",'
'"status":$status,'
'"bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_response_time":"$upstream_response_time",'
'"upstream_cache_status":"$upstream_cache_status",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher"'
'}';
access_log /var/log/nginx/access.json json_combined;
}
Parameter escape=json penting — ia memastikan karakter khusus dalam nilai variabel (seperti tanda kutip atau backslash) di-escape dengan benar sehingga JSON selalu valid.
Menambahkan Request ID untuk Tracing #
Dalam arsitektur microservice, melacak satu request yang melewati banyak service membutuhkan request ID yang unik. Nginx bisa membuat dan mencatatnya:
http {
# Gunakan kombinasi IP dan timestamp sebagai request ID sederhana
# Untuk ID yang benar-benar unik, gunakan modul ngx_http_unique_id
map $time_msec $request_id_header {
default $request_id;
}
log_format trace '$remote_addr [$time_local] '
'"$request" $status '
'reqid=$request_id ' # Variabel bawaan Nginx 1.11.0+
'rt=$request_time';
server {
# Sertakan request ID di response header agar klien bisa melapor
add_header X-Request-ID $request_id always;
# Teruskan ke backend agar backend bisa mencatat di log mereka
proxy_set_header X-Request-ID $request_id;
access_log /var/log/nginx/access.log trace;
}
}
$request_id tersedia sejak Nginx 1.11.0 — berupa string hex 16 byte yang di-generate acak untuk setiap request.
Conditional Logging: Log Hanya Request Tertentu #
Kadang kamu tidak ingin log semua request — misalnya abaikan health check, atau hanya log error:
http {
# Buat variabel: 0 = jangan log, 1 = log
map $status $loggable {
~^[23] 0; # Jangan log 2xx dan 3xx
default 1; # Log semua error (4xx, 5xx)
}
# Syntax: access_log path format if=variabel
access_log /var/log/nginx/errors.log combined if=$loggable;
}
Contoh lain — log hanya request yang lambat:
http {
map $request_time $slow_request {
default 0;
~^[1-9] 1; # Request yang butuh >= 1 detik
}
access_log /var/log/nginx/slow.log performance if=$slow_request;
access_log /var/log/nginx/access.log combined; # Log semua ke file utama
}
Dengan pola ini kamu bisa punya dua file log: satu untuk semua request, satu khusus untuk request lambat yang perlu diinvestigasi.
Menyertakan Header dari Aplikasi #
Backend sering mengirim header khusus yang berguna untuk debugging. Kamu bisa mencatatnya di log:
http {
log_format app_debug '$remote_addr [$time_local] '
'"$request" $status '
'$upstream_http_x_request_id ' # Header X-Request-ID dari backend
'$upstream_http_x_powered_by ' # Header X-Powered-By dari backend
'"$upstream_http_x_debug_info"'; # Header debug kustom dari backend
# Pola: $upstream_http_NAMA_HEADER
# Gunakan huruf kecil dan ganti tanda hubung dengan underscore
}
Ringkasan #
- Tambahkan
$request_timedan$upstream_response_timeke format log untuk membedakan lambat di backend vs lambat di jaringan.- Gunakan
escape=jsondan format JSON untuk integrasi dengan ELK, Loki, atau Datadog — tidak perlu konfigurasi parser tambahan.$request_id(Nginx ≥ 1.11.0) memberikan ID unik per request yang bisa diteruskan ke backend untuk distributed tracing.- Conditional logging dengan
if=memungkinkan log selektif — misalnya hanya log error atau hanya request yang lambat.- Akses header dari backend di log menggunakan
$upstream_http_NAMA— berguna untuk mencatat request ID yang di-generate backend.