關(guān)于Nginx 日志
Nginx 日志分為兩種,一種是錯(cuò)誤日志(error log),記錄 Nginx 運(yùn)行過程中遇到的異常,一種是訪問日志(access log),記錄的是 WEB 服務(wù)被用戶訪問時(shí)留下的一些信息。例如哪些文件被訪問過、Nginx 如何響應(yīng)、用戶使用的 IP 地址等等。
1 開啟訪問日志
要開啟訪問日志,在 nginx.conf 文件中的 http 或 server 字段添加以下參數(shù):
access_log log_file log_format;
其中 log_file 為日志要保存的路徑,log_format 為日志記錄格式。記錄格式可以采用默認(rèn),也可以在 http 字段中自定義:
log_format format_name 'set_of_variables_to_define_format';
其中 format_name 表示這個(gè)日志格式的名稱,在引用時(shí)需要用到。set_of_variables_to_define_format 表示此日志格式所記錄的信息及順序。
訪問日志格式詳解可見此官方文檔。
小提示:
• server 字段如果未設(shè)置訪問日志,則該 server 訪問日志會(huì)繼承 http 字段中的設(shè)置。
• server 字段中的 location 字段也可單獨(dú)設(shè)置訪問日志。
• 每個(gè)字段中都可以設(shè)置多個(gè)不同格式的日志。
2 開啟錯(cuò)誤日志
要開啟錯(cuò)誤日志,在 nginx.conf 文件中 http 字段添加以下參數(shù):
error_log log_file log_level;
其中 log_file 為日志要保存的路徑,log_level 為要記錄的日志級(jí)別,設(shè)置某個(gè)級(jí)別后,該級(jí)別及以上級(jí)別的錯(cuò)誤日志都將被記錄。
錯(cuò)誤日志共分為 8 個(gè)級(jí)別,從高到低分別是:
• emerg: 緊急,可能導(dǎo)致服務(wù)不可用。
• alert: 告警,嚴(yán)重問題告警。
• crit: 嚴(yán)重,需要關(guān)注的嚴(yán)重問題。
• error: 錯(cuò)誤,發(fā)生錯(cuò)誤,例如某個(gè)頁面處理錯(cuò)誤。
• warn: 警示,可能需要關(guān)注的問題。
• notice: 通知,簡單的通知日志,大多數(shù)情況下可以忽略。
• info: 信息,運(yùn)行中的普通信息。
• debug: 調(diào)試,用于分析錯(cuò)誤的調(diào)試信息。
3 日志按天或按月存放
通常配置情況下,Nginx 所有訪問日志存放在同一個(gè) log 文件中,時(shí)間一長,日志文件將變得巨大,導(dǎo)致備份、分析都不方便。因此需要將日志按一定時(shí)間間隔分開存放,例如每天、每月或其它時(shí)間間隔。要實(shí)現(xiàn)這個(gè)目的主要由兩種方式:
• 一種是在 nginx.conf 配置文件中進(jìn)行配置
• 一種是使用系統(tǒng)定時(shí)任務(wù)腳本定期對日志進(jìn)行分割
3.1 在 nginx.conf 中配置日志存放規(guī)則
在這里,我們需要用到 map 指令,map 指令是由 ngx_http_map_module 模塊提供的,默認(rèn)情況下安裝 nginx 都會(huì)安裝該模塊。map 指令只能位于 nginx.conf 的 http 字段內(nèi)。具體代碼如下:
http {
......
......
#設(shè)置日志按日期或月份滾動(dòng)
map $time_iso8601 $year {
default 'date';
'~^(?<yyyy>d{4})-' $yyyy;
}
map $time_iso8601 $month {
default 'not';
'~^d{4}-(?<mm>d{2})-' $mm;
}
map $time_iso8601 $day {
default 'found';
'~^d{4}-d{2}-(?<dd>d{2})' $dd;
}
#日志按年-月-日名稱格式存放
#map $time_iso8601 $logfile_date {
# default 'date-not-found';
# '~^(?<year>d{4})-(?<month>d{2})-(?<day>d{2})' $year-$month-$day;
#}
#日志按年-月名稱格式存放
map $time_iso8601 $logfile_month {
default 'date-not-found';
'~^(?<year>d{4})-(?<month>d{2})' $year-$month;
}
}
使用 map 定義好變量之后,即可在配置訪問日志記錄時(shí)使用該變量:
access_log logs/$logfile_month.access.log;
access_log 指令可以在 http 字段內(nèi),也可以在 server 字段內(nèi)。
配置好后,如果遇到日志文件并沒有生成的問題,則可能是 logs 目錄權(quán)限導(dǎo)致,需要賦予 logs 目錄 nginx 啟動(dòng)用戶的權(quán)限(這是在日志路徑中使用變量的一些限制,參考官方:Nginx 日志模塊說明)。假設(shè) nginx 以 www 組的 www 用戶啟動(dòng),則:
chown -R www:www logs/
最終生成的日志效果如下:
關(guān)于在日志路徑中使用變量的限制,包括:
日志文件路徑可以包含變量 (0.7.6+),但這類設(shè)置存在以下限制:
• 啟動(dòng) Nginx worker 進(jìn)程的用戶必須擁有日志目錄的寫權(quán)限;
• 寫緩存將不起作用;
• 每條日志寫入都會(huì)造成日志文件的打開和關(guān)閉。然而,由于頻繁讀寫的文件的文件描述符可能會(huì)被存儲(chǔ)與緩存中,根據(jù) open_log_file_cache 指令的時(shí)間參數(shù)設(shè)置,日志可能繼續(xù)寫入到舊文件中;
• 每條日志寫入時(shí)都會(huì)檢測站點(diǎn)根目錄是否存在,如果不存在則日志不會(huì)創(chuàng)建,因此最好在 access_log 設(shè)置的同級(jí)別指令段中指定站點(diǎn)根目錄,例如:
server {
root /spool/vhost/data/$host;
access_log /spool/vhost/logs/$host;
...
也有使用 if 判斷語句來定義上面的變量,但據(jù)說可能引發(fā)問題,建議使用 map 指令。
3.2 通過定時(shí)腳本分割日志
創(chuàng)建日志分割腳本 splitLog.sh :
# /bin/bash
# 日志保存位置
base_path='/usr/local/nginx/logs/'
# 獲取當(dāng)前年信息和月信息
log_path=$(date -d yesterday +"%Y%m")
# 獲取昨天的日信息
day=$(date -d yesterday +"%d")
# 按年月創(chuàng)建文件夾
mkdir -p $base_path/$log_path
# 備份昨天的日志到當(dāng)月的文件夾
mv $base_path/access.log $base_path/$log_path/access_$day.log
# 輸出備份日志文件名
# echo $base_path/$log_path/access_$day.log
# 通過Nginx信號(hào)量控制重讀日志
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
添加linux定時(shí)任務(wù):
crontab -e
# 每天0時(shí)1分進(jìn)行日志分割(建議在02-04點(diǎn)之間,系統(tǒng)負(fù)載小)
01 00 * * * /usr/local/nginx/logs/splitLog.sh
重啟Linux定時(shí)任務(wù):
crond restart
如果提示以下錯(cuò)誤 crond: can't lock /var/run/crond.pid, otherpid may be 4141:資源暫時(shí)不可用,刪除 /var/run/crond.pid 重新執(zhí)行命令即可。
作者:李凌






