Details the configuration of slf4j+logback in the Java project

  • 2020-04-01 04:09:04
  • OfStack

This article mainly introduces the configuration of slf4j+logback in Java engineering. The readers are mainly those who have some understanding of slf4j+logback.
Before introducing the slf4j+logback configuration, let's first introduce the logging component logback.
(a) log component logback introduction and configuration use method
I. introduction of logback
      Logback is another open source logging component designed by the log4j founders. Logback is currently divided into three modules: logback-core, logback-classic, and logback-access. Logback-core is the base module for the other two modules. Logback-classic is an improved version of log4j. In addition, the full implementation of the SLF4J API in logback-classic makes it easy to switch to other Logging systems such as log4j or JDK14 Logging. The logback-access access module is integrated with the Servlet container to provide access to logs over Http. Logback is the official site to be combined with SLF4J with two components as follows:
      Logback's official website: (link: http://logback.qos.ch)
      SLF4J's official website: (link: http://www.slf4j.org)
      This article USES the following components: please download the official website!
      Logback - access - 1.0.0. Jar
      Logback - classic - 1.0.0. Jar
      Logback - core - 1.0.0. Jar
      Slf4j - API - 1.6.0. Jar
Ii. Reasons for logback to replace log4j:
      Logback is very similar to log4j, and if you are familiar with log4j, you will be comfortable with Logback very quickly. Here are some advantages of logback over log4j:
      1. Faster implementation   The Logback kernel was rewritten, increasing performance by more than 10 times on some critical execution paths. And logback not only improves performance, it also initializes less memory load.
      A very thorough test   Logback went through years and hours of testing. Logback is tested at a completely different level. From the author's point of view, this is a simple and important reason to choose logback over log4j.
      3. Logback-classic is a very natural implementation of SLF4j      SLF4j is implemented in logback-classic. With SLF4j, you won't even feel logback-classic. And because logback-classic implements SLF4J,   very naturally; So it's easy to switch to log4j or something else, just provide another jar and you don't need to touch the code implemented through SLF4JAPI at all.
      4. Excellent documentation   The official website has more than 200 pages of documentation.
      5. Automatic reload of configuration files   When the configuration file is modified, logback-classic automatically reloads the configuration file. The scan process is fast and safe, and it does not require the creation of an additional scan thread. This technique fully ensures that applications can run happily in a JEE environment.
      6, Lilith    Lilith is an observer of log events, similar to log4j's chainsaw. Lilith can also handle large amounts of log data.
      7. Cautious mode and very friendly recovery   In careful mode, multiple instances of FileAppender run under multiple JVMS, safe enough to write to the same log file. The rollingfileappder has some restrictions. Logback's FileAppender and its subclasses including RollingFileAppender are very friendly to recovering from I/O exceptions.
      Configuration files can handle different situations     Developers often need to judge different Logback profiles in different environments (development, test, production). And these configuration files are just a few minor differences that can be implemented through alpha and beta, so that a single configuration file can be adapted to multiple environments.
      9. Filters & Filters; Sometimes you need to diagnose a problem and log it. In log4j, you only have to lower the logging level, but this results in a large amount of logging, which can affect application performance. In Logback, you can continue to keep that log level except for certain special cases, such as when Alice logs in, her log will be typed at DEBUG level and other users can continue to type at WARN level. You only need to add four lines of XML configuration to achieve this. You can refer to the MDCFIlter.
    10. A SiftingAppender (a very versatile Appender)   It can be used to split log files according to any given run parameter. For example, a SiftingAppender can distinguish between log events that follow a user's Session, and then each user has a log file.
    11. Auto-compress the log  already typed; When a RollingFileAppender generates a new file, it automatically compresses the log file that has been typed. Compression is an asynchronous process, so even for large log files, the application is not affected during compression.
    12. Stack tree with package version   Logback takes the package's data with it when it logs the stack tree.
    Automatically remove old log files   By setting the maxHistory property of TimeBasedRollingPolicy or SizeAndTimeBasedFNATP, you can control the maximum number of log files that have been generated. If you set maxHistory 12, those log files that are more than 12 months old will be automatically removed.
      In short, logback is much better than log4j, so let's all build on it!
Three, Logback configuration
1. Logger, appenders and layout
      Logger, as a Logger of logs, is mainly used to store log objects after it is associated with the corresponding context of the application, and log types and levels can also be defined.
      Appenders are primarily used to specify destinations for log output, which can be consoles, files, remote socket servers, MySQL, PostreSQL, Oracle, and other databases, JMS, and remote UNIX Syslog daemons.
      Layout is responsible for converting events to strings and formatting the output of log information.
  2, the logger context
            Each logger is associated with a LoggerContext, which is responsible for making loggers and for arranging loggers in a tree structure. All other loggers are also obtained by the static method getLogger of the org.slf4j.loggerfactory class. The getLogger method takes the logger name as an argument. Calling the loggerfactory.getlogger method with the same name always gets a reference to the same logger object.
  3. Inheritance of valid levels and levels
          Logger can be assigned levels. Level include: TRACE, DEBUG, INFO, WARN, and the ERROR, defined in ch. Qos. Logback. Classic. Level class. If the logger is not assigned a level, it inherits the level from the nearest ancestor that has the assigned level. The default level of root logger is DEBUG.
4. Printing method and basic selection rules
      The print method determines the level of record requests. For example, if L is an instance of logger, the statement l.info ("..") ) is a record statement at the INFO level. The record request level is said to be enabled when it is above or equal to the valid level of its logger; otherwise, it is said to be disabled. The record request level is p, the effective level of its logger is q, only if p> =q, the request is executed.
      This rule is at the heart of logback. Rank sort: TRACE < The DEBUG < The INFO < WARN < The ERROR
Four, the default configuration of Logback
          If the configuration files logback-test.xml and logback.xml do not exist, logback by default calls BasicConfigurator to create a minimal configuration. The minimization configuration consists of a ConsoleAppender associated with the root logger. The output is formatted with a PatternLayoutEncoder with a pattern of %d{HH:mm: ss.sss} [%thread] %-5level %logger{36} - % MSG %n. The default level of root logger is DEBUG.
  1. Logback configuration file
          The syntax of the Logback configuration file is very flexible. Because of this flexibility, you cannot define it with a DTD or an XML schema. However, the basic structure of the configuration file can be described as follows: Configuration> Beginning, followed by zero or more < Appender> Elements having zero or more < Logger> Element, which has at most one < Root> Elements.
2. Steps for the default Logback configuration
        (1). Try to find the file logback-test.xml under classpath;
        (2). If the file does not exist, find the file logback.xml;
        (3) if both files do not exist, logback automatically configures itself with Bas icConfigurator, which results in records being output to the console.
3. Logback. XML file          


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <!-- Defines the storage address for log files   Don't in  LogBack  Relative paths are used in the configuration of --> 
  <property name="LOG_HOME" value="c:/log" /> 
  <!--  Console output  -->  
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!--  Log output coding  --> 
    <Encoding>UTF-8</Encoding>  
    <layout class="ch.qos.logback.classic.PatternLayout">  
       <!-- Format output: %d Represents the date, %thread Represents the thread name, %-5level : the level is shown from the left 5 Character width %msg : log message, %n Is a newline --> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n  
      </pattern>  
    </layout>  
  </appender>  
  <!--  Generate log files on a daily basis  -->  
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
    <Encoding>UTF-8</Encoding>  
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- The file name of the log file output -->
      <FileNamePattern>${LOG_HOME}/myApp.log.%d{yyyy-MM-dd}.log</FileNamePattern>  
      <MaxHistory>30</MaxHistory>
    </rollingPolicy>  
    <layout class="ch.qos.logback.classic.PatternLayout"> 
      <!-- Format output: %d Represents the date, %thread Represents the thread name, %-5level : the level is shown from the left 5 Character width %msg : log message, %n Is a newline --> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n  
      </pattern>  
    </layout> 
    <!-- Maximum size of log file -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
     <MaxFileSize>10MB</MaxFileSize>
    </triggeringPolicy>
  </appender> 
  <!-- show parameters for hibernate sql  Specially designed for  Hibernate  custom  --> 
  <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" /> 
  <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" /> 
  <logger name="org.hibernate.SQL" level="DEBUG" /> 
  <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> 
  <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> 
  
  <!--  Log output level  -->
  <root level="INFO">  
    <appender-ref ref="STDOUT" />  
    <appender-ref ref="FILE" />  
  </root> 
   
   <!-- Logs are asynchronous to the database  --> 
  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <!-- Logs are asynchronous to the database  --> 
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
      <!-- The connection pool  --> 
      <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <driverClass>com.mysql.jdbc.Driver</driverClass>
       <url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
       <user>root</user>
       <password>root</password>
      </dataSource>
    </connectionSource>
 </appender> -->
</configuration>

Use the reference Logback in the program


package com.stu.system.action; 

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

public class BlogAction{
   //Defines a global logger, retrieved through the LoggerFactory
   private final static Logger logger = LoggerFactory.getLogger(BlogAction.class); 
   
  public static void main(String[] args) {
    logger.info("logback  A success ");
    logger.error("logback  A success ");
  }
}

Let's take a look at the configuration of slf4j+logback in a Java project.

I. slf4j+logback pom.xml configuration based on maven


<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.10</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.1.2</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>1.1.2</version>
</dependency>

Create a new logback.xml configuration file in the classpath directory


<?xml version="1.0" encoding="UTF-8"?>
<!--
scan : when this property is set to true If the configuration file is changed, it will be reloaded. The default value is true . 
scanPeriod : sets the time interval for monitoring whether the configuration file is modified. If no time unit is given, the default unit is milliseconds when scan for true When this property takes effect. The default time interval is 1 Minutes. 
debug : when this property is set to true , will be printed out logback Internal log information, real-time view logback Running state. The default value is false . 
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">
  <!--  Define the root directory of the log  -->
  <property name="LOG_HOME" value="/app/log" />
  <!--  Define the log file name  -->
  <property name="appName" value="netty"></property>
  <!-- ch.qos.logback.core.ConsoleAppender  Represents console output  -->
  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <Encoding>UTF-8</Encoding>
    <!--
     Log output format: %d Represents the date and time, %thread Represents the thread name, %-5level : the level is shown from the left 5 Character width 
    %logger{50}  said logger Name the longest 50 , otherwise split by period.  %msg : log message, %n Is a newline 
    -->
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
    </layout>
  </appender>

  <!--  To scroll through the log file, log to the specified file first, and log to another file when a condition is met  --> 
  <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <Encoding>UTF-8</Encoding>
    <!--  Specify the name of the log file  --> 
    <file>${LOG_HOME}/${appName}.log</file>
    <!--
     When a roll occurs, determines  RollingFileAppender  Behavior involving file movement and renaming 
    TimeBasedRollingPolicy :   The most commonly used rolling strategy, which is designed according to time and is responsible for both rolling and starting rolling. 
    -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!--
       The location and file name of the file generated when scrolling  %d{yyyy-MM-dd} : log scrolling by day  
      %i : when the file size exceeds maxFileSize When, in accordance with the i Scroll the file 
      -->
      <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
      <!-- 
       Optional node that controls the maximum number of archived files that are retained, beyond which old files are deleted. So let's say I set it to scroll every day, 
       and maxHistory is 365 , save only the most recent 365 Days of files before deleting old files. Notice that deleting old files is, 
       Directories created for archiving are also deleted. 
      -->
      <MaxHistory>365</MaxHistory>
      <!-- 
       When the log file exceeds maxFileSize The specified size is, as mentioned above %i Scroll the log file   Notice the configuration here SizeBasedTriggeringPolicy Scrolling by file size is not possible and must be configured timeBasedFileNamingAndTriggeringPolicy
      -->
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <!--
     Log output format: %d Represents the date and time, %thread Represents the thread name, %-5level : the level is shown from the left 5 Character width  %logger{50}  said logger Name the longest 50 , otherwise split by period.  %msg : log message, %n Is a newline 
    -->   
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
    </layout>
  </appender>

  <!-- 
  logger Mainly used to store log objects, you can also define the log type, level 
  name : means matched logger The type prefix, which is the first half of the package 
  level : the level of logging to be logged, including  TRACE < DEBUG < INFO < WARN < ERROR
  additivity : the role of children-logger Whether to use  rootLogger Configuration of the appender Output, false : means only the current logger the appender-ref . true : represents the current logger the appender-ref and rootLogger the appender-ref Are effective 
  -->
  <!-- hibernate logger -->
  <logger name="org.hibernate" level="error" />
  <!-- Spring framework logger -->
  <logger name="org.springframework" level="error" additivity="false"></logger>

  <logger name="com.creditease" level="info" additivity="true">
    <appender-ref ref="appLogAppender" />
  </logger>

  <!-- 
  root with logger Is a parent-child relationship and defaults to root , any class will only have one logger Corresponding, 
   Or it's defined logger , either root The key to judgment is to find this logger And then judge this logger the appender and level .  
  -->
  <root level="info">
    <appender-ref ref="stdout" />
    <appender-ref ref="appLogAppender" />
  </root>
</configuration> 



Related articles: