shell 按时间段截取日志

作为运维工作人员,看日志查问题,以及统计日志关键字,是很常见的工作。有时候由于访问量大,加上开发未能很好地控制日志级别,导致日志刷得非常快,不容易实时查问题不说,还会导致日志非常大,后期查询统计也不方便。

现在就来说说,如何使用 shell 命令,截取一段时间内的日志并进行保存分析。

前提

日志输出包含时间。

案例

日志名:quartz.log。

日志内容:

1
[2016-05-27 09:48:52,332] [Scheduler_Worker-10] (AbstractCommonQuartzJob.java:71) INFO  com.busi.job.AgentSeachXmlJob - 定时任务耗时:52301毫秒,定时任务结束!

脚本

提取5分钟内最新的日志,并统计耗时。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FILE="quartz.log"

awk -F , -v s="`date -d -5mins +\"[%Y-%m-%d %H:%M:%S\"`" '$1>s' ${FILE}|grep "定时任务耗时"|sed -e 's/\[//g;s/\]//g'|awk -F ',| ' '{print $1" "$2"|"$6"|"$8"|"$10}'|sed 's#定时任务耗时:##g;s#毫秒##g'

#使用awk截取日志前的时间,并用s变量获取相应格式化5分钟前的时间,最后对比两者的字符串(间接进行时间对比,所以此方法可能存在漏洞)。把时间大于5分钟前时间的日志输出,并进行后期格式化。

#输出内容为:
2016-05-27 10:40:50|INFO|com.busi.job.SendJob|77
2016-05-27 10:40:55|INFO|com.busi.job.SendJob|56
2016-05-27 10:41:00|INFO|com.busi.job.SendJob|88
2016-05-27 10:41:05|INFO|com.busi.job.SendJob|178
2016-05-27 10:41:10|INFO|com.busi.job.SendJob|104
2016-05-27 10:41:15|INFO|com.busi.job.SendJob|143
2016-05-27 10:41:20|INFO|com.busi.job.SendJob|172
2016-05-27 10:41:22|INFO|com.busi.job.SendJob|81656
2016-05-27 10:41:25|INFO|com.busi.job.SendJob|89
2016-05-27 10:41:30|INFO|com.busi.job.SendJob|203
2016-05-27 10:41:35|INFO|com.busi.job.SendJob|72

提取指定时间段内最新日志,并统计耗时。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FILE="quartz.log"

#定义前时间
S_TIME="20160527 10:41:30"
E_TIME="20160527 10:42:00"

#执行命令
awk -F , -v s="`date -d "${S_TIME}" +\"[%Y-%m-%d %H:%M:%S\"`" -v e="`date -d "${E_TIME}" +\"[%Y-%m-%d %H:%M:%S\"`" '$1>s&&$1<e' ${FILE}|grep "定时任务耗时"|sed -e 's/\[//g;s/\]//g'|awk -F ',| ' '{print $1" "$2"|"$6"|"$8"|"$10}'|sed 's#定时任务耗时:##g;s#毫秒##g'

#和截取5分钟日志的原理一样,只不过多设置了个变量和判断。

#输出内容为:
2016-05-27 10:41:35|INFO|com.busi.job.SendJob|72
2016-05-27 10:41:40|INFO|com.busi.job.SendJob|78
2016-05-27 10:41:45|INFO|com.busi.job.SendJob|87
2016-05-27 10:41:50|INFO|com.busi.job.SendJob|53
2016-05-27 10:41:55|INFO|com.busi.job.SendJob|184

应用:

截取到合适的信息后,输出重定向一下,就可以保存下来以便后期处理。

比如把 5 分钟统计命令保存为脚本, crontab 每 5 分钟执行一次(评估执行一次需要多长时间,调整合适的间隔时间),直接把结果输入 result.log ,再写个脚本,定期把 result.log 的内容读取并写入数据库(之所以用 | 分割,也是为了处理方便),后续需要统计耗时,成功率之类的,可以直接从数据库获取。这样,便形成了一个轻量级的日志分析系统,时间间隔调整准确的话,虽然可能数据还会有些轻微的差异,但也八九不离十了。