异步日志记录

现在在我的应用程序中,在某些时候我们将一些重要的东西记录到日志文件中。

基本上只针对日志记录,我们正在创建可用数据的JSON,然后登录到日志文件。这是以JSON格式记录数据的业务要求。

现在,从可用数据创建JSON,然后记录到FILE会花费大量时间并影响原始请求返回时间。 现在的想法是改善引用。

我们讨论过的一件事是使用创建线程池

Executors.newSingleThreadExecutor() 

在我们的代码中,然后将任务提交给它,将数据转换为JSON和后续日志记录。

这是一个很好的方法吗?因为我们正在管理线程池本身,是否会产生一些问题?

如果有人可以分享更好的解决方案,我将不胜 在某种程度上使用Log4j。我试图使用AsyncAppender但没有达到任何预期的结果。 我们使用的是EJB 3,Jboss 5.0,Log4j,java6。

我相信你在使用单独的线程池进行日志记录方面处于正确的轨道上。 在许多产品中,您将看到异步日志记录function。 使用与请求线程不同的线程累积日志并将其推送到日志文件。 特别是在生产环境中,数百万的传入请求和响应时间需要少于几秒。 您无法负担任何诸如记录以减慢系统速度的任何事情。 因此,使用的方法是在内存缓冲区中添加日志,并以合理大小的块异步推送它们。

使用线程池进行日志记录时需要注意的事项由于多个线程将处理日志文件和内存日志缓冲区,因此需要注意日志记录。 您需要在FIFO类型的缓冲区中添加日志,以确保在按时间戳排序的日志文件中打印日志。 还要确保文件访问是同步的,并且您不会遇到日志文件全部颠倒或混乱的情况。

看看Logback ,AsyncAppender它已经提供了单独的线程池,队列等,并且很容易配置,它几乎与你正在做的一样,但是可以避免重新发明轮子。

是否考虑使用MongoDB进行日志记录 ?

  1. MongoDB插入可以异步完成 。 如果日志记录缓慢,停滞或停止,人们不希望用户的体验停止。 MongoDB提供了将插件发送到日志集合而不是等待响应代码的function。 (如果有人想要一个响应,一个人调用getLastError() – 我们会在这里跳过它。)
  2. 旧的日志数据自动LRU出来了。 通过使用上限集合,我们预先为日志分配空间,一旦它已满,日志将包装并重用指定的空间。 没有填充过多日志信息的磁盘的风险,也无需编写日志存档/删除脚本。
  3. 这个问题足够快。 首先,MongoDB一般来说非常快,对于像这样的问题来说足够快。 其次,使用上限集合时,会自动保留插入顺序:我们不需要在时间戳上创建索引。 这使事情变得更快,并且因为与读取相比,日志记录用例具有非常多的写入(与大多数数据库问题相反),因此这一点非常重要。
  4. 面向文档/ JSON是一种很好的日志信息格式 。 非常灵活和“无模式”,我们可以随时随地投入额外的字段。

还有log4j 2: http : //logging.apache.org/log4j/2.x/manual/async.html另外阅读这篇文章关于为什么这么快: http : //www.grobmeier.de/log4j- 2,性能贴近疯狂-20072013.html#.UzwywI9Bow4

您还可以使用disruptor模式尝试使用CoralLog异步记录数据。 这样你就可以在记录器线程中花费最少的时间,所有的辛苦工作都会传递给执行实际文件I / O的线程。 它还提供内存映射文件以加速使用者线程并减少队列争用。

免责声明:我是CoralLog的开发者之一