代码之家  ›  专栏  ›  技术社区  ›  Sudhanshu Umalkar

用Java增量读取日志文件

  •  0
  • Sudhanshu Umalkar  · 技术社区  · 14 年前

    我需要以增量方式读取和处理日志文件。在Java中如何做到这一点有什么建议吗?

    我需要考虑所有可能的场景,如文件滚动、不同的日志格式等。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Martijn Verburg    14 年前

    你可以看看 Chainsaw

        2
  •  2
  •   halfer    6 年前

    虽然已经很晚了,但是我只是想写一个实现这个功能的方法。

    假设我们开始一项工作,每隔5分钟定期读取一个文件。

    1. 在第一次运行期间,读取整个文件
    2. 存储行计数和文件的上次修改时间

      它对于随后的作业运行变得有趣。

    3. 在下一个作业运行期间,检查文件是否已修改(使用上次修改的文件时间和上次作业运行期间存储的文件时间)。如果文件未被修改,则不执行任何操作。

    4. 如果文件被修改了,我们只需要读取新行。我们有先前作业的行数,因此使用它来确定要跳过的行数。

      到目前为止还不错,如果文件被翻过来怎么办?

    5. 假设我们有文件翻滚时的文件命名模式。。。

    6. 获取与模式匹配的所有文件,并根据文件上次修改的时间按升序排序
    7. 遍历这些文件,并从上次修改时间大于上次运行作业所存储时间的文件开始。巧妙地使用存储行计数跳过已读的行
    8. 从新文件开始时重置行计数

    就这样!

    对于一些奇怪的情况,您可能需要在一些地方设置IF条件。其中一种情况是,当您在文件中迭代时,如果文件上次修改的时间与存储的时间完全相同,则只需重置行数-以便它从下一个/新文件的第一行开始。

    后续作业运行的示例代码:

    for(File file : files) {<BR>
      if(file.lastModified() > storedLastModifiedTime) {<BR>
        // you have the file to process, take care of the line count<BR>
      } else if(file.lastModified() == storedLastModifiedTime) {<BR>
        // reset stored line count<BR>
      }<BR>
    }<BR>
    
        3
  •  0
  •   Jacek Prucia    14 年前

    我正试图解决几乎相同的问题。它看起来并不像乍一看那么微不足道。您必须忽略EOF/EOS的概念,并且必须跟踪日志文件中的位置。

    我认为最好的方法是有一个单独的线程来读取日志文件。我做了个测试 BufferedReader 这是很有希望的。线程读取文件末尾的所有数据(其中 readLine() 回报 null )然后睡觉N秒(我的情况是5秒)。然后在醒来后再次尝试读一句台词。如果它回来了 String ,它继续处理。如果它得到 无效的 它又睡着了。它在每次成功读取时递增行计数器,在停止/启动时写入/读取行计数器,这样它就可以定位日志文件中的最后一个位置并从该位置开始。

    这种方法的唯一问题是N秒的等待。如果有一种方法告诉Java“block on readLine() 不考虑EOF/EOS”。在N秒钟的等待中,您可能正在睡眠,而数据已经可用。不过,睡眠似乎是必要的,除非你想吃掉所有的CPU功率。