Apache Commons IO Tailer доставляет старые сообщения журнала
Мой код приведен ниже.
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()
возвращает ArrayList
содержит значения, такие как [информация, ошибка,abc.catch, предупреждение]. При запуске этого кода я получаю старое сообщение журнала, за которым следует новое сообщение журнала. Т.е. вывод такой:
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()
Как избежать получить старые сообщения журнала из файла журнала, как это?
3 ответа
О, мальчик, я потратил впустую целый день, думая, что это была моя хитрая нить, но теперь я вижу, что другие разделяют мою боль. Ну хорошо, по крайней мере я не буду тратить впустую еще один день, глядя на это
Но я посмотрел на исходный код. Я уверен, что ошибка происходит здесь, в файле 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 ССЫЛКА ЗДЕСЬ). Тем не менее, он помечен как решенный, и это явно не так. Я свяжусь с разработчиками, чтобы узнать, есть ли что-то в процессе разработки. Казалось бы, они того же мнения, что и я, по поводу исправления.
Какую версию commons.io вы использовали (использовали)? Я испытал эту ошибку с 2.0.1. Я обновил до 2.3, и, кажется, работает должным образом (пока)
Я знаю, что это очень старая тема, но я столкнулся с похожей проблемой с Tailer. Оказалось, что в Tailer два потока читают файл одновременно.
Я проследил это до того, как я создал экземпляр Tailer. Вместо того, чтобы использовать одну из трех рекомендаций (статический вспомогательный метод, Executor или Thread), я создал экземпляр с помощью статического вспомогательного метода, а затем передал созданный экземпляр в поток, который, по-видимому, привел к тому, что два потока читают файл.
Как только я исправил это (удалив вызов статического вспомогательного метода и просто используя один из перегруженных конструкторов Tailer и Thread), проблема исчезла.
Надеюсь, это кому-нибудь поможет.