Log4j has been introduced, SLF4J has been introduced, and then, you know, Logback is going to make a big debut, after all, it has a father, that is Ceki Gulcu.

Just yesterday, after hearing how awesome Logback was, my boss was so impressed that he gave me a death order: “It’s such a great logging system, why don’t you hurry up and switch it to our project?”

The Log4j we used for our project is, in my opinion, sufficient, since it is a small company with less demanding performance requirements.

01. Where is Logback strong

1) SLF4J is implemented quite naturally, without the need for an adaptation layer like Log4j and JUL.

2) The default logging framework for Spring Boot uses Logback. Once a library becomes the default option, that means it’s ahead of the competition.

Note the following figure (evidence found, from Spring Boot) :

It can also be seen in source form:

3) Support automatic reloading of configuration files, no need to create another scanning thread to monitor.

4) Since it is a giant’s new work, it must have a great improvement in performance, otherwise?

02. Logback Usage example

First, add the Logback dependency to the POM.xml file:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
Copy the code

Maven automatically imports two other dependencies:

Logback-core is the core of logback and logback-classic is the implementation of SLF4J.

Step 2, here’s the simplest test case:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/ * * *@authorWechat search "silent King 2", reply keyword PDF */
public class Test {
    static Logger logger = LoggerFactory.getLogger(Test.class);
    public static void main(String[] args) {
        logger.debug("logback"); }}Copy the code

Both Logger and LoggerFactory come from SLF4J, so if the project switches from Log4j + SLF4J to Logback, the code is unchanged.

Run the Test class and you can see the following information on the console:

12:04:20.149 [main] DEBUG com.itwanger.Test - logback
Copy the code

In the absence of a configuration file, everything is default and Logback logs are printed to the console. StatusPrinter can print Logback internal information:

LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
Copy the code

After adding the above code to the main method and running the Test class again, you can see the following information on the console:

12:59:22. [the main] the DEBUG com 314. Itwanger. Test - logback 12:59:22, | - INFO in 261 Ch. Qos. Logback. Classic. LoggerContext [default] - Could NOT find the resource logback - test. XML 12:59:22, | - INFO in 262 Ch. Qos. Logback. Classic. LoggerContext [default] - Could NOT find the resource logback. Groovy 12:59:22, | - INFO in 262 Ch. Qos. Logback. Classic. LoggerContext [default] - Could NOT find the resource logback. XML 12:59:22, | - INFO in 268 ch.qos.logback.classic.BasicConfigurator@5e853265 - Setting up default configuration.Copy the code

That is, Logback looks for the logback-test. XML file in the classpath path. If it doesn’t find it, it looks for the logback.groovy file, and if it doesn’t find it, it prints it to the console.

Typically, logback-test.xml is configured in a local environment and logback.xml is configured in a production environment.

Step 3 add the logback-test. XML file to the resource directory as follows:

<configuration debug="true">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %relative [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
Copy the code

The Logback configuration file is very flexible, with the basic structure of a

element consisting of zero or more

elements, followed by zero or more

elements, followed by at most one

element.



Appender (name) appender (class) appender (name) appender (class)

  • Ch. Qos. Logback. Core. ConsoleAppender: output to the console.
  • Ch. Qos. Logback. Core. FileAppender: output to a file.
  • Ch. Qos. Logback. Core. Rolling. RollingFileAppender: file size over threshold to create a new file.

In addition to exporting locally, you can also export to remote devices via SocketAppender and SSLSocketAppender, and to mail via SMTPAppender. You can even output to the database via DBAppender.

Encoder is responsible for converting the log information into byte arrays and writing the byte arrays to the output stream.

Pattern is used to specify the log output format:

  • %d: Time format of the output.
  • %thread: Specifies the thread name of the log.
  • %-5level: Log output level, up to 5 characters. For example, if info is only 4 characters long, fill in a space so that the log information is aligned.

Counterexample (if -5 is not specified) :

  • %logger{length}: Name of logger, length is used to shorten the name. Complete output is not specified; 0 means that only strings after the right-most dot of Logger are printed; Other numbers represent the number of characters before the last dot of the output decimal point.
  • %msg: Indicates log information.
  • %n: Newline character.
  • %relative: Outputs the time from the start of the program to the creation of a log, in milliseconds.

2) Configure root, which supports only one attribute — level, which can be: TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF.

Appender-ref is used to specify the specific appender.

3) View internal status information.

You can print Logback internal status information in code by using StatusPrinter, or you can print internal status information by enabling DEBUG on configuration.

Re-run the Test class and you can see the following information on the console:

13:54:54, 718 | - INFO in ch. Qos. Logback. Classic. LoggerContext [default] - Found the resource at [logback - test. XML] [file: / Users/maweiqing/Documents/lot/JavaPointNew/codes/logbackDemo/target/classes/logback - test. XML] 13:54:54, 826 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch. Qos. Logback. Core. ConsoleAppender] 13:54:54, 828 | - INFO in ch. Qos. Logback. Core. Joran. Action. AppenderAction - Naming Appenders as [STDOUT] 13:54:54, 833 | - INFO in ch. Qos. Logback. Core. Joran. Action. NestedComplexPropertyIA - Assuming the default Type [ch. Qos. Logback. Classic. Encoder. PatternLayoutEncoder] for [encoder] property 13:54:54, | - INFO in 850 Ch. Qos. Logback. Classic. Joran. Action. RootLoggerAction - Setting the level of the ROOT logger to DEBUG 13:54:54, | - INFO in 850 Ch. Qos. Logback. Core. Joran. Action. AppenderRefAction - Attaching appender named [STDOUT] to Logger ROOT 13:54:54, 850 | - INFO in ch. Qos. Logback. Classic. Joran. Action. ConfigurationAction - the End of the configuration. 13:54:54, | - INFO in 851 ch.qos.logback.classic.joran.JoranConfigurator@f8c1ddd - Registering current configuration as safe fallback point 13:54:54.853 [main] DEBUG com.itwanger.Test - logbackCopy the code

4) Automatic overload configuration.

One of Logback’s strongest features is its ability to automatically reload configurations, which can be easily enabled by adding scan=true to the Configuration element.

<configuration scan="true">
    ...
</configuration>
Copy the code

By default, the scan interval is once a minute. If you want to adjust the interval, you can do so in milliseconds, seconds, minutes, or hours using the scanPeriod property.

The following example specifies an interval of 30 seconds:

<configuration scan="true" scanPeriod="30 seconds"
   ...
</configuration>
Copy the code

Note: If an interval is specified, no time unit is specified. The default time unit is milliseconds.

When Scan =true is set, Logback starts a ReconfigureOnChangeTask task to monitor configuration file changes.

Change log4j.properties to logback-test.xml

If your project used Log4j previously, you can convert log4j.properties to logback-test.xml using the following url:

logback.qos.ch/translator/

Make a copy of the previous log4j.properties:

Set # # # # # # log4j. RootLogger = debug, stdout, D, E to the console # # # # # # outputs, log4j. Appender. Stdout = org.. Apache log4j. ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout Log4j. Appender. Stdout. Layout. ConversionPattern = [% - 5 p] % d {MM - dd yyyy - HH: MM: ss, SSS} method: % l % n % m % n # # # the DEBUG output Level above the log to = debug. The log # # # log4j. Appender. D = org.. Apache log4j. DailyRollingFileAppender log4j. Appender. D.F ile. = the debug log log4j.appender.D.Append = true log4j.appender.D.Threshold = DEBUG log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] # # # % m % n output to = ERROR. The ERROR level above the log log # # # log4j. Appender. E = org.. Apache log4j. DailyRollingFileAppender log4j.appender.E.File =error.log log4j.appender.E.Append = true log4j.appender.E.Threshold = ERROR log4j.appender.E.layout = org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%nCopy the code

Paste into the text field of the url:

Click Translate to get the following:

<? The XML version = "1.0" encoding = "utf-8"? > <! -- For assistance related to logback-translator or configuration --> <! -- files in general, please contact the logback user mailing list --> <! -- at http://www.qos.ch/mailman/listinfo/logback-user --> <! -- -- -- > <! -- For professional support please see --> <! -- http://www.qos.ch/shop/products/professionalSupport --> <! -- --> <configuration> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <Target>System.out</Target> <encoder> <pattern>[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n</pattern> </encoder> </appender> <appender name="D" class="ch.qos.logback.core.rolling.RollingFileAppender"> <! --See http://logback.qos.ch/manual/appenders.html#RollingFileAppender--> <! --and http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy--> <! --for further documentation--> <Append>true</Append> <File>debug.log</File> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [  %t:%r ] - [ %p ] %m%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>DEBUG</level> </filter> </appender> <appender name="E" class="ch.qos.logback.core.rolling.RollingFileAppender"> <! --See http://logback.qos.ch/manual/appenders.html#RollingFileAppender--> <! --and http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy--> <! --for further documentation--> <File>error.log</File> <Append>true</Append> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [  %t:%r ] - [ %p ] %m%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> </appender> <root level="debug"> <appender-ref ref="stdout"/> <appender-ref ref="D"/> <appender-ref ref="E"/> </root> </configuration>Copy the code

Verify that all three appenders are present.

However, the converted file cannot be used directly and needs to be adjusted slightly because:

First, the log format is slightly different; there is no % L in Logback.

Second, the RollingFileAppender needs to specify the RollingPolicy and TriggeringPolicy, with the former responsible for the log’s rolling function and the latter responsible for the log’s rolling timing. If the RollingPolicy also implements the TriggeringPolicy interface, then all you need to do is set the RollingPolicy.

TimeBasedRollingPolicy and SizeAndTimeBasedRollingPolicy are two of the most commonly used rolling strategy.

TimeBasedRollingPolicy implements both the RollingPolicy and TriggeringPolicy interfaces, so you can use TimeBasedRollingPolicy without specifying TriggeringPolicy.

TimeBasedRollingPolicy can specify the following attributes:

  • FileNamePattern, which defines the name of the file (mandatory). Its value should be the filename with a %d placeholder. % d should contain Java. Text. The date format specified in the SimpleDateFormat, default is yyyy – MM – dd. The scroll period is inferred by fileNamePattern.

  • MaxHistory, the maximum number of log files to keep (optional), will delete old files asynchronously. For example, if you specify monthly scrolling and maxHistory = 6, log files older than 6 months will be retained and those older than 6 months will be deleted.

  • TotalSizeCap, size of all log files (optional). Beyond this size, old log files will be deleted asynchronously. Needs to be used in conjunction with the maxHistory property and is a second condition.

Consider the following RollingFileAppender configuration:

<appender name="D" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>debug.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <! --> <fileNamePattern>debug.%d{YYYY-MM-DD}. Log </fileNamePattern> <! -- Keep historical records for 30 days. </maxHistory> <totalSizeCap>3GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%relative [%thread] %level %logger{35} - %msg%n</pattern> </encoder> </appender>Copy the code

Based on the scroll by day policy, the file can be retained for a maximum of 30 days with a maximum size of 30 GB.

SizeAndTimeBasedRollingPolicy than TimeBasedRollingPolicy a log file size set of attributes: maxFileSize, other are exactly the same.

Based on what we know about RollingPolicy, we can change the logback-test.xml content to the following:

<configuration> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <Target>System.out</Target> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %level %logger{36} - %msg%n</pattern> </encoder> </appender> <appender name="D" class="ch.qos.logback.core.rolling.RollingFileAppender"> <Append>true</Append> <File>debug.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <! --> <fileNamePattern>debug.%d{YYYY-MM-DD}. Log </fileNamePattern> <! -- Keep historical records for 30 days. </maxHistory> <totalSizeCap>3GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%relative [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="E" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>error.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <! Error.%d{YYYY-MM-DD}. Log </fileNamePattern> <! -- Keep historical records for 30 days. </maxHistory> <totalSizeCap>3GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> </appender> <root level="debug"> <appender-ref ref="stdout"/> <appender-ref ref="D"/> <appender-ref ref="E"/> </root> </configuration>Copy the code

Modify the contents of the Test class:

public class Test {
    static Logger logger = LoggerFactory.getLogger(Test.class);
    public static void main(String[] args) {
        logger.debug("logback");
        logger.error("logback"); }}Copy the code

After running, you can see two files in the target directory: debug.log and error.log.

At this point, the project has switched from Log4j to Logback, and the process is very smooth.

04. Logback Manual

Logback has a very detailed manual on its website, more than 200 pages, but it’s in English. After reading the Logback tutorial for this article, go to the following address to read the official manual.

Logback. Qos. Ch/manual/inde…

If your English reading skills are limited, you can check out lei feng’s Chinese translation on GitHub:

Github.com/itwanger/lo…

Of course, some of you like to see the offline VERSION of the PDF, WHICH I have sorted out:

Link: pan.baidu.com/s/16FrbwycY… Password: BPTL

The truth, the feeling of white piao is comfortable, hurry to download it! Daily for three even, thank you for your diligent fingers, hey hey.