1. 程式人生 > 其它 >Linux下玩轉nginx系列(三)---nginx日誌配置檔案說明

Linux下玩轉nginx系列(三)---nginx日誌配置檔案說明

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

參考文件

Nginx日誌配置詳解
如何在Nginx中配置自定義訪問和錯誤日誌格式
Full Example Configuration