因此,我正在尝试学习log4j2,并把头放在记录器及其级别和父母传播上。
当前,我的源层次结构运行是:
├── main │ ├── java │ │ └── calculatorMain │ │ ├── Main.java │ │ ├── someClass2.java │ │ └── someClass1.java │ └── resources │ ├── Excels │ │ └── TestExcel.xlsx │ ├── FXMLs │ │ └── mainWindow.fxml │ └── log4j2.xml
而我的CalculatorMain是:
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>
问题是将输出到控制台的root记录程序设置为level="ERROR"。根据我对级别的理解,这意味着我的root记录器应仅输出错误日志或更低的错误日志。然后是我的CalculatorMain Calculator.Main记录器,前者应仅记录错误并降低记录,而后者应记录跟踪并降低记录。因此,我的理解是,错误日志及更低版本的日志将被打印两次,而高于错误日志的任何内容仅应基于父级传播被打印到日志一次。但是,基于我的日志文件输出以下内容的情况并非如此:
level="ERROR"
CalculatorMain
Calculator.Main
[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
以上这些日志应该只打印一次。我一直在关注这个经过深思熟虑的教程,但我想我一定是误会了。
您遇到的问题是true默认情况下的可加性。您的教程具有误导性,因为它说:
true
默认情况下,log4j2日志记录是累加的。这意味着当使用特定记录器时,还将使用所有父 记录 器。
其实它并 没有 意味着所有父 记录器 将被使用,这意味着所有的 附加目的地 父记录器将被使用。您应该阅读log4j2手册,尤其是有关可加性的部分。
在手册的可加性部分中,有一个带有一些解释的示例:
请注意,来自com.foo.Bar的跟踪消息出现了两次。这是因为首先使用与记录器com.foo.Bar关联的附加程序,该附加程序将第一个实例写入控制台。接下来,引用com.foo.Bar的父级(在本例中为root记录器)。然后将该事件传递到其 appender ,后者还将写入控制台,从而导致第二个实例。这称为可加性。
将可加性设置为true(默认情况下),子记录器接受的任何事件都会传递给所有父记录器的附加程序。