Solve the problem that the log4j2 debugging log of springboot 2. X integration cannot be closed

Time:2021-11-26

When log4j2 is integrated with springboot2. X, the log output of log4j2 itself cannot be turned off

The following configurations have been made:

In the configuration file of log4j2.xml, the status attribute of configuration is off;

Confirm that log4j2.debug is not configured in all parts of the system;

The above configuration can not solve the problem, so we can only start from the source code.

From the log4j2 API package, find the statuslogger. The code for setting the log output level is as follows:


private StatusLogger(final String name,final MessageFactory messageFactory) {
        super(name, messageFactory);
        final String dateFormat = PROPS.getStringProperty(STATUS_DATE_FORMAT, Strings.EMPTY);
        final boolean showDateTime = !Strings.isEmpty(dateFormat);
        this.logger =new SimpleLogger("StatusLogger", Level.ERROR,false,true, showDateTime,false,
                dateFormat, messageFactory, PROPS, System.err);
        this.listenersLevel = Level.toLevel(DEFAULT_STATUS_LEVEL, Level.WARN).intLevel();
 
        // LOG4J2-1813 if system property "log4j2.debug" is defined, print all status logging
        if (isDebugPropertyEnabled()) {
            logger.setLevel(Level.TRACE);
        }
    }

As can be seen from the above code, the level is set to error by default. The trace log will be output only when log4j2.debug is set.

Where is the log4j2.debug property set? With this problem, we found the systempropertiespropertysource. This class does custom processing before loading properties into the environment:


private static final String PREFIX ="log4j2.";
 
@Override
public CharSequence getNormalForm(final Iterable<?extends CharSequence> tokens) {
    return PREFIX + Util.joinAsCamelCase(tokens);
}

As shown in the above code, this operation will interpret all system attributes, and then prefix log4j2. According to the parsed token. This leads to the problem that the log system thinks it needs to debug and then output the trace log.

Where did the debug on the system properties come from?

First of all, the local process is started in run mode, and the environment variable does not set the debug parameter by itself. Why is there “- ddebug” in the JVM startup parameter?

View the configurations configuration of the running process as follows:

Springboot has a custom configuration. By default, enable debug output is checked. Remove this and run it again. It is found that – ddebug is gone and the log is normal.

But even so, is log4j2 a little retarded? It’s easy to confuse the method of splicing system variables

Spring boot integration log4j2 encountered a pit

When spring boot is used in the project, log4j2 needs to be used as the logging framework

problem

Error during project startup: could not initialize log4j2 logging from classpath: log4j2-dev.yml

It is a problem that log4j2 configuration cannot be initialized. The YML configuration file used in the project.

Pre operation

First, introduce dependencies:


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>

Remove the default logback configuration:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions><!--  Remove the default configuration -- >
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

Add profile:

1040577-20180626113432305-938644465.png

Configuring logging.config

1040577-20180626113453767-2008327927.png

The above is the necessary configuration for the integration operation. An error is reported when the configuration is completed.

Troubleshooting

According to the description of the exception information, find the initialization code in the source code: log4j2loggingsystem.loadconfiguration

1040577-20180626113603596-370754945.png

Follow up:

1040577-20180626113633878-1356429116.png

Discovery is an abstract method. In idea, use Ctrl + Alt + B to find the implementation class:

1040577-20180626113653590-402312615.png

Because YML is used, the implementation class should be yamlconfig. Find the specific implementation:

1040577-20180626113734764-411601003.png

It is found that isactive is false through debug, so null is returned. Find the meaning of isactive in this class:

1040577-20180626113809127-180360783.png

This is the key logic. I went back to check whether there are the above dependent classes. After debugging, I found that there is no yamlfactory class. It can be seen that this class is in Jackson package, which seems to rely less on packages.

solve

Introduce Jackson dataformat yaml dependency:


    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-yaml</artifactId>
    </dependency>

The startup is normal and the problem is solved.

The above is my personal experience. I hope I can give you a reference, and I hope you can support developpaer.