背景 工作需要對接內部的日誌中台,對日誌列印有固定的格式要求,為了使Nginx的access日誌也能被採集,需要對日誌格式進行自定義,要求日誌格式為: yyyy-MM-dd HH:mm:ss.SSS LOG_LEVEL LOG_MSG > 時間格式+列印級別+業務日誌 如: 23-11-18 17: ...
背景
工作需要對接內部的日誌中台,對日誌列印有固定的格式要求,為了使Nginx的access日誌也能被採集,需要對日誌格式進行自定義,要求日誌格式為:
yyyy-MM-dd HH:mm:ss.SSS LOG_LEVEL LOG_MSG ---> 時間格式+列印級別+業務日誌
如:
23-11-18 17:34:23.738 DEBUG monitor-7 org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug:137: xxxxx
但目前我們Nginx按照預設格式配置,大致如下:
192.23.4.5 -- [18/Nov/2023L18:58:52 +0800] "GET /api/cluster HTTP/1.1" 200 155 "https://xxx.xx.xx.x"
時間格式無法不符合要求,並且未區分日誌級別,因此,需要對日誌列印格式進行自定義
自定義日誌格式配置
1.重新定義日誌格式
點擊查看代碼
# 原日誌格式
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 '$time_zh_ms $log_level - $remote_addr - $remote_user "$request" $status $body_bytes_sent "http_referer" "$http_user_agent" "$http_x_forwarded_for";
# 對比修改前後差異,其實就是
1.自定義了$time_zh_ms,在下麵的配置中,將其設置為yyyy-MM-dd HH:mm:ss.SSS格式
2.自定義了$log_level,為日誌列印級別,下麵的配置中,將按照請求響應碼來判斷為何種日誌列印級別
以上只是為了滿足日誌採集需要,其他欄位可按實際情況變動
2.定義時間格式的轉換
Nginx預設支持的時間格式為iso8601,此處我們需要通過獲取到內置時間變數$time_iso8601和$msec,具體配置如下:
點擊查看代碼
# 將iso8601格式時間轉換為yyyy-MM-dd HH:mm:ss格式
# 按照正則將時間字元串分割為6部分,分別為年月日時分秒,再拼接到$time_zh自定義變數中
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
set $minutes $5;
set $seconds $6;
set $time_zh "$1-$2-$3 $4:$5:$6";
}
# 獲取毫秒時間戳,並拼接到$time_zh之後
if ($msec ~ "(\d+)\.(\d+)") {
set $time_zh_ms $time_zh.$2
}
# 註意:$time_zh_ms其實就是在log_format中定義的日誌格式第一個欄位
3.根據響應碼定義日誌級別
Nginx的access日誌預設是沒有日誌級別這一說法的,此處可視為我們為了適配業務而做的規則,在我們的使用場景中,將返回碼為4或5的請求,視為錯誤,列印為ERROR級別,其他請求為INFO級別
點擊查看代碼
# 如果http返回碼為4或5開頭,則設置log_level為ERROR,否則為INFO
map $status $log_level {
~^[45] ERROR;
default INFO;
}
# 此處$status為Nginx內置變數,代表請求的響應碼,log_level為自定義變數
4.設置日誌使用具體格式並列印到文件
點擊查看代碼
access_log /dev/stdout main;
access_log /etc/nginx/logs/access.log main;
error_log /dev/stdout;
error_log /etc/nginx/logs/error.log;