我找到了许多帮助我构建记录器的链接。一些在 SO 中,另一些在其他页面中。
这里的答案:https://stackoverflow.com/questions/7624895/how-to-use-log4j-with-multiple-classes#=是我发现的最好的。 这已经是多年以前的想法了,现在有些事情已经不同了。
我的目标是让所有将消息打印到日志(包括控制台和文件)的 java 类共享一个记录器。
我正在使用 LOG4J2:http://logging.apache.org/log4j/2.x/manual/configuration.html
main():
import org.apache.logging.log4j.Logger;
public class App {
private static final Logger LOGGER = Logger.getLogger("GLOBAL");
public static void main(){
...calling other classes
}
}
任何其他类:
import org.apache.logging.log4j.Logger;
public class secondClass {
private final Logger LOGGER = Logger.getLogger("GLOBAL");
public void writeLog(){
LOGGER.log(Level.INFO, "A simple string");
}
}
log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">/var/log</Property>
</Properties>
<Appenders>
<RollingFile name="fileLogger" fileName="${basePath}/myApp.log" filePattern="${basePath}/myApp-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="java.util.logging.Logger" level="ALL" additivity="true">
<appender-ref ref="fileLogger" level="ALL" />
</Logger>
<Root level="ALL" additivity="false">
<appender-ref ref="console" />
</Root>
</Loggers>
</Configuration>
我(或多或少)知道我应该使用 LogManager,事实上我应该这样调用它:
private static final Logger logger = LogManager.getLogger(MyApp.class);
或者,在 main() 中,可能像这样:
private static Logger LOGGER = null;
@BeforeClass
public static void setLogger() {
System.setProperty("log4j.configurationFile","log4j.xml");
LOGGER = LogManager.getLogger();
}
因为,我相信,使用 LogManager 我可以将日志指向 xml 文件以进行设置。
但是当我构建并运行它时,CLI 愤怒地在第一个日志中退出,报告:Exception in thread "main" java.lang.NullPointerException at myapp.modules.Database.<init>(Database.java:67)
预期结果: 我想要做的就是能够拥有我所有类(class)的日志,并将其写入文件。 我就是无法正常工作。当我不使用 LogManager 时,我只会在控制台上看到日志,但不会创建任何文件。 我同时使用 Windows 和 Linux(这就是/var/log/但我也将其更改为 C:\的原因)。
我用过的其他网站: https://howtodoinjava.com/log4j2/configure-log4j2-for-junit/
Log4J loggers for different classes <-- 没有帮助我
..许多其他搜索结果都超过 6 年了。
POM.xml:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
最佳答案
您在几个层面上都错了:您将 JDK 的记录器与 Log4j2 的记录器混合在一起,您没有记录到多个附加程序,等等。
这是你应该做的:
/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>log4j2test</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
</dependencies>
</project>
这基本上是唯一没有错误的地方。
/src/main/java/so47656300/App.java
package so47656300;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class App {
private static final Logger logger = LogManager.getLogger(App.class);
public static void main(String[] args) {
logger.info("App.main - starting");
new SecondClass();
logger.info("App.main - ending");
}
}
在这里,您的错误是使用 java.util.logger.Logger
而不是 org.apache.logging.log4j.Logger
。
/src/main/java/so47656300/SecondClass.java
package so47656300;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class SecondClass {
private static final Logger logger = LogManager.getLogger(SecondClass.class);
public SecondClass() {
logger.info("SecondClass - starting");
logger.info("SecondClass - ending");
}
}
在这里,您的错误还在于使用了错误的 Logger
类。仅使用来自 org.apache.logging.log4j.*
的类。
/src/main/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="basePath">/var/log</Property>
</Properties>
<Appenders>
<RollingFile name="fileLogger" fileName="${basePath}/myApp.log" filePattern="${basePath}/myApp-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="console"/>
<AppenderRef ref="fileLogger"/>
</Root>
</Loggers>
</Configuration>
在这里,您的错误如下:
- 错误的文件名:Log4J 2 requires a name
log4j2.xml
.对于您的测试,创建一个文件/src/test/resources/log4j2-test.xml
。 - 您只需要一个记录器,所以只使用一个:根记录器。您创建了多个,但您不需要它们。
- 将 appender 添加到记录器(Root-one)
输出
控制台
[INFO ] 2017-12-05 16:52:32.218 [main] App - App.main - starting
[INFO ] 2017-12-05 16:52:32.221 [main] SecondClass - SecondClass - starting
[INFO ] 2017-12-05 16:52:32.222 [main] SecondClass - SecondClass - ending
[INFO ] 2017-12-05 16:52:32.222 [main] App - App.main - ending
/var/log/myApp.log
[INFO ] 2017-12-05 16:52:32.218 [main] App - App.main - starting
[INFO ] 2017-12-05 16:52:32.221 [main] SecondClass - SecondClass - starting
[INFO ] 2017-12-05 16:52:32.222 [main] SecondClass - SecondClass - ending
[INFO ] 2017-12-05 16:52:32.222 [main] App - App.main - ending
关于java - 将 log4j2 用于多个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47656300/