关于logback的AsyncAppender

时间:2018-01-02 07:11:08

标签: java logging logback slf4j

当我在logback中检查AsyncAppender的文档时,我没有找到支持AsyncAppender的线程池设置。

这是否意味着只有一个线程可以使用阻塞队列中的日志事件? (虽然日志事件可以由多个线程产生,比如20-40)

由于

莱昂

2 个答案:

答案 0 :(得分:1)

来自the docs

  

AsyncAppender缓冲BlockingQueue中的事件。 AsyncAppender创建的工作线程从队列头部获取事件,并将它们分派到连接到AsyncAppender的单个appender。

看着代码; AsyncAppenderBase启动Thread的单个实例,以便从appender的blockingQueue中获取事件。

所以,是的,只有一个工作线程,这个线程负责消耗可能由多个应用程序线程发出的日志事件。

如果您担心此工作线程可能无法像生成这些事件那样快速处理这些事件,那么您可以调整以下属性:

  • queueSize:阻塞队列的最大容量。默认情况下,queueSize设置为256.
  • discardingThreshold:默认情况下,当阻塞队列剩余20%的容量时,它将丢弃级别为TRACE,DEBUG和INFO的事件,仅保留级别为WARN和ERROR的事件。要保留所有事件,请将discardingThreshold设置为0。

您可以增加queueSize以确保不会丢失任何事件(尽管以资源使用为代价,因为保留的事件将在应用程序的堆上发送,直到它们被分派到底层的appender)。或者,您可以通过设置discardingThreshold

来提高性能 - 以丢失优先级较低的事件为代价

答案 1 :(得分:0)

我还没有检查过源代码,但我很确定是的,池中只有一个线程。原因是多线程处理这个过程没什么意义,因为任务的性质是单线程的。考虑一下你是否正在写一个文件:不可能同时将两条消息附加到一个文件中。

也许您期望在线程外调用字符串格式和toString方法...我希望它们不会,因为日志消息的参数很可能在调用后不久被修改。同步性主要是为了防止I / O阻塞(例如磁盘延迟)影响性能关键代码。