对于日志的采集,给出一个常规的思路:
执行采集日志应用(非web程序),使用文件流读取文本文件,当读取到文件末尾时,可以让当前线程睡眠一段时间,从而达到对日志采集的目的。
这样就会出现几个问题:
1、当应用异常终止时,重新启动,那样问题就来了:出现对日志的重复采集。
想了下,也没什么更好的办法,于是采集到的日志行数保存在一个文件中,当重新启动时,读取改文件对日志文件进行定位采集。
2、日志文件一般情况下并不是有规律的,需要更多的配置RE进行匹配。
下面介绍RE的常规用法:
比如有如下日志
Mar 3 10:39:31 linux-c3xt slapd[4081]: conn=25 fd=9 ACCEPT from IP=192.168.0.1:4142 (IP=0.0.0.0:389) Mar 3 10:39:31 linux-c3xt slapd[4081]: conn=25 op=0 BIND dn="uid=elfinesh,ou=People,o=ethionet.et,o=etc" method=128 Mar 3 10:39:31 linux-c3xt slapd[4081]: perform_search: performing search in cn=elfinesh,cn=006,cn=testispusers,dc=sctel,dc=com,dc=cn, with filter (objectclass=*). Mar 3 10:39:31 linux-c3xt slapd[4081]: conn=25 op=0 BIND dn="uid=elfinesh,ou=People,o=ethionet.et,o=etc" mech=SIMPLE ssf=0 Mar 3 10:39:31 linux-c3xt slapd[4081]: conn=25 op=0 RESULT tag=97 err=0 text= Mar 3 10:39:31 linux-c3xt slapd[4081]: conn=25 op=1 UNBIND Mar 3 10:39:31 linux-c3xt slapd[4081]: conn=25 fd=9 closed
开始解析的RE:
(\\w+\\s+\\d+\\s+\\d{2}:\\d{2}:\\d{2})\\s+.+\\s+slapd+\\[\\d+\\]:\\s+conn=\\d+\\s+fd=\\d+\\s+ACCEPT\\s+from\\s+IP=.+
得到uid的RE:
\\w+\\s+\\d+\\s+\\d{2}:\\d{2}:\\d{2}\\s+.+\\s+slapd+\\[\\d+\\]:\\s+conn=\\d+\\s+op=\\d+\\s+BIND\\s+dn=\\\"uid=(\\w+),ou.+
得到返回结果的RE:
\\w+\\s+\\d+\\s+\\d{2}:\\d{2}:\\d{2}\\s+.+\\s+slapd+\\[\\d+\\]:\\s+conn=\\d+\\s+op=\\d+\\s+RESULT\\s+tag=\\d+\\s+err=(\\d+)\\s+.+
结束的RE:
\\w+\\s+\\d+\\s+\\d{2}:\\d{2}:\\d{2}\\s+.+\\s+slapd+\\[\\d+\\]:\\s+conn=\\d+\\s+fd=\\d+\\s+closed
使用的时候比较简单,比如定义的RE为re0
RE r = new RE(re0); if (r.match(读取日志文件的一行)) { String str= r.getParen(1); // 这样就可以获取括号里面的内容了 }
3、日志文件通常会限制大小,所以当日志文件会出现备份的情况,要考虑是否对备份日志文件的读取,如xx.log.1这种情况。
4、对于一些特殊情况,日志并不是孤立存在的,如存在请求日志和响应日志,需要对两个日志文件进行同步采集。另外,如果涉及到多系统(多IP采集),可以使用到线程池进行优化处理。
对于线程池的使用,后面再来整理。