我們搞運維的總幻想著,任何線上問題都能靠它自己自愈,它只需要在發生問題時自動解決問題后通知一下我們即可!
這不,今天就有這樣一個小需求,對你來說一定非常簡單。
【需求】
寫一個自動化重啟服務腳本,當訪問日志頻繁出現502狀態碼時,重啟php-fpm服務。
提示:
假定Ngnix訪問日志路徑為/data/logs/www_access.log
重啟php-fpm服務的命令為systemctl restart php-fpm
訪問日志片段(里面的200就是狀態碼)
123.52.13.247 - [30/Jul/202203:15 +0800]bbs.aabcc.cn "/thread-2403963-2-198.html" 200 "http://bbs.aabcc.cn/thread-2403963-1-198.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" 171.8.172.146 - [30/Jul/202203:15 +0800]bbs.aabcc.cn "/thread-2430178-2-7.html" 200 "http://bbs.aabcc.cn:8234/thread-2430178-8-7.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" 171.8.173.103 - [30/Jul/202203:15 +0800]bbs.aabcc.cn "/forum.php?mod=viewthread&action=printable&tid=2407976" 200 "http://bbs.aabcc.cn:8784/forum.php?mod=viewthread&tid=2407976&extra&ordertype=2" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" 123.52.13.247 - [30/Jul/202203:15 +0800]bbs.aabcc.cn "/thread-2396686-1-245.html" 200 "http://bbs.aabcc.cn/thread-2396686-2-245.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
腳本可以每分鐘執行一次,腳本執行時截取上一分鐘的日志,可以計算總日志行數,和出現502的行數,計算比例,這里我給大家定一個比例吧,超過20%就算是有問題啦
【解析】
首先,給出思路:
每分鐘執行腳本,將過去一分鐘的日志截取出來;
然后分析這一分鐘內的日志,計算日志總行數,計算狀態碼為502的日志行數;
兩個數字相除,計算百分比;
拿到百分比數字和20相比較;
高于20執行重啟php-fpm服務的命令;
先看第一個需求點,如何拿到過去一分鐘的日志?
看日志片段吧,很明顯日志里有一個時間字段 "30/Jul/202203:15"
過去一分鐘,就是拿當前的分鐘減去一分鐘,date就可以實現啊 :
date -d "-1 min" +%Y:%H:%M
為了過濾的更加精準,建議在最后面再加個:
所以,從訪問日志中截取過去一分鐘的日志可以這樣做:
last_t=`date -d "-1 min" +%Y:%H:%M"` tail -n 10000 /data/logs/www_access.log |grep "/${last_t}:" > /tmp/last.log
解釋一下,為什么tail -n 10000呢,因為如果訪問日志很大的話,直接去grep會比較耗費時間,所以先將最后面的1w行截取出來,效率會高很多。
當然,這個1w是我預估的,大家也可以根據實際的日志量來評估這個數字,你也可以是1000行。
將過濾后的日志先存放到一個臨時文件里,留著備用。
下面就該計算日志總行數,這個很簡單,直接 wc -l /tmp/last.log 就行了。
而502狀態碼的日志行數,還需要使用grep:
grep -c '" 502 "' /tmp/last.log
大家注意,502左右都帶有空格,這是為了更加精準匹配,因為日志里很有可能其它地方包含502關鍵詞。
拿到兩個數字后,接下來就該計算百分比了。
百分比要精確到小數點后兩位,所以不能直接使用shell中的數學運算,得借助于一個linux下的計算器bc,先看例子吧 :
echo "scale=2; 12*100/101"|bc
所以對應到本案例中,假設502行數用s502_c變量標記,最后1分鐘日志總行數用last_1min_c標記,計算百分比,這樣做:
echo "scale=2; ${s502_c}*100/${last_1min_c}"|bc
由于shell中的數學邏輯運算不能使用小數來比較,所以還需要將上面獲取到的數字進一步包裝,可以將其乘以100,也就是去掉點:
echo "scale=2; ${s502_c}*100/${last_1min_c}"|bc|sed 's/.//'
獲取到這個數字后,然后再與2000進行比較。
之后,就是去做判斷,若符合條件進行重啟操作。
【參考答案】
腳本最終是這樣的:
#!/bin/bash logfile="/data/logs/www_access.log" last_t=`date -d "-1 min" +%Y:%H:%M` tail -n 10000 $logfile |grep "/${last_t}:" > /tmp/last.log last_1min_c=`wc -l /tmp/last.log|awk '{print $1}'` s502_c=`grep -c '" 502 "' /tmp/last.log` p=`echo "scale=2; ${s502_c}*100/${last_1min_c}"|bc|sed 's/.//'` if [ $p -gt 2000 ] then echo "`date` 502日志大于20%,需要重啟php-fpm服務" >> /tmp/restart_php-fpm.log systemctl restart php-fpm fi
審核編輯:劉清
-
Linux
+關注
關注
87文章
11229瀏覽量
208931 -
PHP
+關注
關注
0文章
452瀏覽量
26650 -
Shell
+關注
關注
1文章
363瀏覽量
23297 -
FPM
+關注
關注
0文章
5瀏覽量
1281
發布評論請先 登錄
相關推薦
評論