根据收到的参数动态选择log4j appender

时间:2017-07-05 17:15:27

标签: java log4j log4j2

我有log4j appenders(appendersB,appendersC)和下面的特定类

class A { A{Parent a}}

其中Parent是具有两个实现的接口,如下所示

class B implements Parent {..}
class C implements Parent {..}

现在我想告诉log4j,每当A类用paramater B实例化时,它应该使用appendersB,如果它接收C,那么它应该使用appendersC。

这可能吗?

1 个答案:

答案 0 :(得分:1)

appender的选择是在Log4j配置文件中根据记录器名称完成的,因此为了能够配置它以便将记录条目转到不同的appender,你的代码应该使用不同的记录器。

通常,记录器名称是完全限定的类名,记录器将创建为类的static字段。这样做是为了提高性能,减少内存占用和命名的便利性。

但是,您可以将记录器字段设为非static,并为其指定动态生成的名称。

例如,您的A课通常会这样做:

package org.example;
public class A {
    private static final Logger log = LogManager.getLogger(A.class);
    // rest of code
}

这将创建一个名为org.example.A的记录器,可以将其配置为编写任何选择的任何appender。

要将作为参数提供给构造函数的实际对象类的记录器,可能是appender,你可以这样做:

package org.example;
public class A {
    private final Logger log; // not static
    public A(Parent p) {
        this.log = LogManager.getLogger(getClass().getName() + "." +
                                        p.getClass().getSimpleName());
    }
}

这将为A的每个实例创建一个记录器,名称派生自构造函数参数,例如

new A(new B()) // Logger name: org.example.A.B
new A(new C()) // Logger name: org.example.A.C

您现在可以将Log4j配置为将记录器org.example.A.B定向到appenderB,将记录器org.example.A.C定向到appenderC

您当然可以按照自己的方式构建动态记录器名称。记录器名称不必基于类名,例如您可以将其命名为bravo.foocharlie.foo