如何根据Log4J中的派生类配置基类中的日志记录?

时间:2017-03-09 16:48:45

标签: java log4j

我在库中有一个基类,它有大量的调试级日志语句。该库用于不同的应用程序,基类是子类。我希望能够根据使用它的特定派生类来配置基类的日志记录级别。什么是实现这个目标的有用成语?

例如,以下是起点:

class Base {
    static Logger logger = Logger.getLogger(Base.class);
    protected final void foo() {
        logger.debug("foo");
    }
}

class DerivedA extends Base {
    public void boo() {
        foo();
    }
}

class DerivedB extends Base {
    public void boo() {
        foo();
    }
}

鉴于上述情况,我无法启用DerivedA的日志记录,但无法启用DerivedB的日志记录。

相反,我必须做以下事情:

abstract class Base {

    abstract protected Class getDerivedType();
    protected final void foo() {
        Logger logger = Logger.getLogger(getDerivedType());        
        logger.debug("foo");
    }
}

class DerivedA extends Base {
    public void boo() {
        foo();
    }
    @Override protected Class getDerivedType() {
        return DerivedA.class;
    }
}

class DerivedB extends Base {
    public void boo() {
        foo();
    }
    @Override protected Class getDerivedType() {
        return DerivedB.class;
    }    
}

...鉴于上述情况,我可以在log4j.properties文件中使用不同的日志级别,具体取决于派生类:

log4j.logger.a.DerivedA=debug
log4j.logger.a.DerivedB=info

虽然上面的 工作,但我不喜欢我的logger对象不再是静态的事实,必须在每个方法中重新定义。另外,我必须为派生类定义一个抽象方法以提供它们的具体类型,而不是为了能够自定义日志记录而感觉不自然。

以上是惯用的,如果没有,会有什么更好的方法来达到同样的效果?

通常,有没有办法根据上下文配置日志记录? (在这种情况下,上下文是派生类,但也可以是调用堆栈,即调用发生日志记录的特定方法的方法)。或者这种级别的日志记录可配置性是否真的不受支持,甚至是一个坏主意?

1 个答案:

答案 0 :(得分:3)

使用非静态记录器的一种可能解决方案:

public class Base {
    protected Logger logger = Logger.getLogger(Base.class);

    protected final void foo() {
        logger.debug("foo");
    }
}

class DerivedA extends Base {
    {
        logger = Logger.getLogger(DerivedA.class);
    }

    public void boo() { foo(); }
}

class DerivedB extends Base {
    {
        logger = Logger.getLogger(DerivedB.class);
    }
    public void boo() { foo(); }
}

即使logger不是静态的,这个结构也不像原始结构那么复杂。

替代解决方案:子类必须实现getLogger()抽象方法(它们可以简单地返回静态记录器),该方法在基类中用于记录。记录器可以是静态的。

public abstract class Base {
    protected abstract Logger getLogger();

    protected final void foo() {
        getLogger().debug("foo");
    }
}

class DerivedA extends Base {
    private static final Logger logger = Logger.getLogger(DerivedA.class);

    public void boo() { foo(); }

    protected Logger getLogger() { return logger; }
}

class DerivedB extends Base {
    private static Logger logger =  Logger.getLogger(DerivedB.class);

    public void boo() { foo();}

    protected Logger getLogger() { return logger; }
}

这两种方法都适用于您当前的属性文件。

相关问题