1. 前言
在 Nginx 服務器中,如果想對日志輸出進行控制還是很容易的。Nginx 服務器提供了一個 HttpLogModule 模塊,可以通過它來設置日志的輸出格式。
2. HttpLogModule 模塊
2.1 示例
2.2 指令
指令名稱:access_log
語法:access_log [format [buffer=size] ] | off
默認值:access_log logs/access.log combined;
使用環境:http, server, location, if in location, limit_except
指令名稱:log_format
語法:log_format name [escape=default|json|none] string ...;
默認值:log_format combined "...";
使用環境:http
Nginx 日志格式中,有很多參數,總結如下:

參數 說明 示例 $remote_addr 客戶端地址 14.116.133.170 $remote_user 客戶端用戶名稱 -- $time_local 訪問時間和時區 03/Mar/2019:16:43:53 +0800 $request 請求的URI和HTTP協議 "GET /city/static/js/illegals/vehicle-search.js HTTP/1.1" $http_host 請求地址,即瀏覽器中你輸入的地址(IP或域名) www.super.com 192.168.118.15 $status HTTP請求狀態 200 $upstream_status upstream狀態 200 $body_bytes_sent 發送給客戶端文件內容大小 1547 $http_referer url跳轉來源 https://www.baidu.com/ $http_user_agent 用戶終端瀏覽器等信息 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0 $ssl_protocol SSL協議版本 TLSv1 $ssl_cipher 交換數據中的算法 RC4-SHA $upstream_addr 后台upstream的地址,即真正提供服務的主機地址 192.168.118.16:8080 $request_time 整個請求的總時間 0.205 $upstream_response_time 請求過程中,upstream響應時間 0.002
指令名稱:open_log_file_cache
語法:open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time]; | open_log_file_cache off;
默認值:open_log_file_cache off;
使用環境:http、server、location
max - 該選項用來設置在緩存中可以存儲的最大文件描述符數量。它通過最近最少使用(LRU)算法來移除緩存條目 inactive - 該選項用來設置一個時間間隔。在這個時間間隔之后,沒有被命中的文件描述符將會被移除,默認值是10秒 min_uses - 該選項用來設置訪問次數。在一定時間間隔內,一個文件描述符至少被訪問多少次后就可以將該文件描述符放在緩存中,默認為 1,即訪問一次便緩存 valid - 該選項用於設置檢查同名文件存在的時間,默認為60秒 off - 關閉緩存 示例: open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
2.3 測試
首先,查看下 nginx 默認的日志格式:
測試訪問,查看日志:
注意:這里有兩個 '- -' 第一個 '-' 是 log_format 中定義的,第二個 '-' 是 $remote_user 變量為null時,返回的占位符。
這些變量通過上面表對比就能明白。
默認的日志格式可能不滿足我們日常問題的排查,可以自行定義,這里通過是否需要轉發后端服務器來分為 2類進行定義日志格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" "$request_time"'; log_format remote_main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" "$request_time" "$upstream_response_time" "$upstream_addr" "$upstream_status"';
為了能夠盡快的通過日志查詢到異常情況,這里建議取消 http 段的全局定義日志,改為每個location 中定義一個日志文件。這樣除了異常,可以快速定位。
access_log xxx buffer = 32k flush =5s;
這里非常有必要說一下,如果這樣設置了,日志是不會實時刷新的,buffer 滿 32k 才寫盤;假如 buffer 不滿 5s 鍾后強制寫盤。
最后,別忘記加上日志緩存,有利於減少服務器資源消耗。
2.4 測試
通過訪問:
curl http://10.0.10.158/ 返回的日志查看
最后一位是 $request_time 整個請求的總時間,我們這里只是很短的字符串測試,所以很快就處理完成。記錄為 0.000
curl http://10.0.10.158/apache/index.html
通過這樣一條日志,能夠很清晰的看出來:
用戶請求訪問的uri:GET /apache/index.html
整個請求總耗時:0.002
后端處理耗時:0.002
后端處理請求主機socket:"10.0.10.159:8080"
后端處理返回狀態:200