前言
本篇文章將對nginx服務(wù)中提供的日志文件進行介紹改执,同時對我們?nèi)粘_\維中對nginx日志常見的操作進行分享
一测秸、Nignx的日志類型
我們進入到nginx
目錄下的log
目錄中匀归,可以看到里面存放著三個文件舌镶,分別是access.log
阱扬,error.log
和nginx.pid
文件幽污,其中nginx.pid
是用來記錄當(dāng)前nginx進程的pid號的,不屬于日志文件咕痛。真正屬于日志文件的是另外兩個文件痢甘。
-rw-r--r-- 1 root root 90261926 Jun 9 09:38 access.log
-rw-r--r-- 1 root root 21159964 Jun 8 16:36 error.log
-rw-r--r-- 1 root root 5 May 24 15:18 nginx.pid
(一)access.log日志文件
1、access.log文件的介紹
access文件用于存放每個用戶訪問網(wǎng)站的請求日志茉贡,開發(fā)運維人員通過訪問日志來分析用戶的瀏覽器行為产阱。默認(rèn)情況下,nginx會在log
目錄下生成該文件块仆,無需用戶配置构蹬。
2、access.log
的相關(guān)配置
我們可以在$nginx_home/conf/nginx.conf
配置文件中對nginx請求日志進行配置悔据。配置的格式為:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
其中庄敛,access_log
是關(guān)鍵字,表示接下來的配置是關(guān)于access日志的配置科汗,path
為該日志文件的存儲路徑藻烤,后面還可以對日志輸出格式、是否壓縮头滔、日志刷新時間等設(shè)置進行配置怖亭。可能有讀者會留意到坤检,上面截圖中的用例在path
后面寫上了main
兴猩,其實這里的main
并不是什么關(guān)鍵字,而是nginx默認(rèn)定義好的一個日志格式名稱早歇,我們可以在log_format
中看到倾芝,nginx默認(rèn)定義了一個名為main
的日志輸出格式。
- 關(guān)于日志輸出格式的配置
nginx自帶了一些變量箭跳,讓我們能夠作為日志輸出格式進行配置晨另,方便我們對用戶的請求進行查詢和統(tǒng)計。當(dāng)然了谱姓,nginx其實默認(rèn)的日志輸出格式其實就已經(jīng)把一些重要的請求參數(shù)保存到訪問日志里面了借尿,基本滿足我們?nèi)粘J褂昧耍绻行枰梢愿鶕?jù)下面的表單自定義配置所需要的日志格式屉来。
參數(shù) | 說明 | 示例 |
---|---|---|
$remote_addr | 客戶端地址 | 211.28.65.253 |
$remote_user | 客戶端用戶名稱 | -- |
$time_local | 訪問時間和時區(qū) | 18/Jul/2012:17:00:01 +0800 |
$request | 請求的URI和HTTP協(xié)議 | "GET /article-10000.html HTTP/1.1" |
$http_host | 請求地址路翻,即瀏覽器中你輸入的地址(IP或域名) | www.wang.com 192.168.100.100 |
$status | HTTP請求狀態(tài) | 200 |
$upstream_status | upstream狀態(tài) | 200 |
$body_bytes_sent | 發(fā)送給客戶端文件內(nèi)容大小 | 1547 |
$http_referer | url跳轉(zhuǎn)來源 | https://www.baidu.com/ |
$http_user_agent | 用戶終端瀏覽器等信息 | "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; GTB7.0; .NET4.0C; |
$ssl_protocol | SSL協(xié)議版本 | TLSv1 |
$ssl_cipher | 交換數(shù)據(jù)中的算法 | RC4-SHA |
$upstream_addr | 后臺upstream的地址,即真正提供服務(wù)的主機地址 | 10.10.10.100:80 |
$request_time | 整個請求的總時間 | 0.205 |
$upstream_response_time | 請求過程中奶躯,upstream響應(yīng)時間 | 0.002 |
下面我們來簡單地自定義一個日志輸出格式帚桩,并且應(yīng)用起來。
步驟一:在http標(biāo)簽下新增一個log_format
格式
步驟二:在server標(biāo)簽中應(yīng)用定義新的access_log
配置
server {
listen 9600;
location / {
root html;
access_log logs/mine_access.log mine_format;
}
}
步驟三:使用nginx -s reload
重新加載配置文件
(注意嘹黔,如果這里提示說日志文件不存在的話账嚎,就自己先手動建一下文件即可)
自己手動訪問幾次服務(wù)莫瞬,就可以看到新生成的日志格式會和我們定義的日志格式一致了。
- 關(guān)于刷新時間的配置
nginx默認(rèn)情況下對訪問日志是實時記錄的郭蕉,其實一定程度上來說是會占用cpu資源的疼邀,當(dāng)然了大部分站點其實訪問量并不大,所以實時記錄日志所帶來的性能消耗是可以忽略的召锈。如果說對于訪問量大且對性能要求較高的站點旁振,可能會希望通過優(yōu)化日志的輸出頻率來達到減少IO的效果。
location / {
root html;
access_log logs/mine_access.gz mine_format gzip flush=5s;
}
我們可以看一下官方對這個配置的介紹
配置完flush和buffer
后涨岁,其實我們就相當(dāng)于是有兩個記錄日志的節(jié)點了拐袜,一個是緩沖區(qū)滿了,另外一個是到刷新日志的時間點了梢薪。緩沖區(qū)的存在使得nginx不需要針對每一個請求都做一次IO蹬铺,可以節(jié)省一點系統(tǒng)資源。當(dāng)然了秉撇,我們還可以開啟gzip壓縮(可選等級為1-9甜攀,級別越高壓縮級別越高)來進一步減輕磁盤壓力。
- 關(guān)閉訪問日志的記錄
只需要配置access_log
為off
即可
location / {
root html;
access_log off;
}
(二)error.log錯誤日志
相比于訪問日志來說琐馆,運維人員可能更加關(guān)注錯誤日志文件规阀,錯誤日志文件記錄了nginx運行過程中遇到的錯誤信息(注意,也包括用戶請求沒有正常響應(yīng)的錯誤日志)瘦麸,向有時候我們nginx啟動失敗后谁撼,都可以在這個error日志中找到對應(yīng)較為詳情的報錯信息。
這里貼一下官網(wǎng)對error.log
的介紹瞎暑,該錯誤日志的配置格式為:error_log path level
彤敛,error_log為關(guān)鍵字,path為日志保存的路徑了赌,level為日志級別。默認(rèn)情況下nginx會在logs目錄下建立一個名為error.log
的日志文件玄糟,且日志級別為error勿她。可選的日志級別配置從低到高分別為debug, info, notice, warn, error, crit, alert, emerg阵翎。
我們可以簡單演示一下逢并,這個錯誤日志的用法
server {
listen 9600;
location / {
root html;
access_log logs/mine_access.log mine_format;
error_log logs/mine_error.log warn;
}
}
配置完后reload一下nginx配置,然后在瀏覽器中隨意訪問一下不存在的資源郭卫,我們就可以在日志文件里面看到相關(guān)的錯誤日志了砍聊。
二、運維優(yōu)化
(一)實現(xiàn)日志按指定時間分割處理
nginx默認(rèn)是不會進行日志文件的分割操作的贰军,也就是所有訪問日志會一直往access.log
文件里面追加玻蝌,時間一長的話這個文件就會變得很大,而且運維人員在查看當(dāng)天文件的也很不方便。所以一般來說俯树,我們都會選擇按日對日志文件進行切割帘腹。
常見的處理方案有2種:(1)直接在nginx配置文件中配置(2)通過linux的crontab
配置定時任務(wù),自己手動寫一下定時處理的腳本许饿。下面我們就來講講這兩種處理方案:
方案一:在nginx配置文件中配置
在Nginx配置文件中阳欲,可以使用$time_local
或$time_iso8601
變量來獲取當(dāng)前時間,然后將其作為日志文件名的一部分陋率。所以我們可以這樣配置我們的日志文件名球化。
步驟一:在http標(biāo)簽塊中按照我們需要的日期格式yyyy-MM-dd
定義變量$logdate
http {
...
map $time_iso8601 $logdate {
'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
default 'date-not-found';
}
...
}
步驟二:在對應(yīng)的站點中使用變量來動態(tài)生成日志文件
location / {
root html;
access_log /opt/nginx/logs/mine_access.$logdate.log mine_format;
error_log /opt/nginx/logs/mine_error.log warn;
}
這里需要注意的是,error_log
日志文件可能會由于nginx版本的原因瓦糟,無法使用變量來動態(tài)切割每天的日志赊窥,所以感覺這種方法并不完全適用。
步驟三:重新加載一下配置文件狸页,上述配置即可生效了
方案二:結(jié)合crontab定時任務(wù)來完成日志的切割效果(更推薦)
步驟一:寫一下按日切割文件的日志腳本锨能,命名為nginx_log_split.sh
簡單解釋一下腳本做的工作,根據(jù)年/月
生成對應(yīng)的目錄芍耘,然后把日志文件重命名后放入到對應(yīng)月份的目錄中址遇,最后再通過nginx -s reopen
命令重新啟動日志。
吐槽一下斋竞,本來是想用current_date
作為變量名的倔约,但似乎觸發(fā)了簡書的bug,一直保存不了....
#!/bin/bash
nginx_home=/opt/nginx/
nginx_log_path=${nginx_home}logs/
current_date1=$(date +%Y-%m-%d)
access_log_file_name=access.log
error_log_file_name=error.log
history_file_path=${nginx_home}logs/history_log/$(date +%Y)/$(date +%m)
# check if the nginx server alive
if [ -e ${nginx_log_path}nginx.pid ];then
# create log folder for nginx log file
if [ ! -e ${history_file_path} ];then
mkdir -p ${history_file_path}
echo "$(date) create folder success"
fi
# rename the log file with current date
if [ -e $nginx_log_path$access_log_file_name ];then
mv ${nginx_log_path}${access_log_file_name} ${history_file_path}/access-${current_date1}.log
echo "$(date) rename access.log successfully"
else
echo "$(date) access.log file no exist,skip"
fi
if [ -e $nginx_log_path$error_log_file_name ];then
mv ${nginx_log_path}${error_log_file_name} ${history_file_path}/error-${current_date1}.log
echo "$(date) rename error.log successfully"
else
echo "$(date) error.log file no exist,skip"
fi
# reopen the nginx server log
${nginx_home}/sbin/nginx -s reopen
echo "$(date) reload log file success"
else
echo "$(date) nginx server is close,skip"
fi
步驟二:給腳本授權(quán)
chmod 774 nginx_log_split.sh
步驟三:配置crontab定時器
通過crontab定時器坝初,讓系統(tǒng)每天晚上23:59
分的時候跑一次我們的腳本浸剩,生成分割當(dāng)天的日志文件。然后順便把執(zhí)行日志輸出到指定的文件中鳄袍,方便我們查看绢要。
59 23 * * * /opt/nginx/logs/nginx_split_log.sh > /opt/nginx/logs/history_log/execute.log 2>&1
為什么說個人更推薦這種寫法呢?我感覺通過定時任務(wù)來做的話拗小,靈活性更強重罪,我們可以根據(jù)自己的需要來決定怎么分割日志文件,另外更方便管理哀九,通過腳本我們可以更好的管理我們的日志文件(像上面的腳本剿配,我們就可以通過年/月的格式來存放我們的日志文件,一目了然)阅束。
(二)按模塊區(qū)分訪問日志
對于站點較多呼胚,且都部署在同一臺nginx服務(wù)器(或者同一個nginx集群)的企業(yè),一般我們會習(xí)慣性的將不同站點的日志分開管理息裸,避免所有的站點日志都輸出在同一個access.log
文件中蝇更,導(dǎo)致后續(xù)統(tǒng)計或者排查問題的時候容易混淆沪编。
server {
listen 9600;
location / {
root html;
access_log /opt/nginx/logs/mine_access1.log mine_format;
error_log /opt/nginx/logs/mine_error.log warn;
}
}
server {
listen 9601;
location / {
root html;
access_log /opt/nginx/logs/mine_access2.log mine_format;
}
}
參考文章:
nginx官網(wǎng):http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format