一、背景介绍
1.当出现线上问题时,需要查询生产环境的日志排查定位问题原因,但生产环境的服务器是集群部署,每台机器上每天都会有日志产生,且每台机器上的日志不一样,通过依次登录每台机器去各个文件下查询日志,费时的重复性操作,令人厌烦;更让人糟心的是,有的机器上不一定能查到所需的日志;更让人无语的是,登录多台机器直至最后一台机器才查询到想要的日志;最让人崩溃的是,费劲滴在各个机器上查询了一遍结果却没有日志。
2.A与B系统由php语言实现,因人力、历史缘故、代码复杂度等一系列原因,目前由java语言实现的C系统对A与B系统达到了部分接口重构,现阶段未完全重构的整体系统链路调用关系如下图:
![](https://img-blog.csdnimg.cn/img_convert/e76fa591838aec8505b4aa8cc6ca0dc2.png)
生产环境上,A、B、C系统各有自己的集群部署机器,排查生产环境问题时,分别登录不同系统对应各个机器去查询日志,重复性的耗时费力工作量,可想而知。
二、目标制定
为了解决重复性、繁琐冗长命令操作带来的耗时费力问题,故而重新设计编写shell脚本,自动检索各个系统对应集群机器上的日志文件,减轻查询日志的重复性工作量,从而提高工作效率,以达到快速定位问题的目的。
三、具体要求
1.脚本执行执行有误有相应提示,以防忘却如何执行
2.脚本执行命令尽量简洁,避免输入繁琐冗长
3.脚本可以跨集群机器查询日志
4.脚本可以兼顾查询当日日志及历史日志
四、思路设计
1.执行脚本仅仅需要输入脚本名称+关键字+日期(可选)
日期作为非必输入项,最好支持多种格式
2.执行脚本命令输入有误,响应提示,提高易用性
3.根据系统遍历不同的集群机器,去查询日志
4.根据输入日期与否,判断查询当日日志亦或是历史日志
五、脚本实现
#!/bin/bash
#set -x
echo "------------------------start------------------------"
#关键词$1 日期$2
key_word=$1;
date=$2;
#参数校验
if [ -z "$1" -a -z "$2" ]
then
echo "脚本执行有误,请按照如下格式执行:"
echo "方式一:sh xxx.sh 关键字"
echo "方式二:sh xxx.sh 关键字 日期"
echo "------------------------end------------------------"
exit
fi
#校验日期
if [ -n "$2" ]
then
if echo $date | grep -Eq "[0-9]{4}[0-9]{2}[0-9]{2}" && date -d $date +%Y%m%d > /dev/null 2>&1
then
format_date=$(date -d ${date} +'%Y-%m-%d')
elif echo $date | grep -Eq "[0-9]{4}-[0-9]{2}-[0-9]{2}" && date -d $date +%Y%m%d > /dev/null 2>&1
then
format_date=$date
else
echo "日期格式不正确,应为yyyymmdd或yyyy-mm-dd"
echo "------------------------end------------------------"
exit 1;
fi
fi
#根据系统划分查询日志
for system in 系统C 系统B 系统A
do
if [ "系统C" == $system ]
then
echo "----------------开始查询system:${system}日志----------------"
#日志文件的存储目录
logfile_path=/data/logs/${system}/
#历史日志文件
logfile_nottoday="${logfile_path}${system}.log.${format_date}.gz"
#当日日志文件
logfile="${system}.log"
#循环灰度及线上环境机器IP
for ip in 100.109.89.204 100.109.89.203 100.105.80.184 100.105.80.185 100.109.86.216 100.109.89.205 100.105.80.186
do
#根据关键字及日期查询日志
if [ -n "$key_word" -a -n "$format_date" ]
then
echo "查询当前日志对应的IP为$ip"
ssh -i readonly readonly@$ip zcat $logfile_nottoday | grep $key_word --color
elif [ -n "$key_word" -a -z "$format_date" ]
then
echo "查询当前日志对应的IP为$ip"
ssh -i readonly readonly@$ip cat $logfile_path$logfile | grep $key_word --color
else
echo "脚本执行有误"
echo "------------------------end------------------------"
exit
fi
done
echo -e "----------------system:${system}日志查询完毕----------------\n"
elif [ "系统B" == $system -o "系统A" == $system ]
then
echo "----------------开始查询system:${system}日志----------------"
#日志文件的存储目录
logfile_path=/data/logs/${system}/
#历史日志文件
logfile_nottoday="${logfile_path}backuplogs/${date}/${system}.log*"
#当日日志文件
logfile="${system}.log*"
#登录灰度及线上环境机器IP
for ip in 100.109.91.229 100.109.91.228 100.105.85.106 100.105.85.105 100.109.79.239
do
#根据关键字及日期查询日志
if [ -n "$key_word" -a -n "$date" ]
then
echo "查询当前日志对应的IP为$ip"
ssh -i readonly readonly@$ip zcat $logfile_nottoday | grep $key_word --color
elif [ -n "$key_word" -a -z "$date" ]
then
echo "查询当前日志对应的IP为$ip"
ssh -i readonly readonly@$ip cat $logfile_path$logfile | grep $key_word --color
else
echo "脚本执行有误"
echo "------------------------end------------------------"
exit
fi
done
echo -e "----------------system:${system}日志查询完毕----------------\n"
fi
done
echo "------------------------end------------------------"
六、日志查询
情景1、查询当日日志
查询方式:sh xxx.sh 关键字
[user@admin-堡垒机跳板机 blj]$ sh find.sh a44613739aa04679858bb3055370563f
情景2、查询历史日志
查询方式:sh xxx.sh 关键字 日期
[user@admin-堡垒机跳板机 blj]$ sh find.sh 8b4d0b6f979a45119bad4dd4c2558d8a 20201021
或
[user@admin-堡垒机跳板机 blj]$ sh find.sh 8b4d0b6f979a45119bad4dd4c2558d8a 2020-10-21
情景3、输入日期有误
[user@admin-堡垒机跳板机 blj]$ sh find.sh 8b4d0b6f979a45119bad4dd4c2558d8a 2020102100:25:33
------------------------start------------------------
日期格式不正确,应为yyyymmdd或yyyy-mm-dd
------------------------end------------------------
情景4、脚本执行有误
[user@admin-堡垒机跳板机 blj]$ sh find.sh
------------------------start------------------------
脚本执行有误,请按照如下格式执行:
方式一:sh xxx.sh 关键字
方式二:sh xxx.sh 关键字 日期
------------------------end------------------------
情景5、查无日志
[user@admin-堡垒机跳板机 blj]$ sh find.sh wieudksln23r9045k092j3lkdkldajsf
------------------------start------------------------
----------------开始查询system:系统C日志----------------
查询当前日志对应的IP为100.109.89.204
查询当前日志对应的IP为100.109.89.203
查询当前日志对应的IP为100.105.80.184
查询当前日志对应的IP为100.105.80.185
查询当前日志对应的IP为100.109.86.216
查询当前日志对应的IP为100.109.89.205
查询当前日志对应的IP为100.105.80.186
----------------system:系统C日志查询完毕----------------
----------------开始查询system:系统B日志----------------
查询当前日志对应的IP为100.109.91.229
查询当前日志对应的IP为100.109.91.228
查询当前日志对应的IP为100.105.85.106
查询当前日志对应的IP为100.105.85.105
查询当前日志对应的IP为100.109.79.239
----------------system:系统B日志查询完毕----------------
----------------开始查询system:系统A日志----------------
查询当前日志对应的IP为100.109.91.229
查询当前日志对应的IP为100.109.91.228
查询当前日志对应的IP为100.105.85.106
查询当前日志对应的IP为100.105.85.105
查询当前日志对应的IP为100.109.79.239
----------------system:系统A日志查询完毕----------------
------------------------end------------------------
七、效果收益
1.避免了重复性操作,节省了时间
2.提高了查询日志的效率
3.提升了执行脚本的运行体验