Format Log yang Berguna
log_format terperinci '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time '
'cache=$upstream_cache_status';
access_log /var/log/nginx/access.log terperinci;
error_log /var/log/nginx/error.log warn;
$upstream_response_time mengukur waktu hulu bekerja; $request_time mengukur seluruh perjalanan hingga byte terakhir sampai ke klien. Bila hulu 0,05 detik tetapi total 4 detik, hulu tidak bersalah — jaringan klien lambat, atau balasan besar sedang dikirim tanpa buffering. Tanpa dua angka ini terpisah, tim aplikasi dan tim infrastruktur akan saling menyalahkan tanpa bukti.
Membaca Kode Status yang Sering Membingungkan
502 Bad Gateway hulu menolak koneksi atau memutusnya
→ proses hulu mati, port salah, crash
504 Gateway Timeout hulu terhubung tapi tidak membalas tepat waktu
→ hulu lambat, atau proxy_read_timeout terlalu pendek
499 Client Closed klien pergi sebelum balasan selesai
→ pengguna menutup tab, atau batas waktu di sisi klien
413 Too Large client_max_body_size terlampaui
504 vs 502 periksa mana yang muncul — artinya berbeda jauh
Kode 499 khusus Nginx dan sering diabaikan karena "klien yang pergi". Namun bila jumlahnya melonjak, biasanya klien menyerah karena batas waktunya sendiri lebih pendek daripada waktu balasan aplikasi. Perbaikannya ada di kecepatan hulu, bukan di Nginx.
Log Kesalahan Adalah Sumber Kebenaran
tail -f /var/log/nginx/error.log connect() failed (111: Connection refused) → hulu tidak berjalan upstream timed out (110: Connection timed out) → hulu lambat no live upstreams → semua hulu ditandai gagal too many open files → batas deskriptor berkas SSL_do_handshake() failed → ketidakcocokan TLS directory index of "/var/www/" is forbidden → tidak ada index dan autoindex mati
Debug pada Satu Klien Saja
error_log /var/log/nginx/debug.log debug;
events {
debug_connection 203.0.113.42; # hanya IP ini yang dicatat rinci
}
Level debug menghasilkan puluhan baris untuk setiap permintaan. Pada lalu lintas produksi, disk dapat penuh dalam hitungan menit — dan disk penuh menjatuhkan seluruh server, bukan hanya menghentikan pencatatan. Gunakan debug_connection agar hanya alamat tertentu yang dicatat rinci. Modul debug juga harus tersedia; periksa dengan nginx -V mencari --with-debug.
Halaman Status
location = /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106
Angka accepts dan handled yang berbeda adalah tanda bahaya: artinya sebagian koneksi diterima lalu dijatuhkan, biasanya karena batas worker_connections atau deskriptor berkas tercapai.
Rotasi Log
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
Worker Nginx memegang deskriptor berkas yang terbuka. Setelah mv atau rm, worker tetap menulis ke inode lama yang sudah tak bernama — ruang disk tidak kembali dan log baru tidak muncul. Sinyal USR1 menyuruh Nginx menutup dan membuka kembali berkas lognya. Inilah alasan blok postrotate di atas wajib ada.