在分析服務器運行狀況和業務數據時,nginx日誌是很是可靠的數據來源,而掌握經常使用的nginx日誌分析命令的應用技巧則有着事半功倍的做用,能夠快速進行定位和統計。php
1)Nginx日誌的標準格式(可參考:http://www.cnblogs.com/kevingrace/p/5893499.html)html
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $request_time';
記錄的形式以下: nginx
192.168.28.22 - - [28/Feb/2018:04:01:11 +0800] "GET /UserRecommend.php HTTP/1.1" 200 870 "http://wwww.kevin.www/grace/index.html" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)" 320
日誌格式說明:
$remote_addr 遠程請求使用的IP地址
$remote_user 遠端登陸名
$time_local 時間,用普通日誌時間格式(標準英語格式)
$request 請求的第一行
$status 狀態。
$body_bytes_sent 請求返回的字節數,包括請求頭的數據
$http_referer 請求頭Referer的內容
$http_user_agent 請求頭User-Agent的內容
$request_time 處理完請求所花時間,以秒爲單位apache
Apache日誌的標準格式後端
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %T " combined CustomLog log/access_log combined
記錄的形式以下: 數組
192.168.28.23 - frank [28/Feb/2018:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"
日誌格式說明:
%h 請求使用的IP地址
%l 遠端登陸名(由identd而來,若是支持的話),除非IdentityCheck設爲"On",不然將獲得一個"-"。
%u 遠程用戶名(根據驗證信息而來;若是返回status(%s)爲401,多是假的)
%t 時間,用普通日誌時間格式(標準英語格式)
%r 請求的第一行
%s 狀態。對於內部重定向的請求,這個狀態指的是原始請求的狀態,---%>s則指的是最後請求的狀態。
%b 以CLF格式顯示的除HTTP頭之外傳送的字節數,也就是當沒有字節傳送時顯示'-'而不是0。
\"%{Referer}i\" 發送到服務器的請求頭Referer的內容。
\"%{User-Agent}i\" 發送到服務器的請求頭User-Agent的內容。
%T 處理完請求所花時間,以秒爲單位。
%I 接收的字節數,包括請求頭的數據,而且不能爲零。要使用這個指令你必須啓用mod_logio模塊。
%O 發送的字節數,包括請求頭的數據,而且不能爲零。要使用這個指令你必須啓用mod_logio模塊。緩存
Nginx 日誌字段解釋性能優化
說明 |
字段名 |
示例 |
主機頭 |
$host |
域名 kevin.bo.com |
服務器ip |
$server_addr |
192.168.10.109 |
端口 |
$server_port |
80 |
客戶ip |
$remote_addr |
172.17.12.18 |
客戶 |
$remote_user |
- |
時間 |
$time_iso8601 |
2018-11-04T10:13:40+09:00 |
狀態碼 |
$status |
204 |
發送主體大小 |
$body_bytes_sent |
0 |
發送總大小 |
$bytes_sent |
140 |
請求總大小 |
$request_length |
578 |
請求主體大小 |
$request_body |
- |
請求時間 |
$request_time |
0.001 |
請求方式 |
$request_method |
GET |
uri |
$uri |
/rest/quickreload/latest/18747370 |
變量 |
$args |
since=1559180602998&_=1559181197999 |
協議 |
$server_protocol |
HTTP/1.1 |
cookie |
$cookie_nid |
- |
記錄從哪一個頁面連接訪問過來 |
$http_referer |
http://kevin.bo.com/pages/viewpage.action?pageId=18747370 |
客戶端信息 |
$http_user_agent |
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36 |
客戶端真實ip(通過反向代理) |
$http_x_forwarded_for |
- |
編碼 |
$http_accept_encoding |
gzip, deflate |
當前經過一個鏈接得到的請求數量 |
$connection_requests |
1 |
後端ip |
$upstream_addr |
192.168.10.33:8090 |
後端狀態碼 |
$upstream_status |
204 |
後端響應時間 |
$upstream_status |
0.001 |
後臺緩存 |
$upstream_cache_status |
- |
後端接口狀態 |
$upstream_http_x_status |
- |
配置文件
log_format main '$host\t$server_addr\t$server_port\t$remote_addr\t'
'$remote_user\t$time_iso8601\t$status\t'
'$body_bytes_sent\t$bytes_sent\t$request_length\t'
'$request_body\t$request_time\t$request_method\t'
'$uri\t$args\t$server_protocol\t$cookie_nid\t'
'$http_referer\t$http_user_agent\t$http_x_forwarded_for\t'
'$http_accept_encoding\t$connection_requests\t$upstream_addr\t'
'$upstream_status\t$upstream_response_time\t$upstream_cache_status\t$upstream_http_x_status'; bash
2)Nginx日誌切割服務器
#!/bin/sh # 設置日誌文件備份文件名 #logfilename=`date +%Y%m%d` logfilename=`date +\%Y\%m\%d -d "1 days ago"` # 設置日誌文件原始路徑 logfilepath=/opt/nginx/logs/ # 設置日誌備份文件路徑 backupfilepath=/opt/data/logs/nginx/ LOG_FILE='access error log_mm log_db' for j in $LOG_FILE do cd ${logfilepath} tar zcvf ${backupfilepath}$j/${logfilename}.tar.gz $j.log rm -rf $j.log done kill -USR1 `cat /opt/nginx/nginx.pid
===================================================
apache日誌切割
#!/bin/bash # 獲取昨天的日期 logfilename=`date -d yesterday +%Y_%m_%d` today=`date +%Y.%m.%d` # 設置日誌文件原始路徑 logfilepath=/opt/apache2/logs/ # 設置日誌備份文件路徑 backupfilepath=/opt/data/logs/apache/ echo "get access log:" # 打包壓縮訪問日誌文件 cd ${logfilepath} tar zcvf ${backupfilepath}access/${logfilename}.tar.gz access_${logfilename}.log rm -rf access_${logfilename}.log echo "get error log:" # 打包壓縮錯誤日誌文件 cd ${logfilepath} tar zcvf ${backupfilepath}error/${logfilename}.tar.gz error_${logfilename}.log rm -rf error_${logfilename}.log echo "done @"${today}
==========================================================
3)日誌定時清理的腳本
#!/bin/sh ####################### clear logs ######################### ### nginx ### #clear nginx access log(by hour .log) 2 days ago /usr/bin/find /opt/data/logs/nginx/access -mtime +2 -name "access.log*" -exec rm -rf {} \; #clear nginx (access,error,log_mm,log_db) log(by day tar.gz) 10 days ago NGINX='access error log_mm log_db' for i in $NGINX do /usr/bin/find /opt/data/logs/nginx/$i -mtime +10 -name "*tar.gz" -exec rm -rf {} \; done ### apache ### #clear apache (access,error) log(by day tar.gz) 10 days ago APACHE='access error' for j in $APACHE do /usr/bin/find /opt/data/logs/apache/$j -mtime +10 -name "*tar.gz" -exec rm -rf {} \; done ### other log ### #clear (txt/mq,txt/auto,txt/man) log(by day .log) 10 days ago OTHER='txt/mq txt/auto txt/man' for k in $OTHER do /usr/bin/find /opt/data/logs/$k -mtime +10 -name "*log" -exec rm -rf {} \; done
=============在分析nginx日誌時經常使用命令總結=============
1. 利用grep ,wc命令統計某個請求或字符串出現的次數
好比統計GET /app/kevinContent接口在某天的調用次數,則可使用以下命令: [root@Fastdfs_storage_s1 ~]# cat /usr/local/nginx/logs/access.log | grep 'GET /app/kevinContent' | wc -l 其中cat用來讀取日誌內容,grep進行匹配的文本搜索,wc則進行最終的統計。 固然只用grep也能實現上述功能: [root@Fastdfs_storage_s1 ~]# grep 'GET /app/kevinContent' /usr/local/nginx/logs/access.log -c
2. 統計全部接口的調用次數並顯示出現次數最多的前二十的URL
[root@Fastdfs_storage_s1 ~]# cat /usr/local/nginx/logs/access.log|awk '{split($7,b,"?");COUNT[b[1]]++;}END{for(a in COUNT) print COUNT[a], a}'| sort -k1 -nr|head -n20 2722 / 10 /group1/M00/00/00/wKgKylqT3OCAUrqYAAAwK2jUNaY262.png 9 /group1/M00/00/00/wKgKylqUxBOAFo8hAAKHUIZ3K9s443.jpg 6 /group1/M00/00/00/wKgKylqUrceAGkPOAAAwK2jUNaY843.png 4 /group1/M00/00/00/wKgKylqTsFCAdeEuAAKHUIZ3K9s287.png 3 /group2/M00/00/00/wKgKy1qUtu2Acai1AAKHUIZ3K9s555.jpg 2 /favicon.ico 1 /group2/M00/00/00/wKgKy1qT3P-Ae-vQAAKHUIZ3K9s459.png 1 /group2/M00/00/00/wKgKy1qT3P-Ae-vQAAKHUIZ3K9s459.jpg 1 /group1/M00/00/00/wKgKylqUyMuAdkLwAAAwK2jUNaY176.png 1 /group1/M00/00/00/wKgKylqUtuyAA5xrAAKHUIZ3K9s226.jpg 1 /group1/M00/00/00/wKgKylqUscKAa4NXAAKHUIZ3K9s530.jpg 1 /group1/M00/00/00/wKgKylqTsFCAdeEuAAKHUIZ3K9s287.jpg 1 /group1/M00/00/00/wKgKylqT4ESAHdNjAAKHUIZ3K9s730.jpg 1 /group1/M00/00/00/wKgKylqT3-6AbEeUAAKHUIZ3K9s742.png 解釋說明: 這裏awk是按照空格把每一行日誌拆分紅若干項,其中$7對應的就是URL,固然具體對應的內容和使用nginx時設置的日誌格式有關。 這樣就能夠經過拆分提取出IP,URL,狀態碼等信息。split是awk的內置函數,在此的意思是按照「?」將URL進行分割獲得一個數組,並賦值給b。 COUNT[b[1]]++表示相同的接口數目加1。sort用來排序,-k1nr表示要把進行排序的第一列做爲數字看待,而且結果倒序排列。 head -n20意爲取排名前二十的結果。
3. 統計報錯的接口
統計nginx日誌中報錯較多的接口,對於分析服務器的運行狀況頗有幫助,也能夠有針對性的修復bug和性能優化。 [root@Fastdfs_storage_s1 ~]# cat /usr/local/nginx/logs/access.log|awk '{if($9==500) print $0}'| awk '{split($7,b,"?");COUNT[b[1]]++;}END{for(a in COUNT) print COUNT[a], a}'|sort -k 1 -nr|head -n10 先用awk’{if(9==500)print0}’過濾出500錯誤的日誌,而後在此基礎上作統計,其思路同2相似!
4. 統計HTTP響應狀態碼
經過統計響應狀態碼能夠看出服務器的響應狀況,好比499較多時能夠判斷出服務器響應緩慢,再結合3能夠找出響應慢的接口, 這樣就能有針對性進行性能分析和優化。 [root@Fastdfs_storage_s1 ~]# cat /usr/local/nginx/logs/access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}' | sort -k 2 -nr 200 2733 304 20 404 11
5. 統計服務器併發量
[root@Fastdfs_storage_s1 ~]# cat /usr/local/nginx/logs/access.log |grep '10.15.19.138'| awk '{COUNT[$4]++}END{for( a in COUNT) print a,COUNT[a]}' |sort -k 2 -nr|head -n20 nginx轉發請求時能夠記錄響應請求的服務器IP,先經過grep過濾出某個服務器全部的請求,而後統計各個時間點的併發請求響應的數量便可獲得某個服務器的併發量。 $4對應的是響應時間。固然,若是把grep的內容更換成某個接口也就能夠統計出該接口對應的併發量了。
6. grep多條件與或操做
有時候咱們須要在nginx日誌經過多個條件來查找某些特定請求,好比我須要找個某個用戶瀏覽文章的請求,則能夠須要同時匹配兩個條件: 瀏覽文章接口GET /app/kevinContent和userId=59h7hrrn。 grep對應的與操做命令以下: [root@Fastdfs_storage_s1 ~]# grep -E "GET /app/kevinContent.*userId=59h7hrrn" /usr/local/nginx/logs/access.log grep與命令格式: grep -E 「a.*b」 file,ab條件同時成立 而grep或命令的格式爲:grep -E 「a|b」 file ,ab兩個條件有一個成當即可。
7. grep打印匹配的先後幾行
有時候咱們須要查找某個特定請求的先後幾行的請求,以觀察用戶的關聯操做狀況。grep提供了一下幾條命令: # grep -C 5 'parttern' inputfile //打印匹配行的先後5行。 # grep -A 5 'parttern' inputfile //打印匹配行的後5行 # grep -B 5 'parttern' inputfile //打印匹配行的前5行 grep -An 或grep -A n grep -Bn 或grep -B n grep -Cn 或grep -C n 以下,打印出access.log日誌文件中匹配/app/kevinContent關鍵字符所在行的先後各10行 [root@Fastdfs_storage_s1 ~]# grep -C 10 'GET /app/kevinContent' /usr/local/nginx/logs/access.log