Spring Batch:如何处理多行日志文件

我试图使用Spring Batch将日志文件的内容导入数据库。

我目前正在使用FlatFileItemReader,但遗憾的是有许多日志条目无法捕获。 两个主要问题是:

  1. 包含多行JSON字符串的行:

    2012-03-22 11:47:35,307 DEBUG main someMethod(SomeClass.java:56): Do Something(18,true,null,null,null): my.json = '{ "Foo":"FooValue", "Bar":"BarValue", ... etc }' 
  2. 包含堆栈跟踪的行

     2012-03-22 11:47:50,596 ERROR main com.meetup.memcached.SockIOPool.createSocket(SockIOPool.java:859): No route to host java.net.NoRouteToHostException: No route to host at sun.nio.ch.Net.connect0(Native Method) at sun.nio.ch.Net.connect(Net.java:364) at sun.nio.ch.Net.connect(Net.java:356) at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:623) at sun.nio.ch.SocketAdaptor.connect(SocketAdaptor.java:92) at com.meetup.memcached.SockIOPool$SockIO.getSocket(SockIOPool.java:1703) at com.meetup.memcached.SockIOPool$SockIO.(SockIOPool.java:1674) at com.meetup.memcached.SockIOPool.createSocket(SockIOPool.java:850) at com.meetup.memcached.SockIOPool.populateBuckets(SockIOPool.java:737) at com.meetup.memcached.SockIOPool.initialize(SockIOPool.java:695) 

基本上,我需要FlatFileItemReader继续读取,直到它到达下一个时间戳,同时聚合所有行。 之前有没有做过这样的事情(在Spring Batch中)

现在有一个解决此用例的Spring Batch文档中的FAQ。

解决方案是编写一个自定义阅读器,回溯最后几行并查找标记有效行开始的特定模式。 我没有在Spring Batch中找到任何预先制作的东西,但我可以重用大量现有代码。 该解决方案是专有的,所以我不能在这里发布,抱歉,但这是它的工作原理:

  1. 保持Lines的LinkedList。 LinkedList很重要,因为我们将它们作为List和Queue访问。
  2. 在read方法中,启动循环:读取下一行并将其写入队列。 检查你的队列,看看你是否有两条有效的线路(这里你需要列表访问)。 如果这样做,则返回第二个有效行之前的所有行(并从队列中删除它们)。 如果找不到任何有效行,则返回null。

毋庸置疑,此解决方案明显慢于内置的FlatFileItemReader,但它可以获得正确的数据。