线上的项目需要实时监控日志来分析用户行为和系统健康情况,我们可以通过分析系统日志来知道系统的实时运行情况,然而系统的日志又非常多,有
tomcat日志、ng日志、mysql日志、lvs日志等等非常多的日志信息,如何在这么多的日志信息中捕获出我们需要的日志是一件有价值的事情。
下面我来介绍一下如何利用antlr来分析出ng日志中timeout的日志信息,
ng中的timeout日志格式:
2013/07/24 16:02:52 [error] 3389#0: *31309 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.30.52, server: tj.playsnail.com, request: "GET /gather/data.do?data=0-3-4-4-1:211182,2:12,3:12001&_=1374652788858 HTTP/1.1", upstream: "http://10.103.20.6:9088/gather/data.do?data=0-3-4-4-1:211182,2:12,3:12001&_=1374652788858", host: "tj.playsnail.com", referrer: "http://www.playsnail.com/platform/game/frame?gameId=12&serverId=12001" |
在解析日志,我们需要抽取哪些接口报了异常,在什么时候报的异常是我们比较感兴趣的数据,所以定义日期和时间的语法定义,
日志中的日期和时间的格式:2013/07/24 16:02:52 ,那么在antlr中可以这样来定义:
INT : [0-9]+ ; date: INT '/' INT '/' INT ; time: INT ':' INT ':' INT ; |
下面再定义timeout时 url的语法规则,分析ng日志,发现接口的url规则:都以 upstream开头,后面是以双引号开始和结束,如下是ng的超时接口片段:
upstream: "http://10.103.20.6:9088/gather/data.do?data=0-3-4-4-1:211182,2:12,3:12001&_=1374652788858" |
那么可以定义如下的语法规则:
url : 'upstream:' '"' 'http://' ~'"'* '"'; |
对于整个timeout的异常信息的语法定义如下:
date time '[error]' INT '#' INT ':' '*' INT 'upstream timed out' (CHAR | url | ~'\n' )* NL* EOF?;
于是整个的语法文件就如下:
grammar Timeout;
file: (expectedRows | .)*; INT : [0-9]+ ; date: INT '/' INT '/' INT ; time: INT ':' INT ':' INT ; //STRING: ~'\n'*; NL : '\n' ; WS : ' ' -> skip ; //WS : [\n\t\r] -> skip ; ID: [a-zA-Z_$] [a-zA-Z_$0-9]* ; CHAR : '('|')'|','|'?'|'.'|'='|'"'|'-'|'&'|':'|'%'|'['|']'|'@'|'{'|'}'|'\\"'; url : 'upstream:' '"' 'http://' ~'"'* '"'; expectedRows: date time '[error]' INT '#' INT ':' '*' INT 'upstream timed out' (CHAR | url | ~'\n' )* NL* EOF? |
在antlr提供的visitor接口中我们可以动态的获取每个超时日志的信息中的日期、时间和超时接口等信息,然后我们利用mysql或者nosql这样的工具来把这些数据入库做
数据筛选查询,这就满足了我们对哪些应用在什么时间段发生了超时,一天中哪个时间段发生超时访问,再结合实时的监控数据,比如:系统各个方面的资源消耗,cpu ,
memory, jvm gc 时长,网络吞吐量等数据一起分析,就能够达到我们实时的多角度分析系统的目的。