nginx日誌共三個引數。
access_log: 定義日誌的路徑及格式。
log_format: 定義日誌的模板。
open_log_file_cache: 定義日誌檔案快取。
nginx access日誌配置
access_log日誌配置
access_log用來定義日誌級別,日誌位置。語法如下:
日誌級別: debug > info > notice > warn > error > crit > alert > emerg
語法格式: access_log path [format [buffer=size] [gzip[=level]]
[flush=time] [if=condition]];access_log off; 預設值 : access_log logs/access.log combined; 作用域 : http, server, location, if in
location, limit_except
• path 指定日誌的存放位置。
• format 指定日誌的格式。預設使用預定義的combined。
• buffer 用來指定日誌寫入時的快取大小。預設是64k。
• gzip 日誌寫入前先進行壓縮。壓縮率可以指定,從1到9數值越大壓縮比越高,同時壓縮的速度也越慢。預設是1。
• flush 設定快取的有效時間。如果超過flush指定的時間,快取中的內容將被清空。
• if 條件判斷。如果指定的條件計算為0或空字串,那麼該請求不會寫入日誌。
另外,還有一個特殊的值off。如果指定了該值,當前作用域下的所有的請求日誌都被關閉。
示例:
基本用法
access_log /var/logs/nginx-access.log
該例子指定日誌的寫入路徑為/var/logs/nginx-access.log,日誌格式使用預設的combined。
access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m
該例子指定日誌的寫入路徑為/var/logs/nginx-access.log,日誌格式使用預設的combined,指定日誌的快取大小為32k,日誌寫入前啟用gzip進行壓縮,壓縮比使用預設值1,快取資料有效時間為1分鐘。
log_format 定義日誌格式
語法格式: log_format name [escape=default|json] string ...;
預設值 : log_format combined "...";
作用域 : http
• name 格式名稱。在access_log指令中引用。
• escape 設定變數中的字元編碼方式是json還是default,預設是default。
• string 要定義的日誌格式內容。該引數可以有多個。引數中可以使用Nginx變數。
示例:
access_log /var/logs/nginx-access.log main log_format main
'$remote_addr - $remote_user [$time_local] "$request"' '$status
$body_bytes_sent "$http_referer"' '"$http_user_agent"
"$http_x_forwarded_for"';
我們使用log_format指令定義了一個main的格式,並在access_log指令中引用了它。假如客戶端有發起請求:https://suyunfe.com/,我們看一下我擷取的一個請求的日誌記錄:
124.78.32.26 - - [12/Mar/2022:22:18:20 +0800] "GET / HTTP/1.1" 200 569 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51
Safari/537.36" "-"
我們看到最終的日誌記錄中$remote_user、$http_referer、$http_x_forwarded_for都對應了一個-,這是因為這幾個變數為空。
設定error_log
錯誤日誌在Nginx中是透過error_log指令實現的。該指令記錄伺服器和請求處理過程中的錯誤資訊。
- 語法
配置錯誤日誌檔案的路徑和日誌級別。
error_log file [level];
Default:
error_log logs/error.log error;
第一個引數指定日誌的寫入位置。
第二個引數指定日誌的級別。level可以是debug, info, notice, warn, error, crit, alert,emerg中的任意值。可以看到其取值範圍是按緊急程度從低到高排列的。只有日誌的錯誤級別等於或高於level指定的值才會寫入錯誤日誌中。預設值是error。
- 基本用法
error_log /var/logs/nginx/nginx-error.log
它可以配置在:main, http, mail, stream, server, location作用域。
例子中指定了錯誤日誌的路徑為:/var/logs/nginx/nginx-error.log,日誌級別使用預設的error。
常見的日誌變數
• $remote_addr, $http_x_forwarded_for 記錄客戶端IP地址。
• $remote_user記錄客戶端使用者名稱稱。
• $request記錄請求的URL和HTTP協議(GET,POST,DEL,等)。
• $status記錄請求狀態。
• $body_bytes_sent傳送給客戶端的位元組數,不包括響應頭的大小; 該變數與Apache模組mod_log_config裡的“%B”引數相容。
• $bytes_sent傳送給客戶端的總位元組數。
• $connection連線的序列號。
• $connection_requests 當前透過一個連線獲得的請求數量。
• $msec 日誌寫入時間。單位為秒,精度是毫秒。
• $pipe如果請求是透過HTTP流水線(pipelined)傳送,pipe值為“p”,否則為“.”。
• $http_referer 記錄從哪個頁面連結訪問過來的。
• $http_user_agent記錄客戶端瀏覽器相關資訊。
• $request_length請求的長度(包括請求行,請求頭和請求正文)。
• $request_time 請求處理時間,單位為秒,精度毫秒; 從讀入客戶端的第一個位元組開始,直到把最後一個字元傳送給客戶端後進行日誌寫入為止。
• $time_iso8601 ISO8601標準格式下的本地時間。
• $time_local通用日誌格式下的本地時間。
open_log_file_cache
使用open_log_file_cache來設定日誌檔案快取(預設是off)。
• max 設定快取中的最大檔案描述符數量,如果快取被佔滿,採用LRU演算法將描述符關閉。
• inactive 設定存活時間,預設是10s。
• min_uses 設定在inactive時間段內,日誌檔案最少使用多少次後,該日誌檔案描述符記入快取中,預設是1次。
• valid 設定檢查頻率,預設60s。
• off 禁用快取。
語法格式: 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
示例
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
它可以配置在http、server、location作用域中。
例子中,設定快取最多快取1000個日誌檔案描述符,20s內如果快取中的日誌檔案描述符至少被被訪問2次,才不會被快取關閉。每隔1分鐘檢查快取中的檔案描述符的檔名是否還存在。
nginx日誌除錯技巧
設定 Nginx 僅記錄來自於指定的 IP 的錯誤
當設定日誌級別成 debug,如果在除錯一個線上的高流量網站的話,錯誤日誌可能會記錄每個請求的很多訊息,這樣會變得毫無意義。
在events{...}中配置如下內容,可以使 Nginx 記錄僅僅來自於指定的 IP 的錯誤日誌。
events {
debug_connection 1.2.3.4; }
除錯 nginx rewrite 規則
除錯rewrite規則時,如果規則寫錯只會看見一個404頁面,可以在配置檔案中開啟nginx rewrite日誌,進行除錯。
server {
error_log /var/logs/nginx/example.com.error.log; rewrite_log on; }
rewrite_log on; 開啟後,它將傳送所有的 rewrite 相關的日誌資訊到 error_log 檔案中,使用 [notice] 級別。隨後就可以在error_log 檢視rewrite資訊了。
使用location記錄指定URL的日誌
server {
error_log /var/logs/nginx/example.com.error.log; location /static/ { error_log /var/logs/nginx/static-error.log debug; } }
配置以上配置後,/static/ 相關的日誌會被單獨記錄在static-error.log檔案中。
常用例子
main格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$upstream_addr $upstream_response_time $request_time ';
access_log logs/access.log main;
json格式
log_format logstash_json '{"@timestamp":"$time_iso8601",'
'"host": "$server_addr",'
'"client": "$remote_addr",'
'"size": $body_bytes_sent,'
'"responsetime": $request_time,'
'"domain": "$host",'
'"url":"$request_uri",'
'"referer": "$http_referer",'
'"agent": "$http_user_agent",'
'"status":"$status",'
'"x_forwarded_for":"$http_x_forwarded_for"}';
解釋:
$uri請求中的當前URI(不帶請求引數,引數位於$args),不同於瀏覽器傳遞的$request_uri的值,它可以透過內部重定向,或者使用index指令進行修改。不包括協議和主機名,例如/foo/bar.html。
$request_uri 這個變數等於包含一些客戶端請求引數的原始URI,它無法修改,請檢視$uri更改或重寫URI。也就是說:$request_uri是原始請求URL,$uri則是經過nginx處理請求後剔除引數的URL,所以會將漢字表現為union。
坑點:
使用$uri可以在nginx對URL進行更改或重寫,但是用於日誌輸出可以使用$request_uri代替,如無特殊業務需求,完全可以替換。
壓縮格式
日誌中增加了壓縮的資訊。
http {
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
gzip on;
access_log /spool/logs/nginx-access.log compression;
...
}
}
upstream格式
增加upstream消耗的時間。
http {
log_format upstream_time '$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"';
server {
access_log /spool/logs/nginx-access.log upstream_time;
...
}
}
總結
Nginx中透過access_log和error_log指令配置訪問日誌和錯誤日誌,透過log_format我們可以自定義日誌格式。如果日誌檔案路徑中使用了變數,我們可以透過open_log_file_cache指令來設定快取,提升效能。
另外,在access_log和log_format中使用了很多變數,這些變數沒有一一列舉出來,詳細的變數資訊可以參考Nginx官方文件
檢視日誌使用技巧
統計status 出現的次數
awk '{print $9}' access.log | sort | uniq -c | sort -rn
36461 200
483 500
9 400
3 302
1 403
1 301
顯示返回302狀態碼的URL
awk '($9 ~ /302/)' access.log | awk '{print $7}' | sort | uniq -c | sort -rn
1 /anyrtc.png
1 /test.html