我们搞运维的总幻想着,任何线上问题都能靠它自己自愈,它只需要在发生问题时自动解决问题后通知一下我们即可!
这不,今天就有这样一个小需求,对你来说一定非常简单。
【需求】
写一个自动化重启服务脚本,当访问日志频繁出现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.36171.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.36171.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.36123.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/bashlogfile=/data/logs/www_access.loglast_t=`date -d -1 min +%y:%h:%m`tail -n 10000 $logfile |grep /${last_t}: > /tmp/last.loglast_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-fpmfi
浅析锐龙4000系列 锐龙7-4800U和锐龙7-4800H和酷睿i9打平?
Intel处理器占据CPU单线程性能前17位 酷睿i9-9900KS仍稳居榜首
蓄电池的开路电压_蓄电池的终止电压
电子闹钟diy 从此不再被吵醒而是被吓醒
5G工业网关和4G工业网关有什么区别?
写一个自动化重启服务脚本
从EDA技术演变里看芯片创新之未来
电子芯闻早报:Intel最新战略引台厂响起警报
气密测试仪设备如何安装?是否需要定期维护?
AMDVega56深度评测 与1070非公默认极限大致相当
小米MIX 3即将发布,将搭载更快的无线充电
智能安防格局谁能来重塑
华为鸿蒙系统能否赶超苹果IOS系统呢
小米mix2怎么样?小米mix2评测:不再惊艳的小米mix2更值得入手
浅析2021年MCU行业发展现状及未来趋势
在线视频服务器租用如何配置?
可编程序控制器程序设计
台湾通嘉LD7792SGS集成芯片PFC+QR
智行者获北京T3级自动驾驶车辆道路测试许可
雷柏发布 ralemo Pre 5 圣诞定制版无线机械键盘和鼠标,自主研发的机械轴体