Nginx 存取日誌:每個欄位的意義與分析方法
Nginx 存取日誌會記錄你的網頁伺服器所處理的每一個請求。當你在除錯 404 錯誤、追查緩慢的端點,或調查可疑流量時,這裡是第一個該查看的地方。然而,許多開發者只是匆匆掃過原始日誌行,而沒有完全理解每個欄位的意義。本指南將詳細解析 Nginx 的預設日誌格式,示範如何自訂格式,並使用標準命令列工具帶你走過實用的分析技巧。
Nginx 預設存取日誌格式
開箱即用,Nginx 使用 combined 日誌格式,看起來像這樣:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
一個典型的日誌行:
192.0.2.1 - - [10/Oct/2023:13:55:36 +0000] "GET /api/users HTTP/1.1" 200 1234 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
逐欄位說明
| 欄位 | 變數 | 說明 |
|---|---|---|
| 遠端位址 | $remote_addr | 發出請求的用戶端 IP 位址。 |
| 遠端使用者 | $remote_user | 若使用 HTTP 驗證則為使用者名稱;否則為 -。 |
| 本機時間 | $time_local | 伺服器本機時間,格式為 [日/月/年:時:分:秒 時區]。 |
| 請求 | $request | 完整的請求行:方法、路徑和 HTTP 協定。 |
| 狀態 | $status | HTTP 回應狀態碼(例如 200、404、500)。 |
| 傳送的主體位元組 | $body_bytes_sent | 回應主體的大小(以位元組為單位),不含標頭。 |
| 參照位址 | $http_referer | 連結至該請求的頁面(若用戶端有提供)。 |
| 使用者代理 | $http_user_agent | 用戶端軟體字串(瀏覽器、機器人、工具)。 |
自訂日誌格式
你可以定義自己的格式來擷取更多細節,例如請求時間、上游回應時間或 gzip 壓縮率。在 http 區塊中新增 log_format 指令,並在 access_log 中引用它。
http {
log_format detailed '$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"';
access_log /var/log/nginx/access.log detailed;
}
常見的額外變數:
$request_time– 從接收到第一個位元組到傳送出最後一個位元組的總時間。$upstream_response_time– 等待上游(例如 PHP-FPM、Node.js)所花費的時間。$gzip_ratio– 若啟用 gzip 則為壓縮率。$http_x_forwarded_for– 位於代理或負載平衡器後方時的原始用戶端 IP。
使用命令列工具分析 Nginx 日誌
你不需要昂貴的軟體就能萃取洞見。標準的 Unix 工具如 grep、awk、sort 和 uniq 對大多數任務來說已經足夠強大。
1. 找出最頻繁的 IP 位址
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
這有助於識別高流量來源或潛在的 DDoS 攻擊來源。
2. 找出最常被請求的 URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
可用於了解熱門內容或發現異常模式。
3. 統計 HTTP 狀態碼
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
快速查看有多少 404 或 500 錯誤正在發生。
4. 找出回應時間緩慢的請求
如果你在日誌格式中加入了 $request_time,你可以篩選出緩慢的請求:
awk '{ if ($NF > 1) print }' /var/log/nginx/access.log
視需要調整閾值(此處為 1 秒)。
5. 偵測可疑的使用者代理
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
尋找已知的惡意機器人或異常的用戶端。
實際應用案例
- 疑難排解: 將 500 錯誤與特定端點或上游回應時間關聯起來。
- 效能調校: 找出緩慢的頁面並最佳化資料庫查詢或快取。
- 安全監控: 發現暴力破解嘗試(來自同一 IP 的大量 401/403)或 URL 中的 SQL 注入模式。
- 容量規劃: 追蹤一段時間內的請求量,以預測擴展需求。
使用日誌解析器自動化分析
雖然命令列一行指令適合臨時查詢,但定期報告則受益於專用工具。你可以使用開源日誌分析器如 GoAccess 或 AWStats,或建立自訂指令碼。若想快速、以瀏覽器為基礎進行解析而不需安裝任何東西,Nginx Log Analyzer 讓你貼上日誌行並立即取得狀態碼、熱門 IP 和請求路徑的摘要。
日誌管理最佳實務
- 定期輪替日誌: 使用
logrotate以防止磁碟空間問題。 - 集中管理日誌: 傳送至日誌管理系統(例如 ELK、Graylog)以進行長期儲存和搜尋。
- 加入請求 ID: 新增
$request_id以與應用程式日誌關聯。 - 尊重隱私: 若 GDPR 或其他法規要求,請匿名化 IP。
常見問題
Nginx 中的存取日誌和錯誤日誌有什麼區別?
存取日誌記錄 Nginx 處理的每一個請求,包括用戶端 IP、請求方法、狀態碼和使用者代理。錯誤日誌則擷取有關伺服器問題的診斷訊息,例如連線失敗、設定錯誤或上游逾時。兩者對於不同的疑難排解情境都至關重要。
當 Nginx 位於負載平衡器後方時,如何查看真實的用戶端 IP?
當 Nginx 位於代理或負載平衡器後方時,$remote_addr 會顯示平衡器的 IP。若要記錄原始用戶端 IP,請設定 real_ip 模組以信任平衡器的 IP,並在日誌格式中使用 $http_x_forwarded_for 或 $realip_remote_addr。
我可以在不安裝軟體的情況下分析 Nginx 日誌嗎?
可以。你可以直接在終端機中使用標準 Unix 指令如 grep、awk 和 sort。若想使用圖形化、以瀏覽器為基礎的方式,線上工具如 Nginx Log Analyzer 無需任何安裝即可提供快速洞見。
準備好深入探索你的日誌了嗎?試試 Nginx Log Analyzer,在幾秒內解析並視覺化你的存取日誌——無需設定。