Meet is fate, pass by a praise

Source: https://github.com/yulc-coding/java-note/tree/master/log4j2

Related articles: Simple use of Spring Boot Logback logs

The function point

  • Different log files are generated at different levels.
  • Set the size of a single log file.
  • Generate log files by date;
  • Generate custom category log files;
  • Set the log output level of the specified package or class.
  • Asynchronous logging (LMAXDisruptor required)

start

  • The Log4j2 configuration is similar to Logback
  • Spring Boot uses Logback as the logging framework by default, so remove the reference to Logback from the POM
  • If asynchronous logging is required, LMAXDisruptor needs to be introduced in the POM
  • Create a new XML file log4j2.xml under SRC /main/resources

PMX file

<! - the use oflog<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <! - the use oflog<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <! Lmax </groupId> <artifactId> Disruptor </artifactId> <version>3.4.2</version> </dependency>Copy the code

The basic structure

<! - the status sayslog4j2 Level of its own logs monitorInterval: Automatically detects the time when the Configuration file is modified or reconfigured, in seconds --> <Configuration Status ="INFO" monitorInterval="60"> <! -- Variable configuration, pass${name}Reference --> <Properties> <property name="" value=""/> </Properties> <! Configure log output format --> <Appenders> <! -- Console prints --> <Console name="" target="SYSTEM_OUT"> <! -- Format output --> <PatternLayout pattern=""/> </Console> <! -- Output the log to a file with append astrue, appends logs to the log file, isfalse--> <File name="" fileName="" append="true"> <! -- Log level filtering --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern=""/> </File> <! <RollingFile name= --> <RollingFile name="" fileName="" filePattern="">
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <! -- interval specifies how many times to scroll. The default value is 1, and filePattern generates archived logs by day if filePattern is YYYY-MM-DD. Is generated by minutes archive logs - > < TimeBasedTriggeringPolicy interval ="1"/ > <! - the size of a single file -- > < SizeBasedTriggeringPolicy size ="5M"/> </Policies> <! -- DefaultRolloverStrategy if not set, default to start overwriting a maximum of 7 files in the same folder --> <DefaultRolloverStrategy fileIndex="max" max="15"/> </RollingFile> </Appenders> <! -- Configure logs to output --> <Loggers> <! -- Custom output --> < Logger name="" level="" additivity="">
            <AppenderRef ref=""/> </logger> <! -- AsyncRoot -- asynchronous logging -- requires LMAXDisruptor support --> <AsyncLogger name="" level="" additivity="">
            <AppenderRef ref=""/> </AsyncLogger> <! -- Specify the Root log of the project --> <Root level="info">
            <AppenderRef ref=""/>
            <AppenderRef ref=""/>
        </Root>
    </Loggers>

</Configuration>
Copy the code
Properties Custom variable
<Properties> <! -- Formatted output: %d for date; %X Prints custom data, set with org.sl4j.MDC, ex: mdc.put ("user"."aaa"); %thread indicates the name of the thread. %-5level: level 5 characters wide from the left; %logger{50} indicates that the maximum length of logger name is 50 characters. Otherwise, split % MSG: log message by period. %n is a newline character --> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{user}]-[%X{args}] [%thread] %-5level %logger{50} - %msg%n"/ > <! -- Define log store path --> <property name="LOG_HOME" value="./logs/" />
    </Properties>
Copy the code
Appenders configures the log output format
  • Console: Displays information on the Console
<! -- Console prints --> <Console name="STDOUT" target="SYSTEM_OUT">
        <PatternLayout pattern="${LOG_PATTERN}"/>
    </Console>
Copy the code
  • File: output common log files
<! -- The file will print out all the information, append istrue, appends logs to the log file, isfalse--> <File name="FileLog" fileName="${LOG_HOME}/file.log" append="true"> <! -- Outputs only info and higher messages (INFO, WARN, error) (onMatch), other messages (onMismatch) --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout pattern="${LOG_PATTERN}" />
    </File>
Copy the code
  • RollingFile: rolls out log files according to the configured rules
<! -- normal info, fileName is the latest log file, every time the size exceeds size, a new archive will be generated in filePattern format --> <RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log" filePattern="${LOG_HOME}/info-%d{yyyy-MM-dd}-%i.log"> <! --> <Filters> <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <! -- interval specifies how many times to scroll. The default value is 1, and filePattern generates archived logs by day if filePattern is YYYY-MM-DD. Is generated by minutes archive logs - > < TimeBasedTriggeringPolicy interval ="1"/ > <! - specifies the size of a single log file - > < SizeBasedTriggeringPolicy size ="5M"/> </Policies> <! -- DefaultRolloverStrategy if not set, default to start overwriting a maximum of 7 files in the same folder --> <DefaultRolloverStrategy fileIndex="max" max="Seven"/>
    </RollingFile>
Copy the code
Loggers sets the logs to be printed

Logger customizations include Logger and Root Logger customizations that allow you to set log levels for specific packages and classes for easy debugging, export specific packages or classes or Logger to separate files, and export logs in one step (LMAXDisruptor support required). All the Logger

<Loggers> <! <logger name= -- Set the log level of the specified package or class, ex: filter out some useless spring and Mybatis DEBUG messages --> < Logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger> <! -- Specify a specific package or class to generate a separate file additivityfalseLogs are not passed up, fortrue--> <Logger name= is printed in the corresponding root log"org.ylc.note.log4j2.service" level="info" additivity="false">
            <AppenderRef ref="RollingFileMyService"/> </Logger> <! -- Specify logger to generate a separate file for schedule logs, here name and loggerFactory.getLogger ("schedule"<Logger name="schedule" level="info" additivity="false">
            <AppenderRef ref="RollingFileSchedule"/> </Logger> <! -- AsyncRoot -- asynchronous logging -- requires LMAXDisruptor support --> <AsyncLogger name="asyncLog" level="info" additivity="false">
            <AppenderRef ref="RollingFileAsync"/> </AsyncLogger> <! -- Specify the Root log of the project --> <Root level="info">
            <AppenderRef ref="STDOUT"/>
            <AppenderRef ref="FileLog"/>
            <AppenderRef ref="RollingFileInfo"/>
            <AppenderRef ref="RollingFileError"/>
        </Root>
    </Loggers>
Copy the code

Unit testing

@springbooTtest Class Log4j2ApplicationTests {/** * private Final Logger normalLogger = LoggerFactory.getLogger(Log4j2ApplicationTests.class); /** * The name of logger must be the same as that of LOGGER in XML. Schedule */ Private Final Logger scheduleLogger = LoggerFactory.getLogger("schedule"); Private final Logger asyncLogger = loggerFactory.getLogger ("asyncLog"); @Autowired private MyService myService; /** * normal log Test */ @test voidnormalLogTest() {
        normalLogger.debug("this is a debug log with out args");
        normalLogger.info("this is a info log with out args");
        normalLogger.error("this is a error log with out args"); } /** * log Test with parameters */ @test voidargsLogTest() {
        MDC.put("user".Fish Fairy);
        MDC.put("args"."Parameters");
        normalLogger.debug("this is a debug log with args");
        normalLogger.info("this is a info log with args");
        normalLogger.error("this is a error log with args"); } /** * Test for independent logs * 1, specify log name * 2, specify package or class */ @test voidindependentLogTest() {// Specify the name schedulelogger.debug ("this is a schedule debug log");
        scheduleLogger.info("this is a schedule info log");
        scheduleLogger.error("this is a schedule error log"); // Specify the package or class myservice.mylog (); } /** * asynchronous log */ @test voidasyncLogTest() {
        asyncLogger.debug("this is a async log -- debug");
        asyncLogger.info("this is a begin async log -- info");
        asyncLogger.error("this is a begin async log -- error"); }}Copy the code

Please focus on