【发布时间】:2016-03-21 16:40:14
【问题描述】:
这是我的日志的简单通用规范:
- 一个请求来了,记录
...[XXXHandler] comming time... - 获取锁定并开始事务,记录
...[XXXHandler] [UID] start time... - 业务完成并返回锁,记录
...[XXXHandler] [UID] spend time...
在实践中,有大量的请求以各自的 UID 齐平,三行模式相互混乱。这是其中的一部分:
~ cat sample.log
[240] [DeleteAllLettersHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [DeleteAllLettersHandler] [13497] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [DeleteAllLettersHandler] [13497] spend time [1] dbs 1 dbu 1 | {}
[240] [StartBiddingAllianceBossAuctionHandler] [1495] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetMazeMainInfoHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [1495] spend time [1] dbs 1 dbu 0 | {}
[240] [GetMazeMainInfoHandler] [8941] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetResHarvestInfoHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetResHarvestInfoHandler] [1807] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [RCHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016] ## gotcha
[240] [GetMazeMainInfoHandler] [8941] spend time [10] dbs 27 dbu 2 | {}
[240] [GetResHarvestInfoHandler] [1807] spend time [5] dbs 15 dbu 4 | {}
[240] [StartBiddingAllianceBossAuctionHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [18052] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [18052] spend time [1] dbs 1 dbu 0 | {}
[240] [GetResourceAmount] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetResourceAmount] [29063] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetResourceAmount] [29063] spend time [1] dbs 3 dbu 0 | {}
我的要求是过滤日志,删除杂乱的三行模式,同时我可以看到哪个处理程序挂起(日志来了但没有开始时间)。
这是我的解决方案:
- cat process.sh
sed -r '
$!N
$!N
$!N
s/(([^\n]*\n)*)[^\n]*\[([^\n]*)\] coming time[^\n]*\n(([^\n]*\n)*)[^\n]*\[\3\] \[([^\n]*)\] start time[^\n]*\n(([^\n]*\n)*)[^\n]*\[\3\] \[\6\] spend time[^\n]*(.*)/\1\4\7\9/
t print
P
D
:print
' |
grep -v '^ *$'
这可以过滤一些模式,但不是全部,因为 sed 可以处理分散在三或四行的一个模式(sed 轮添加可能更多)行。
~ ./process.sh < sample.log
[240] [StartBiddingAllianceBossAuctionHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [1495] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetMazeMainInfoHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [1495] spend time [1] dbs 1 dbu 0 | {}
[240] [GetMazeMainInfoHandler] [8941] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [RCHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016] ## gotcha
[240] [GetMazeMainInfoHandler] [8941] spend time [10] dbs 27 dbu 2 | {}
[240] [StartBiddingAllianceBossAuctionHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [18052] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [StartBiddingAllianceBossAuctionHandler] [18052] spend time [1] dbs 1 dbu 0 | {}
将过滤后的日志作为SEED,一次次过滤,就能得到我想要的结果:
~ ./process.sh < sample.log | ./process.sh
[240] [GetMazeMainInfoHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [GetMazeMainInfoHandler] [8941] start time [Fri Mar 18 05:00:00 GMT-06:00 2016]
[240] [RCHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016] ## gotcha
[240] [GetMazeMainInfoHandler] [8941] spend time [10] dbs 27 dbu 2 | {}
~ ./process.sh < sample.log | ./process.sh | ./process.sh
[240] [RCHandler] coming time [Fri Mar 18 05:00:00 GMT-06:00 2016] ## gotcha
看来我只需要再过滤几次就可以得到最终需要的结果。于是我问了一个问题:shell pipe process repeat, @tripleee 的回答对我很有用。大致经过五次过滤后,我可以得到每条日志的最终结果。
但是耗时太长,一个10K行的日志,这样过滤一般需要10分钟。
所以我的问题是,你能想出一个更好的方法吗?或者如何改进我的方式让它运行得更快。
感谢您的宝贵时间!
【问题讨论】:
-
来的时间和开始时间的记录对你来说还不够吗?
-
@user3132194 我必须找到挂在那里的处理程序。
-
如果挂起的处理程序不再启动,您可以通过获取每个处理程序的最后一次发生并检查它是否包含
coming time来简化任务。 -
@Hedley Yan 我的意思是您可以按处理程序计算到来和开始记录的出现次数。如果它们长时间不同 - 那么这个处理程序出了点问题。如果它是某种监控任务,那么您可以通过管道
tail -f到您的脚本在线检查它,它应该可以缓解性能问题。 -
@user3132194 明白你的意思,谢谢