Java log4j2 logger levels aren't being followed

99封情书 提交于 2019-12-20 07:32:19

问题


So I'm trying to learn log4j2 and wrap my head around the loggers and their levels and parental propagation.

Currently my source hierarchy runs is:

├── main
│   ├── java
│   │   └── calculatorMain
│   │       ├── Main.java
│   │       ├── someClass2.java
│   │       └── someClass1.java
│   └── resources
│       ├── Excels
│       │   └── TestExcel.xlsx
│       ├── FXMLs
│       │   └── mainWindow.fxml
│       └── log4j2.xml

and my calculatorMain is:

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);
        }
    }
}

My log4j2.xml is

<?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>

The problem is that the root logger which outputs to the console is set to level="ERROR". From my understanding of levels that means my root logger should only output error logs or lower. Then there's my CalculatorMain Calculator.Main loggers, the former should only log errors and lower whereas the latter should log traces and lower. So my understanding is that error logs and lower will be printed twice and anything above error logs should only get printed to the log once based on parent propagation. However that is not the case based with my log file outputting the following:

[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

These above logs should've only printed once. I've been following this well thought out tutorial but I guess I must be misunderstanding.


回答1:


The issue you're having is due to additivity being true by default. Your tutorial is misleading in that it says:

By default log4j2 logging is additive. It means that all the parent loggers will also be used when a specific logger is used.

In fact it does not mean that all parent loggers will be used, it means all of the appenders of parent loggers will be used. You should read the log4j2 manual, particularly the section on additivity.

In the additivity section of the manual, there is an example with some explanation after it:

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.

With additivity set to true (as it is by default) any event accepted by a child logger is passed to the appenders of all parent loggers.



来源:https://stackoverflow.com/questions/51898831/java-log4j2-logger-levels-arent-being-followed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!