我的代码如下。
public static void main(String[] args) {
// TODO code application logic here
File pcounter_log = new File("c:\development\temp\test.log");
try {
Tailer tailer = new Tailer(pcounter_log, new FileListener("c:\development\temp\test.log",getLogPattern()), 5000,true);
Thread thread = new Thread(tailer);
thread.start();
} catch (Exception e) {
System.out.println(e);
}
}
public class FileListener extends TailerListenerAdapter {
public void handle(String line) {
for (String logPattern : pattern) {
if (line.contains(logPattern)) {
logger.info(line);
}
}
}
}
此处getLogPattern()
返回包含[info,error,abc.catch,warning]等值的ArrayList
。运行此代码时,我会收到旧的日志消息,然后是新的日志消息。即输出是这样的:
20 May 2011 07:06:02,305 INFO FileListener:? - 20 May 2011 07:06:01,230 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:06:55,052 INFO FileListener:? - 20 May 2011 07:06:55,016 DEBUG - readScriptErrorStream()
20 May 2011 07:06:56,056 INFO FileListener:? - 20 May 2011 07:06:55,040 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:07:01,241 INFO FileListener:? - 20 May 2011 07:07:01,219 DEBUG - readScriptErrorStream()
20 May 2011 07:07:02,245 INFO FileListener:? - 20 May 2011 07:07:01,230 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:07:55,020 INFO FileListener:? - 20 May 2011 07:07:55,016 DEBUG - readScriptErrorStream()
20 May 2011 07:07:56,024 INFO FileListener:? - 20 2011 07:07:55,030 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:08:01,269 INFO FileListener:? - 20 May 2011 07:08:01,227 DEBUG - readScriptErrorStream()
20 May 2011 07:08:02,273 INFO FileListener:? - 20 May 2011 07:08:01,230 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:08:21,234 INFO FileListener:? - 20 May 2011 06:40:02,461 DEBUG - readScriptErrorStream()
20 May 2011 07:08:22,237 INFO FileListener:? - 20 May 2011 06:40:02,468 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:08:23,242 INFO FileListener:? - 20 May 2011 06:41:01,224 DEBUG - readScriptErrorStream()
20 May 2011 07:08:24,250 INFO FileListener:? - 20 May 2011 06:41:01,232 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:08:25,261 INFO FileListener:? - 20 May 2011 06:42:01,218 DEBUG - readScriptErrorStream()
20 May 2011 07:08:26,265 INFO FileListener:? - 20 May 2011 06:42:01,230 DEBUG - exiting readScriptErrorStream()
20 May 2011 07:08:27,272 INFO FileListener:? - 20 May 2011 06:43:01,223 DEBUG - readScriptErrorStream()
20 May 2011 07:08:28,275 INFO FileListener:? - 20 May 2011 06:43:01,231 DEBUG - exiting readScriptErrorStream()
如何避免从这样的日志文件中获取旧的日志消息?
答案 0 :(得分:1)
哦,小男孩,我浪费了一整天的时间,认为这是我的狡猾的线程,但我现在看到其他人分享了我的痛苦。哦,好吧,至少我不会浪费另一天看它。
但我确实看过源代码。我确定Tailer.java文件中出现错误:
boolean newer = FileUtils.isFileNewer(file, last); // IO-279, must be done first
...
...
else if (newer) {
/*
* This can happen if the file is truncated or overwritten with the
* exact same length of information. In cases like this, the file
* position needs to be reset
*/
position = 0;
reader.seek(position);
...
在写入数据之前,文件修改数据似乎可能会发生变化。我不知道为什么会这样。我从网络上获取我的日志文件,所以也许正在进行各种缓存,这意味着你不会认为新文件将包含更多数据。
我更新了源代码并删除了此部分。对我来说,以完全相同的字节数截断/重新创建文件的可能性很小。我正在引用10MB滚动日志文件。
我发现这是一个已知问题(IO-279 LINK HERE)。但是,它被标记为已解决,显然并非如此。我会联系开发人员,看看是否有什么东西在管道中。看起来他们和我一样对修复问题持有同样的看法。
答案 1 :(得分:0)
您使用的是什么版本的commons.io? 我在2.0.1中遇到了这个错误。我更新到2.3,它似乎正常工作(到目前为止)
答案 2 :(得分:0)
我知道这是一个非常古老的主题,但我遇到了与Tailer类似的问题。事实证明,Tailer有两个线程同时读取文件。
我追溯到我如何创建Tailer实例。我使用静态帮助器方法创建了实例,然后将创建的实例提供给一个看起来导致两个线程读取文件的Thread,而不是使用他们的3个推荐(静态帮助器方法,执行器或线程)中的一个。
一旦我纠正了这一点(通过删除对静态助手方法的调用,只使用其中一个重载的Tailer构造函数和一个Thread),问题就消失了。
希望这有助于某人。