log4j2 asyncLogger不支持Custom Disruptor Queue Full Policy

时间:2017-11-02 16:32:42

标签: java logging log4j log4j2

log4j2版本:2.9.1

当Disruptor队列已满时,log4j2调用Appenders In CurrentThread By Default,这可能导致在checkrollover或write-file方法中阻塞许多线程。要解决此问题,我尝试自定义log4j2 AsyncQueueFullPolicy,例如:如果CurrentThread数字大于100,则丢弃日志

但唯一的方法 org.apache.logging.log4j.core.async.AsyncQueueFullPolicy.getRoute(long, Level)返回Enum类型EventRoute,仅支持ENQUEUE | SYNCHRONOUS | DISCARD。在Java中,不支持枚举类型。

如何定制AsyncQueueFullPolicy,请举个例子。谢谢!

1 个答案:

答案 0 :(得分:0)

可以指定自定义AsyncQueueFullPolicy。您的类需要实现AsyncQueueFullPolicy接口,并通过启动应用程序并将系统属性log4j2.AsyncQueueFullPolicy设置为AsyncQueueFullPolicy实现类的完全限定类名来install

当队列已满时,您的实现类将被称为,用于每个事件,以决定如何处理该事件。如果队列未满,则 not 将调用您的实现类。对于每个事件,您的实现类需要决定是否

  • DISCARD此事件(不会记录)
  • ENQUEUE此事件(这将阻止,直到队列中的空间可用)
  • SYNCHRONOUS:绕过队列并将此事件直接记录到底层appender。 如果您执行此操作,事件将在日志文件中无序显示!

这些是策略可用的唯一选项。如果您想提出其他选项,请在Log4j2 issue tracker上提出一张票。

也许我误解了你的问题,但是当线程ID大于100时丢弃事件的自定义策略可能如下所示:

public class CustomQueueFullPolicy extends DefaultAsyncQueueFullPolicy {
    public CustomQueueFullPolicy() {
    }

    @Override
    public EventRoute getRoute(final long backgroundThreadId, final Level level) {
        if (backgroundThreadId > 100) {
            return EventRoute.DISCARD;
        }
        return super.getRoute(backgroundThreadId, level);
    }
}

(请注意,Log4j2的DefaultAsyncQueueFullPolicy的实现将随即将发布的Log4j 2.10版本而变化。有关详细信息,请参阅LOG4J2-2031。)

另请参阅DiscardingAsyncQueueFullPolicy以获取在队列已满时丢弃级别低于特定阈值的日志事件的策略示例。