Springboot integrates log4j2 processes

1. Add dependencies

<! > <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <! --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <! --log4j dependency --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <! - < version > 2.1.7. RELEASE < / version > -- > < / dependency >Copy the code

1.1 Precautions for Adding dependencies

To exclude logback dependencies in spring-boot-starter, if you exclude logback dependencies only in spring-boot-starter-web, the following error will be reported:Copy the code
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/develop/repository_leannews/ch/qos/logback/logback-classic/1.23./logback-classic-1.23..jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/develop/repository_leannews/org/apache/logging/log4j/log4j-slf4j-impl/2.133./log4j-slf4j-impl-2.133..jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

Caused by: java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:17 - no applicable action for [Properties], current ElementPath  is [[Configuration][Properties]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@6:55 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@8:57 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:50 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@12:61 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@14:63 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@16:55 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@18:47 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@20:84 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@22:57 - no applicable action for [Property], current ElementPath  is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@25:16 - no applicable action for [Appenders], current ElementPath  is [[Configuration][Appenders]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@27:52 - no applicable action for [Console], current ElementPath  is [[Configuration][Appenders][Console]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@29:54 - no applicable action for [PatternLayout], current ElementPath  is [[Configuration][Appenders][Console][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@31:92 - no applicable action for [ThresholdFilter], current ElementPath  is [[Configuration][Appenders][Console][ThresholdFilter]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:115 - no applicable action for [RollingRandomAccessFile], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@38:22 - no applicable action for [Filters], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Filters]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@40:98 - no applicable action for [ThresholdFilter], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Filters][ThresholdFilter]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@42:96 - no applicable action for [ThresholdFilter], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Filters][ThresholdFilter]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@44:54 - no applicable action for [PatternLayout], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@45:23 - no applicable action for [Policies], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Policies]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@47:79 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Policies] [TimeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@48:68 - no applicable action for [SizeBasedTriggeringPolicy], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Policies][SizeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@51:57 - no applicable action for [DefaultRolloverStrategy], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][DefaultRolloverStrategy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@57:116 - no applicable action for [RollingRandomAccessFile], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@58:22 - no applicable action for [Filters], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Filters]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@59:97 - no applicable action for [ThresholdFilter], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Filters][ThresholdFilter]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@61:54 - no applicable action for [PatternLayout], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@62:23 - no applicable action for [Policies], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Policies]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@63:79 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Policies][TimeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@64:68 - no applicable action for [SizeBasedTriggeringPolicy], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][Policies][SizeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@66:57 - no applicable action for [DefaultRolloverStrategy], current ElementPath  is [[Configuration][Appenders][RollingRandomAccessFile][DefaultRolloverStrategy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@71:14 - no applicable action for [Loggers], current ElementPath  is [[Configuration][Loggers]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@73:41 - no applicable action for [Root], current ElementPath  is [[Configuration][Loggers][Root]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@74:40 - no applicable action for [AppenderRef], current ElementPath  is [[Configuration][Loggers][Root][AppenderRef]]
	at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169)
	at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:66)
	at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:57)
	at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:310)...14 more
Copy the code

2. Write a log4j2 configuration file

Create log4j2.xml in the resource directory. If the file name is different, for example, log4j2-spring. XML, you need to import the corresponding file in application.yml

<? xml version="1.0" encoding="UTF-8"? > <! -- Log level trace: it's tracing, that is, if you go through the program, you can write a trace output, so it should be a lot of trace output, but that's ok, we can set the lowest log level to stop it. -Dan: I'm just using this as the lowest level. Trace is not used at all. If there is no way out, use Eclipse or IDEA debug function. Info: Output information that you are interested in or important to you. Warn: Some of the messages are not error messages, but there are also warnings for programmers, similar to the ones in Eclipse where code validation does not have error and WARN (not errors but also note, as in the following method depressed). Error: indicates an error message. They use it a lot. You're fatal. Major error, this level you can directly stop the program, is not supposed to appear error?! Don't be so nervous, in fact, it is a matter of degree. --><Configuration status="OFF">
    <! -- Define log directory -->
    <Properties>
        <Property name="logPath">logs</Property>
        <! -- Output log format -->
        <! -- %d{YYYY-MM-DD HH: MM: SS, SSS} : log production time %p: log output format %C: logger name %m: log content, that is, logger.info("message") %n: newline %c: Java class name %L: number of the log output line %M: name of the log output method hostName: name of the local machine hostAddress: local IP address -->
        <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} %L %M - %msg%xEx%n</Property>
    </Properties>
    <! Define all appenders first -->
    <Appenders>
        <! -- Output to console -->
        <Console name="ConsoleLog" target="SYSTEM_OUT">
            <! -- Only output messages of level or higher (onMatch), reject others (onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
            <! -- Output log format, using custom template PATTERN -->
            <PatternLayout pattern="${PATTERN}" />

        </Console>
        <! -- Output to file -->
        <! -- The file will print out all the information. This log will be automatically cleared every time the program runs, as determined by the append property.
        <! False: the message overwrites the content of the specified file. The default value is TRUE -->
        <! Each time the size of the log exceeds size, the size of the log will be automatically saved in the folder created by year - month and compressed, as an archive -->
        <RollingFile name="RollingFileLog" fileName="${logPath}/kingbag.log" append="true" filePattern="${logPath}/$${date:yyyy-MM}/kingbag-%d{MM-dd-yyyy}-%i.log.gz">
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="${PATTERN}" />
            <SizeBasedTriggeringPolicy size="10MB" />
        </RollingFile>
        <RollingFile name="RollingFileLog" fileName="${logPath}/behavior_kingbag.log" append="true" filePattern="${logPath}/$${date:yyyy-MM}/kingbag-%d{MM-dd-yyyy}-%i.log.gz">
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="${PATTERN}" />
            <SizeBasedTriggeringPolicy size="10MB" />
        </RollingFile>

        <! Error levels are not recorded in files -->
        <! --<File name="ErrorFileLog" fileName="${logPath}/kits-error.log">-->
        <! --<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" />-->
        <! --<PatternLayout pattern="${PATTERN}" />-->
        <! --</File>-->

    </Appenders>
    <! An appender will not work until logger is defined and appender is appended.
    <Loggers>
        <! Create a default Root logger that logs logs greater than level and higher than WARN. If the level in Appenders is higher than that in Appenders, it will start at that level. For example, level="fatal", Appenders only displays fatal information.
        <! -- Production environment level>= WARN -->
        <Root level="debug">
            <! -- Output, can choose any combination of items defined above, or all, can be customized at will -->
            <appender-ref ref="ConsoleLog" />
            <appender-ref ref="RollingFileLog" />
        </Root>
        <! -- Third-party log system -->
        <! - to filter out spring and mybatis useless DEBUG information, can also be in the spring the boot logging.level.org.springframework=FATAL Settings - >
        <! -- <logger name="org.springframework" level="INFO"></logger> -->
        <! -- <logger name="org.mybatis" level="INFO"></logger> -->
        <! -- <logger name="org.apache.http" level="warn" /> -->
    </Loggers>
</Configuration>
Copy the code

3. Import the configuration file in application.yml

logging:
  config: classpath:log4j2-spring.xml
Copy the code

4. Demo code

Try not to use @log4j2 and supplement it with @slf4J annotations : SLF4J is a log surface, it is not a real log framework,log output implementation still depends on the specific log4j, Logback and other frameworks, the advantage of using @SLf4J is that if the late replacement of the log framework only need to replace jar packages and configuration files, the code is less invasive

package com.yongforever.contorller;

import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class HelloWorldController {

    @GetMapping("/hello")
    public String hello(){
        log.info("yong-forever");
        return "yong-forever"; }}Copy the code

Console printing:

2021-04-14 09:45:44.552 [http-nio-9001-exec-5-14] INFO  com.yongforever.contorller.HelloWorldController 14 hello - yong-forever
Copy the code