springboot learning series: use log4j2 logging framework to dynamically create log files based on spring variables

Scenes

The old project was switched to a microservice framework , and in order to be compatible with the log framework of the old project, the log4j2 framework was used. After switching to the log4j2 framework, the log configuration is quite different from the original logback log configuration, and there is no way to read the environment variables and then convert the variables. This article is mainly aimed at solving this situation.

surroundings

software version
spring-boot 2.1.1.RELEASE

text

Original understanding

Let me show you the contents of the log4j2.xml file used in the project , as follows:

<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <property  name="springAppName" value="${spring:spring.application.name}" />
        <property  name="springAppPort" value="${spring:server.port}" />
        <property name="LOG_INFO_FILE" value="${BUILD_FOLDER:-logs}/${springAppName}-${springAppPort}.log" />
        <property name="CONSOLE_LOG_PATTERN" value="[%p] %d{yyyy-MM-dd HH:mm:ss S} - %m%n" />
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout
                    pattern="${CONSOLE_LOG_PATTERN}"/>
        </Console>
        <RollingRandomAccessFile name="infoLog" fileName="${LOG_INFO_FILE}"
                                 filePattern="${LOG_INFO_FILE}.%d{yyyy-MM-dd}.gz"
                                 append="true">
            <PatternLayout
                    pattern="${CONSOLE_LOG_PATTERN}"/>
            <Filters>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
            </Filters>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="30 MB"/>
            </Policies>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- root logger -->
        <Root level="info" includeLocation="true">
            <AppenderRef ref="infoLog"/>
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

The variables here are set using the property tag. The default label prefixes of log4j are as follows: For
Insert picture description here
specific details, please refer to the reference link below to view by yourself. Log4j provides us with more plug-ins, and it can also dynamically read data according to the configuration file. But our project here is a springcloud project, and the configuration information is stored in the configuration center. I hope that it can be dynamically read based on the configuration of the configuration center.

Source code display

Next, I will show you the source code used in the project:

@Plugin(name = "spring", category = StrLookup.CATEGORY)
public class SpringEnvrionmentLookup extends AbstractLookup
        implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    
    

    private static ConfigurableApplicationContext context;


    @Override
    public String lookup(final LogEvent event, final String key) {
    
    
        if (context != null) {
    
    
            return context.getEnvironment().getProperty(key);
        }
        return null;
    }


    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
    
    
        context = configurableApplicationContext;
    }
}

In addition, to use this, you need to create a new META-INF/spring.factories under the resource directory. The contents are as follows:

org.springframework.context.ApplicationContextInitializer=SpringEnvrionmentLookup

Configure the corresponding logging.config in the system configuration table corresponding to the configuration center as classpath:log4j2.xml , otherwise it may cause the default logback.xml file to be read , and the problem of log creation failure may occur.

result

After the project is started, you can see the error report in the console. However, because the spring environment variable in the plug-in is not injected, the obtained value is empty, and an error is reported. However, it can run normally after waiting for the configuration data to be obtained from the configuration center. If you directly view the generated log, there will be no such errors. The beginning of the log is as follows:
Insert picture description here

to sum up

I checked a lot of documents on the Internet, and what I wrote was more or less problematic, so I wrote this blog myself, hoping to give you an effective solution! ! !

Reference link

lookups official document
configuration official document

Ask for praise

If my article is helpful to everyone, you can click like or favorite at the bottom of the article;
if there is a good discussion, you can leave a message;
if you want to continue to view my future articles, you can click Follow
You can scan the following QR code to follow me 'S public account: Fengye Zhixuege, check out my latest share!
Insert picture description here
Bye bye

Guess you like

Origin blog.csdn.net/u013084266/article/details/108818441