Kodeloka
  1. Kodeloka
  2. Kelas Nginx
  3. Materi

5 · Operasi · Modul 8 dari 8

Log, Diagnosis & Penelusuran Masalah

Membaca log yang tepat, dan mengenali penyebab sesungguhnya di balik 502, 504, dan 499.

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;
💡 Selisih $request_time dan $upstream_response_time adalah petunjuk utama

$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
⚠️ Lonjakan 499 hampir selalu berarti aplikasi terlalu lambat

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
}
🚫 Jangan menyalakan level debug secara global di produksi

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
}
🚫 Memindahkan berkas log tidak membebaskan ruang disk

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.