本文介绍了不遵循Java log4j2记录器级别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在尝试学习log4j2,并把我的头缠在记录器及其水平和父母的传播上.

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

我的计算器主要是:

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是

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>

问题在于,输出到控制台的根记录程序设置为level="ERROR".根据我对级别的理解,这意味着我的root记录器应仅输出错误日志或更低的错误日志.然后是我的CalculatorMain Calculator.Main记录器,前者应仅记录错误并降低错误,而后者应记录跟踪并降低错误.因此,我的理解是,错误日志及更低版本的日志将被打印两次,而高于错误日志的任何内容仅应基于父级传播被打印到日志一次.但是,基于我的日志文件输出以下内容的情况并非如此:

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.

推荐答案

您遇到的问题是由于可加性默认为true.您的教程具有误导性,因为它说:

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

实际上,它并不意味着将使用所有父级记录器,这意味着将使用父级记录器的所有 appenders .您应该阅读 log4j2手册,尤其是有关可加性的部分

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:

将可加性设置为true(默认情况下),子记录器接受的任何事件都将传递给所有父记录器的附加器.

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.

这篇关于不遵循Java log4j2记录器级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 19:41