异步日志记录

时间:2013-06-10 07:01:04

标签: java performance asynchronous log4j jboss5.x

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

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

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

我们讨论过的一件事是使用

创建一个线程池
Executors.newSingleThreadExecutor() 

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

执行此操作是一种好方法吗?由于我们正在管理线程池本身,是否会产生一些问题?

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

5 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:5)

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

答案 2 :(得分:3)

是否正在考虑使用MongoDB for logging

  1. MongoDB插入可以异步完成。如果日志缓慢,停滞不前,人们不希望用户的体验停滞不前 或者。 MongoDB提供了这种能力     触发插入到日志集合中而不是等待响应代码。 (如果一个     想要一个响应,一个调用getLastError() - 我们会在这里跳过它。)
  2. 旧日志数据自动LRU输出。通过使用上限集合, 我们预先为日志分配空间,一旦它满了,日志就会换行 并重用指定的空间。没有填满磁盘的风险 过多的日志信息,无需写日志存档/ 删除脚本。
  3. 这个问题足够快。首先,MongoDB非常快 一般来说,足够快这样的问题。第二,使用时 上限集合,插入顺序自动保留:我们 不需要在时间戳上创建索引。这使事情变得平坦 更快,并且鉴于日志记录用例非常重要,这一点非常重要 与读取相比,写入次数较多(与大多数数据库相反) 问题)。
  4. 面向文档/ JSON是一种很好的日志信息格式。非常灵活和“无模式”在某种意义上我们可以额外投入 我们想要的任何时候。

答案 3 :(得分:1)

答案 4 :(得分:0)

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

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