Logback Usage Summary

Posted by RIRedinPA on Thu, 27 Jan 2022 08:10:18 +0100

preface

Sorted out the common functions of logback, and recorded some questions in the process of use and the troubleshooting process of problems, so as to prevent yourself from making similar mistakes again. I hope it will be helpful to you passing by.

1, How to use logback

The use of any framework is a three-step process:
1. Import jar package
2. Configuration file
3. Start using
Logback is no exception. Let's simply say it here and don't repeat it too much. Springboot integrates logback by default, so if you build a springboot project, don't import the jar package of logback, otherwise there will be problems.
The management of configuration files will be described in detail in the second part.
It's easier to use it. Add comments @Slf4j directly, and then use log Info can be used normally.

2, Knowledge points

1.logback simple template

The following is a simple template of logback (in fact, the production system is the same), covering the common configurations of logback. These configurations are enough for daily use. Based on this configuration, summarize the use of logback:

<?xml version="1.0" encoding="UTF-8"  ?>
<configuration debug="false"><!--debug=false Indicates no printing logback of debug information-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss.sss}  %-5level  %class{30}  that 's ok:%line   %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="RollingFileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./logs/info.log</file>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>./logs/%d{yyyy-MM, aux}/info.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
            <totalSizeCap>5GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss.sss}  %-5level  %-60class{60}  that 's ok:%-5line  %msg%n</pattern>
        </encoder>
    </appender>


    <appender name="RollingFileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./logs/error.log</file>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>./logs/%d{yyyy-MM,aux}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <maxFileSize>50MB</maxFileSize>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss.sss}  %-5level  %-60class{60}  that 's ok:%-5line  %msg%n</pattern>
        </encoder>
    </appender>


    <root level="info">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="RollingFileInfo"/>
        <appender-ref ref="RollingFileError"/>
    </root>
</configuration>

2. Analyze the main labels

1.configuration Label
It is the root tag and contains the following three attributes
scan: when this property is set to true, the configuration file will be reloaded if it changes. The default value is true.
debug: when this property is set to true, the internal log information of logback will be printed out to view the running status of logback in real time. The default value is false.
scanPeriod: set the time interval for monitoring whether the configuration file is modified. If no time unit is given, the default unit is milliseconds. This property takes effect when scan is true. The default interval is 1 minute.
Interpretation of usage: generally, these three attributes are configured by default and do not need to be changed.

2.root label

This tag can only have one, which is used to declare some attributes of the root recorder. It has one attribute level, which is used to declare the log level: trace < debug < info < warn < error. In addition, all Appenders need to tell the root recorder. The common configurations are as follows:

	<root level="info"> <!-- Declare the log level, where the declaration will apply to all recorders-->
	    <appender-ref ref="STDOUT" /> <!-- Declare accessor reference-->
	    <appender-ref ref="RollingFileInfo"/>
	    <appender-ref ref="RollingFileError"/>
	</root>

3.appender label
This tag is used to define the appender. The so-called appender is the way of log attachment. This tag is the same level as the root tag and contains two attributes
Name: this attribute specifies that the name of the appender is consistent with that in the root tag.
class: Specifies the attachment method of logs. Common attachments are:

        Console appender: ch.qos.logback.core.ConsoleAppender
		File appender: ch.qos.logback.core.FileAppender
		Scroll file appender: ch.qos.logback.core.rolling.RollingFileAppender

The difference between the three appendages is obvious. The console appender outputs the log to the console, the file appender outputs the log to the file, and the rolling file appender outputs the log to the file. The rolling file appender supports file segmentation, but the file appender does not. So they are basically used: console appender and scroll file appender.

4.encoder label
Encoder is used to declare the format of log. The common methods are as follows

	<encoder>
	    <pattern>%date{yyyy-MM-dd HH:mm:ss.sss}  %-5level  %-60class{60}  that 's ok:%-5line  %msg%n</pattern>
	</encoder>

Common information acquisition methods are as follows:
1)%date gets the current date, or you can specify a more specific format, such as:% date {yyyy mm – dd HH:mm:ss.sss}
2)%level get current log level
3)%msg get the log information printed, that is, the log printed through the recorder in the code
4)%n line break. The log should be added in pattern, so that the log will wrap correctly when it is output
5)%logger gets the current recorder and can also specify the longest display length of the recorder, such as:% logger{50}. Note that this length only limits the length of the name of the recorder printed out
6)%class gets the current class name. Similar to logger, class can also indicate the length, for example:% class{40}
7)%line gets the number of lines of code where the statement that prints the log is located.
8)%thread get current thread name
9)%10class is less than 10 digits, and fill in space before it
10%-10class is less than 10 digits, followed by a space

5.file label
This tag is relatively simple to declare log files.

6.filter label
Change the label to filter. There are two commonly used filters, which are based on log level filtering:
Filter level: ch.qos logback. classic. filter. LevelFilter
When the output log matches the level, the information in onMatch will be returned. When it does not match, the information in onMismatch will be returned.
If DENY is returned, the output is rejected, and ACCEPT is returned. In addition, NEUTRAL can be returned. The function of the following filter is: if the log is error, the log will not be output, otherwise the log will be output.

	<filter class="ch.qos.logback.classic.filter.LevelFilter">
	    <level>error</level>
	    <onMatch>DENY</onMatch>
	    <onMismatch>ACCEPT</onMismatch>
	</filter>

Threshold filter: ch.qos logback. classic. filter. ThresholdFilter
If the output log level is higher than the level declared in level, it will be output, otherwise it will not be output. Those higher than info are warn and error.

	<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
	    <level>info</level>
	</filter>

7.rollingPolicy label
There will be more content in this tag, which mainly defines the log segmentation behavior. In official terms, it is to define the rolling strategy of logs. There are two common scrolling strategies:
Time based rolling strategy: ch.qos logback. core. rolling. TimeBasedRollingPolicy
Its common configuration is shown in the following main. fileNamePattern is used to declare the specific strategy of log segmentation,%d{yyyy mm, aux} special attention should be paid here. Only one date in fileNamePattern is allowed to be declared as aux, and the others must be declared as aux, so that logback can know which time is used as the benchmark to divide the log. maxHistory identifies the storage time of the log. The unit of this time is the time unit of log segmentation in fileNamePattern. totalSizeCap identifies the maximum size of all log files. If it exceeds this value, logback will clean up the original logs to meet this limit.

	<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
	    <fileNamePattern>./logs/%d{yyyy-MM, aux}/info.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
	    <maxHistory>30</maxHistory>
	    <totalSizeCap>5GB</totalSizeCap>
	</rollingPolicy>

Rolling strategy based on size and time: ch.qos logback. core. rolling. SizeAndTimeBasedRollingPolicy
This one has more maxFileSize than the one above. This one limits the file size. When the log reaches this limit, it will be split. In addition, it should be noted that if the specified size is not reached, the log will not be divided even if the specified time is reached. The log will not be divided until the log size is reached. This segmentation scenario is more suitable for systems with a large amount of logs, because at this time, only logs can be segmented many times a day. If the system log with a small amount of logs can be segmented one day, the above time-based segmentation strategy is the best. There are also two points to note%i, which are used to mark the log when splitting the log. There must be. The following point gz is used to compress the file. When the fileNamePattern statement is followed by gz or zip, logback will automatically identify and compress the file.

<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <fileNamePattern>./logs/%d{yyyy-MM,aux}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
    <maxFileSize>50MB</maxFileSize>
    <maxHistory>30</maxHistory>
</rollingPolicy>
8.property tag

It is used to define variable value. It has two properties name and value. The values defined through property can be obtained normally in the configuration file, and "${}" can be used to use variables.

	<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
	   <property name="APP_Name" value="myAppName" /> 
	   <contextName>${APP_Name}</contextName> 
	</configuration>

3, Problems and troubleshooting

Here are some problems encountered during use. Some problems are idiotic, but it's better to keep a record to prevent yourself from committing them again.

1. Description: only the dependency of logback is introduced. When starting the project, an error is reported: Failed to load class "org.slf4j.impl.StaticLoggerBinder"
Solution: add a dependency, which should be the implementation of the above class, as follows:

 <dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>1.6.6</version>
</dependency>

After adding this dependency, the code can normally obtain the recorder, but the configuration file still fails. In fact, the most fundamental reason for the above error is that springboot has integrated logback by default. It is ok to cancel the import without importing it.

2. Description: logback configuration file does not take effect. Logback is added directly under classpath XML or logback spring XML is not valid.
Solution: many methods have been tested. Changing the jar package will not work if the file location is wrong. Now test the following version of reducing springboot. Currently, springboot 2.0 is used 6.3 is reduced to 2.5.9. Finally, it is found that it is not the problem of the springboot version, but because the springboot integrates logback by default, there is no need to manually introduce the dependency. The introduction is redundant operation, and the jar package is redundant. It is found that it is normal to delete the reference.

3. Description: using the default logback of springboot, it is found that the logs will not be printed on the console after adding the configuration file
Solution: This is because the configuration file is used. By default, the configuration is read from the configuration file, but this configuration is not specified, which leads to this result.
Here, you need to specify the log output to the console and an appender for it. This is ok. The detailed configuration is as follows:

	<?xml version="1.0" encoding="UTF-8" ?>
	<configuration>
	    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
		    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	    </appender>
	    <root level="debug">
		<appender-ref ref="STDOUT" />
	    </root>
	</configuration>

4. Question: what is the relationship between the appender and each recorder?
Answer: you can declare an appender in the recorder. Will the appender declared in the recorder be inherited by the recorder's sub recorders? I think it may be possible. If so, why doesn't my log take effect? Theoretically, if the root recorder has an appender, other sub recorders should also have an appender, which should be able to output normally. Strange.
Then test whether the pattern in the previous encoder has log output
Conclusion: the appender of the parent recorder can indeed be obtained by the child recorder, so when we declare the appender, we can only declare it in the root recorder. In addition, the pattern log added by myself did not appear because the log forgot to add% n for line feed, and all logs were output to one line.

5. Problem: when the rolling file adder uses time-based rolling segmentation, the file will not be automatically segmented.
Answer: two reasons:
1). The log output file needs to be specified, and the location of the split file should also be specified (otherwise it will be in the root directory of the project)
2). The log cannot be split until it is being printed. If the log file is empty, the log will not be split even if the time-based segmentation requirements are met.

6. Question: use the size and time-based scrolling strategy in the scrolling file appender. If the project is restarted, can the maxHistory of the previously existing log file still take effect?
It is verified to be effective, so restarting will not affect the integrity of file backup.

7. Question: which value in fileNamePattern is used to split the log
Answer: after testing, it is split with the last% d {} of the specified file name, but other% D needs to be declared with aux, such as% d {yyyy mm, aux}

8. Problems; If logback is configured, do you also need to use the nohup command to specify the output file of the log?
Answer: guess is not necessary. Test it. It is verified that it is not necessary. Start the command to output the console log to the black hole, > / dev / null &.

9. Question: how to use logback in lombok
Answer: you can directly use the annotation @ Slf4j, but you need to install lombok in idea in advance.

10. Question: does the file path use slashes or backslashes
Answer: it seems that absolute paths use backslashes and relative paths use slashes.
After testing, whether relative path or absolute path, slash and backslash can be used in windows without difference.
However, when testing on linux server, it is found that it is difficult to use backslash for relative path, and you have to use backslash.

11. Question: can logback directly compress and package logs, which can save a lot of space
Answer: it is said on the Internet that it is added directly at the end of the split file gz is enough. It seems to be used in the project. Test it.
After verification, it is indeed possible. In fact, it is added at the end zip is also possible. logback supports these two declaration methods for compression.

12. Question: add After gz, the log is not normally segmented by time
Guess: because of the size 1mb limit, the time is cut in minutes. Do you have to reach the size of 1mb before cutting according to time. If so, it means that the cutting must be carried out with the maximum restrictions. If it is cut in minutes, the file size will not be cut if it does not reach the maximum within one minute. If it does not reach the maximum value, it will be cut. If it does, it will be cut according to the size. So can we say that the rolling strategy based on time and size is actually based on size, and time is only auxiliary.
Verification: it is true. Hejia gz has nothing to do with it.

13. Question: if logback is used to record logs, nohup cannot be used to record logs during startup. How should the startup command be written?
Answer: Java - server - Jar - xss1m - server - xms512m - xmx2048m - xmn128m - XX: metaspacesize = 128M - XX: + useconcmarksweepgc MDM project server biz jar >/dev/null &
This command is used normally in local tests. When uat is started, it is found that the log is not output normally.
After a profound lesson, when using jenkins n to package and publish, because after ssh to the target server, the default path is the working path of the user you log in to. Executing the above command here will create the files created in the script here instead of taking the path where the jar package is located as the relative path. This problem has been solved for 3 hours. It is a deep lesson. When writing a script in jenkins, ssh must first cd and then operate.

14. Question: time based scrolling strategy versus size and time based scrolling strategy
Answer: time based scrolling strategy: if you specify the scrolling time, you will only scroll down in time, but you can also add this limit to it:

 <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
 	<!-- maxFileSize:This is the size of the active file. The default value is 10 MB,During the test, it can be changed to 1 KB See the effect -->
 	 <maxFileSize>3kb</maxFileSize>
 </timeBasedFileNamingAndTriggeringPolicy>

In this way, as like as two peas and a time based scroll strategy, the rolling effect is exactly the same. They all look at whether the size is reached first. When the size is reached, the log file will be divided by time. If the size is not reached, the file will not be divided. The experience value plus its effect is basically consistent with the rolling strategy based on size and time.

15. Problem: after% {yyyy mm} is added to the fileNamePattern log output path (absolute path), the log cannot be divided normally
Answer: after verification, the folder of the current date cannot be produced normally in windows system after adding this path.
The following tests whether it is feasible to add this path to the relative path: it is not feasible. In windows system, it fails to add this folder whether it is an absolute path or a relative path.
But it's strange to remember before.
Verify the situation in linux system again: it seems that it doesn't work all of a sudden.
Is it related to this:%d{yyyy MM DD, aux}: after checking, this configuration tells logback not to split at this time. In a fileNamePattern, except for the specified split date, other dates need to add this aux.
After verification, it is found that it is really related to this configuration, and the problem is solved.

summary

This is a summary of my study of logback. At the same time, it records my ideas to solve the problems in the learning process. There are not many logback things, which are basically enough. As for the color log of the console, it is useless and has not been studied. Record here that hope can help those who want to learn.

Topics: Java Spring Boot jar