Java 未遵循 log4j2 记录器级别
Java log4j2 logger levels aren't being followed
所以我正在尝试学习 log4j2 并全神贯注于记录器及其级别和 parental 传播。
目前我运行的源层次结构是:
├── main
│ ├── java
│ │ └── calculatorMain
│ │ ├── Main.java
│ │ ├── someClass2.java
│ │ └── someClass1.java
│ └── resources
│ ├── Excels
│ │ └── TestExcel.xlsx
│ ├── FXMLs
│ │ └── mainWindow.fxml
│ └── log4j2.xml
我的计算器主要是:
Public class Main extends Application
{
private static final String mainWindow = //FXML stuff
private static final Logger logger = LogManager.getLogger(Main.class.getName());
public static void main(String[] args)
{
logger.debug("Main has started");
launch(args);
}
@Override
public void start(Stage primaryStage)
{
try
{
//FXML stuff
Parent root = //fxml stuff
logger.info("Main scene loaded successfully");
if (root != null)
{
//FXML stuff
}
else
logger.error("Root was null");
}
catch (Exception e)
{
logger.error("Error",e);
}
}
}
我的log4j2.xml是
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="BrightnessCalculator packages">
<!-- Logging Properties -->
<Properties>
<Property name="basePath">./logs</Property>
<Property name="filePattern">${date:yyyy-MM-dd}</Property>
</Properties>
<Appenders>
<!-- File Appenders -->
<RollingFile name="mainLog" fileName="${basePath}/info-${filePattern}.log"
filePattern="${basePath}/app-info-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{36} - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
<!-- Console Appender -->
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="console"/>
</Root>
<Logger name="calculatorMain" level="ERROR">
<appenderRef ref="mainLog"/>
</Logger>
<Logger name="calculatorMain.Main" level="TRACE">
<appenderRef ref="mainLog"/>
</Logger>
</Loggers>
</Configuration>
问题是输出到控制台的根记录器设置为 level="ERROR"
。根据我对级别的理解,这意味着我的根记录器应该只输出错误日志或更低级别。然后是我的 CalculatorMain
Calculator.Main
记录器,前者应该只记录错误和更低,而后者应该记录痕迹和更低。所以我的理解是,错误日志和更低的日志将被打印两次,错误日志之上的任何内容都应该只根据 parent 传播被打印到日志中一次。但是,基于我的日志文件输出以下内容,情况并非如此:
[DEBUG] 2018-08-17 16:37:28.239 [main] calculatorMain.Main - Main has started
[DEBUG] 2018-08-17 16:37:28.239 [main] calculatorMain.Main - Main has started
[INFO ] 2018-08-17 16:37:28.741 [JavaFX Application Thread] calculatorMain.Main - Main scene loaded successfully
[INFO ] 2018-08-17 16:37:28.741 [JavaFX Application Thread] calculatorMain.Main - Main scene loaded successfully
以上这些日志应该只打印一次。我一直在关注 this 深思熟虑的教程,但我想我一定是误会了。
您遇到的问题是由于可加性默认为 true
。您的教程具有误导性,因为它说:
By default log4j2 logging is additive. It means that all the parent
loggers will also be used when a specific logger is used.
事实上它 not 意味着所有父 loggers 都将被使用,这意味着所有 appenders 个父记录器将被使用。您应该阅读 log4j2 manual,尤其是关于可加性的部分。
在手册的可加性部分,有一个例子,后面有一些解释:
Notice that the trace messages from com.foo.Bar appear twice. This is
because the appender associated with logger com.foo.Bar is first used,
which writes the first instance to the Console. Next, the parent of
com.foo.Bar, which in this case is the root logger, is referenced. The
event is then passed to its appender, which also writes to the
Console, resulting in the second instance. This is known as
additivity.
将可加性设置为 true
(默认情况下),子记录器接受的任何事件都会传递给所有父记录器的附加程序。
所以我正在尝试学习 log4j2 并全神贯注于记录器及其级别和 parental 传播。
目前我运行的源层次结构是:
├── main
│ ├── java
│ │ └── calculatorMain
│ │ ├── Main.java
│ │ ├── someClass2.java
│ │ └── someClass1.java
│ └── resources
│ ├── Excels
│ │ └── TestExcel.xlsx
│ ├── FXMLs
│ │ └── mainWindow.fxml
│ └── log4j2.xml
我的计算器主要是:
Public class Main extends Application
{
private static final String mainWindow = //FXML stuff
private static final Logger logger = LogManager.getLogger(Main.class.getName());
public static void main(String[] args)
{
logger.debug("Main has started");
launch(args);
}
@Override
public void start(Stage primaryStage)
{
try
{
//FXML stuff
Parent root = //fxml stuff
logger.info("Main scene loaded successfully");
if (root != null)
{
//FXML stuff
}
else
logger.error("Root was null");
}
catch (Exception e)
{
logger.error("Error",e);
}
}
}
我的log4j2.xml是
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="BrightnessCalculator packages">
<!-- Logging Properties -->
<Properties>
<Property name="basePath">./logs</Property>
<Property name="filePattern">${date:yyyy-MM-dd}</Property>
</Properties>
<Appenders>
<!-- File Appenders -->
<RollingFile name="mainLog" fileName="${basePath}/info-${filePattern}.log"
filePattern="${basePath}/app-info-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{36} - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
<!-- Console Appender -->
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="console"/>
</Root>
<Logger name="calculatorMain" level="ERROR">
<appenderRef ref="mainLog"/>
</Logger>
<Logger name="calculatorMain.Main" level="TRACE">
<appenderRef ref="mainLog"/>
</Logger>
</Loggers>
</Configuration>
问题是输出到控制台的根记录器设置为 level="ERROR"
。根据我对级别的理解,这意味着我的根记录器应该只输出错误日志或更低级别。然后是我的 CalculatorMain
Calculator.Main
记录器,前者应该只记录错误和更低,而后者应该记录痕迹和更低。所以我的理解是,错误日志和更低的日志将被打印两次,错误日志之上的任何内容都应该只根据 parent 传播被打印到日志中一次。但是,基于我的日志文件输出以下内容,情况并非如此:
[DEBUG] 2018-08-17 16:37:28.239 [main] calculatorMain.Main - Main has started
[DEBUG] 2018-08-17 16:37:28.239 [main] calculatorMain.Main - Main has started
[INFO ] 2018-08-17 16:37:28.741 [JavaFX Application Thread] calculatorMain.Main - Main scene loaded successfully
[INFO ] 2018-08-17 16:37:28.741 [JavaFX Application Thread] calculatorMain.Main - Main scene loaded successfully
以上这些日志应该只打印一次。我一直在关注 this 深思熟虑的教程,但我想我一定是误会了。
您遇到的问题是由于可加性默认为 true
。您的教程具有误导性,因为它说:
By default log4j2 logging is additive. It means that all the parent loggers will also be used when a specific logger is used.
事实上它 not 意味着所有父 loggers 都将被使用,这意味着所有 appenders 个父记录器将被使用。您应该阅读 log4j2 manual,尤其是关于可加性的部分。
在手册的可加性部分,有一个例子,后面有一些解释:
Notice that the trace messages from com.foo.Bar appear twice. This is because the appender associated with logger com.foo.Bar is first used, which writes the first instance to the Console. Next, the parent of com.foo.Bar, which in this case is the root logger, is referenced. The event is then passed to its appender, which also writes to the Console, resulting in the second instance. This is known as additivity.
将可加性设置为 true
(默认情况下),子记录器接受的任何事件都会传递给所有父记录器的附加程序。