文章原創於公眾號:程式猿周先森。本平臺不定時更新,喜歡我的文章,歡迎關注我的微信公眾號。
眾所周知,線上如果出現事故我們通常都是檢視日誌去進行問題定位並且進行修復。使用好Nginx日誌有利於我們線上進行修復異常問題。在Nginx中日誌主要分為兩種:accesslog(訪問日誌)和errorlog(錯誤日誌)。通過檢視accesslog我們可以檢視使用者ip,瀏覽器資訊及請求時間等資訊,通過檢視errorlog我們可以檢視線上出錯的具體資訊,可以幫助我們定位異常的原因。本篇文章主要帶領大家詳細瞭解Nginx如何配置日誌。本文將會涉及到的日誌配置指令:
- access_log
- log_format
- openlogfile_cache
- lognotfound
- log_subrequest
- rewrite_log
- error_log
access_log指令
首先,我們可以先看看accesslog指令。accesslog命令可以配置訪問日誌。我們可以先看下access_log指令的語法結構:
- access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; # 設定訪問日誌
- access_log off; # 關閉訪問日誌
我們先來看看語法結構中的引數的含義:
- path: 指定日誌的存放位置
- format: 指定日誌的格式,非必填,預設為預定義的combined
- buffer:指定日誌寫入時的快取大小,非必填,預設64k
- gzip: 日誌寫入前先進行壓縮
- flush: 設定快取的有效期
- if: 設定條件判斷,當天劍成立時才會寫入日誌
- off: 值為off表示不開啟日誌,值為on表示開啟日誌
accesslog指令可以使用於http根節點,虛擬伺服器server節點,上下文配置location以及limitexcept中。無法在其他作用域使用accesslog指令,否則Nginx會報錯。我們可以看一個簡單的配置accesslog的小例子:
- access_log /root/.pm2/logs/niyueling.log buffer=32k gzip flush=5m
這個配置指定日誌儲存路徑為/root/.pm2/logs/niyueling.log,日誌使用預設格式combined。日誌快取大小為32k,日誌寫入前會進行gzip壓縮,快取有效期為5分鐘。
log_format指令
剛才有講過如果未指定日誌格式,Nginx會使用combined日誌格式為預設格式。combined日誌格式預設使用格式為:
- logformat combined '$remoteaddr - $remoteuser [$timelocal] ' '"$request" $status $bodybytessent ' '"$httpreferer" "$httpuser_agent"';
但是如果不想使用combined日誌格式,就可以使用logformat指令來自定義格式內容。logformat指令需要在http節點下進行配置。我們先來看下log_format指令的語法結構:
- log_format name [escape=default|json] string;
我們先來看看log_format的引數對應的用法:
- name: 指定日誌格式名稱,因為在access_log指令中需要指定日誌格式
- escape: 設定字元編碼方式,可以選擇default或者json
- string: 要寫入日誌的內容,可以有多個引數,可以使用Nginx變數。
下面貼一下log_format指令中常用的一些變數:
我們可以接著看個自定義日誌格式的小案例:
http {logformat main '$remoteaddr - $remoteuser [$timelocal] "$request" ''"$status" $bodybytessent "$http_referer" ''"$httpuseragent" "$httpxforwarded_for" ''"$gzipratio" $requesttime $bytessent $requestlength';
server {server_name www.niyueling.cn;access_log /root/.pm2/logs/niyueling.log main;}}
openlogfile_cache指令
對於網站的訪問記錄,通常操作都是首先開啟日誌檔案,然後寫入日誌記錄,最後關閉檔案。預設情況下日誌檔案不進行快取的,我們可以通過openlogfilecache指令設定日誌檔案快取。openlogfilecache指令可以配置在http根節點,虛擬伺服器server節點以及上下文location中。我們先看下openlogfile_cache指令的語法結構:
- openlogfilecache max=X [inactive=time] [minuses=N] [valid=time];
- openlogfile_cache off;
首先先貼下引數對應的含義:
- max: 設定快取中的最大檔案描述符
- inactive: 設定存活時間
- min_uses: 在存活時間內,日誌檔案最少被使用幾次後將日誌檔案描述符寫入快取。
- valid: 設定檢查頻率
- off: 禁用日誌快取
可以看一個簡單配置日誌快取的小例子:
- openlogfilecache max=100 inactive=30s valid=5m minuses=3;
lognotfound指令
這個命令用於指定是否在error_log錯誤日誌中記錄不存在的錯誤,如檔案不存在等。預設值為是。我們可以先看下語法結構:
- lognotfound on | off;
lognotfound指令可以配置在http根節點,虛擬伺服器server節點以及上下文location中。設定為on表示記錄不存在的錯誤,設定為off表示不記錄不存在的錯誤。
log_subrequest指令
logsubrequest指令用於指定在accesslog訪問日誌中是否記錄子請求的訪問記錄。預設情況為不記錄,貼下語法結構:
- log_subrequest on | off;
log_subrequest指令可以配置在http根節點,虛擬伺服器server節點以及上下文location中。設定為on表示記錄子請求訪問記錄,設定為off表示不記錄子請求訪問記錄。
rewrite_log指令
rewritelog指令由ngxhttprewritemodule模組提供服務,用來記錄日誌重寫。可以在error_log錯誤日誌中記錄notice級別的重寫日誌。預設是不啟用狀態,貼下語法結構:
- rewrite_log on | off;
rewrite_log指令可以配置在http根節點,虛擬伺服器server節點以及上下文location以及if條件判斷中。設定為on表示在錯誤日誌中記錄notice級別的重寫日誌,設定為off表示在錯誤日誌中不記錄notice級別的重寫日誌。
error_log指令
errorlog指令顧名思義,就是用來指定錯誤日誌的,一般來說線上出現bug都是通過errorlog日誌來定位問題所在而加以解決的。errorlog指令可以記錄伺服器和請求處理過程中的錯誤資訊。我們先看下errorlog指令的語法結構:
- error_log file [level];
引數含義其實很容易可以理解:
- file: error_log 存放路徑
- level: 日誌級別,只有日誌級別高於指定級別才會記錄到error_log中
- error_log指令可以配置在http節點,main節點,虛擬伺服器server節點以及上下文location中。
日誌切割
Nginx記錄日誌預設情況下是訪問日誌全部寫入accesslog中,錯誤日誌全部寫入errorlog中。這樣會導致日誌檔案原來越大,不利於檢視日誌分析問題異常,所以我們可以將日誌以日期為單位進行切割。首先需要寫一個指令碼實現Nginx按天切割:
日誌儲存位置
- base_path='/root/.pm2/logs/niyueling.log'
獲取當前年資訊和月資訊
- log_path=$(date -d yesterday +"%Y%m")
獲取昨天的日資訊
- day=$(date -d yesterday +"%d")
按年月建立資料夾
- mkdir -p $basepath/$logpath
備份昨天的日誌到當月的資料夾
- mv $basepath/access.log $basepath/$logpath/access$day.log
輸出備份日誌檔名
- echo $basepath/$logpath/access_$day.log
通過Nginx訊號量控制重讀日誌
- kill -USR1
cat /opt/nginx/logs/nginx.pid
然後給指令碼新增可執行許可權,最後新增Linux定時任務:
- crontab -e
每天凌晨兩點半進行日誌分割
- 30 02 0 * /root/.pm2/logs/splitLog.sh
重啟Linux定時任務
- crond restart
通過上面的講解差不多可以知道Nginx對於日誌是如何進行配置的,實際上就是通過logformat配置日誌格式,如果logformat中使用了Nginx變數,則可以通過openlogfilecache指令來設定快取提高效能。然後通過accesslog進行設定訪問日誌,通過error_log指令設定錯誤日誌。最後實現定時任務定時切割每天的日誌,有利於我們後期維護。
如果喜歡我的文章,歡迎關注個人公眾號:程式猿周先森。