如何将log4j与多个类一起使用?

2022-09-01 22:57:18

我目前正在用java编写一个大项目,有许多类,有些类很安静,只是用很少的方法表示对象。我在主类中设置了一个记录器,它工作正常。我希望能够对所有类仅使用一个记录器(带有一个控制台追加器)。我试图将对记录器的引用传递给不同的类,但它看起来不对。此外,有时我在类上运行测试而不运行main,因此记录器没有为其他类初始化。

实现此目的的最佳方法是什么,我的意思是,如何将不同类记录到一个日志,类之间没有硬依赖关系,并且能够对每个类独立使用日志?


答案 1

如果我理解正确,你现在拥有的是:

public class Main {
    public static final Logger LOGGER = Logger.getLogger(Main.class);
}

public class AnotherClass {
    public void doSomething() {
        Main.LOGGER.debug("value=" + value);
    }
}

或者,将对记录器的引用传递到类的构造函数中。

首先,您可以通过简单地使用传递给 Logger.getLogger 的相同值来使用一个全局记录器,例如:

public class Main {
    private static final Logger LOGGER = Logger.getLogger("GLOBAL");
}

public class AnotherClass {
    private final Logger LOGGER = Logger.getLogger("GLOBAL");

    public void doSomething() {
        LOGGER.debug("value=" + value);
    }
}

这使用完全相同的记录器,Logger.getLogger在两个调用中返回相同的对象。类之间不再有依赖关系,这将起作用。

我从您的评论中收集到的另一件事是,您正在手动配置(使用.大多数情况下,这不是必需的,您应该通过简单地将log4j.properties或log4j.xml添加到类路径来进行配置。在Eclipse中,这是通过将其添加到src/(如果您使用的是maven,则为src/main/resources)来完成的。如果您使用的是 junit,请将其添加到 test/source 目录(或带有 maven 的 src/test/resources)。这是配置log4j的一种更好的长期方法,因为您不必在类之间传递信息。BasicConfigurator.configure

此外,使用记录器的推荐方法是将类传递给 Logger.getLogger()。通过这种方式,您可以根据类名过滤输出,这通常比只有一个全局记录器更有用:

public class Main {
    private static final Logger LOGGER = Logger.getLogger(Main.class);
    public static final main(String[] args) {
        LOGGER.debug("started");
    }
}

public class AnotherClass {
    private final Logger LOGGER = Logger.getLogger(this.getClass());

    public void doSomething() {
        LOGGER.debug("value=" + value);
    }
}

然后在 log4j.properties 中,可以将单个追加器配置到一个文件。

# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

最后,不必将所有记录器声明为静态。这只有在您进行大量[*]对象创建时才会产生明显的差异。通过将记录器声明为非静态字段,您可以使用这种情况,在这种情况下,将记录器添加到类中将变为剪切和粘贴单行。这个slf4j页面包含了对利弊的良好解释。因此,除非您有充分的理由不这样做,否则请使用非静态字段。Logger.getLogger(this.getClass());

当Cameron说你应该尝试使用slf4j如果可能的话时,他是对的,它有一个杀手级的功能,你可以使用它的多个日志记录框架。

[*]我的意思是很多。


答案 2

您的记录器实例通常应为私有静态最终实例。通过这样做,每个类都将拥有自己的记录器实例(在加载类后创建),以便您可以标识创建日志记录的类,并且不再需要跨类传递记录器实例。


推荐