spring boot Use logback Log Level Print Control Operations

  • 2021-08-31 08:08:34
  • OfStack

Because the business needs of the company, the performance log and business log need to be printed separately and collected and processed by elk, so the logs of different businesses need to be printed to different files.

The logback that comes with spring boot is used.

First, configure the logback. xml file in the yml file. By default, you will find the logback. xml file under resources. If you can't find it, you will find the specified file under logging. config from the yml file.


logging:
 level: DEBUG
 config: classpath:logback.xml

logback. xml is the configuration file of logback. You can set the path, format, filter printing level, etc. Let's look at logback. xml file.


<?xml version="1.0" encoding="UTF-8"?>
<!--根标签-->
<configuration>
  <!--设置变量,name为变量名,value为值,可以使用${变量名}方式使用-->
  <property name="APPDIR" value="log" />
  <property name="LOG_HOME" value="/var/app/logs" />
  <property name="APPNAME" value="app_test" />
  <property name="MDC_LOG_PATTERN"
  value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS} %p app_test %t %logger{50} [line:%L %msg]%n"></property> 
 
  <!-- 性能日志记录器,日期滚动记录 -->
  <!--当1个记录日志的事件被发起时,logback 会将这个事件发送给 appender-->
  <!--RollingFileAppender,滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件-->
  <appender name="performanceAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 记录的日志文件的路径及文件名 -->
    <file>${LOG_HOME}/${APPNAME}/performanceLog/${APPNAME}.log</file>
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
    <!--TimeBasedRollingPolicy 实现的是基于时间的分包策略,分包间隔是根据fileNamePattern中指定的事件最小单位-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- 归档的日志文件的路径,例如今天是2018-12-19日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
        而2018-12-01的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
      <fileNamePattern>${LOG_HOME}/${APPNAME}/performanceLog/${APPNAME}-%d{yyyyMMdd}.%i.log</fileNamePattern>
      <!-- 除按日志记录之外,还配置了日志文件不能超过50Mb,若超过50Mb,日志文件会以索引0开始, 命名日志文件,例如app_test-20181219.0.log -->
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!--最大50mb-->
        <maxFileSize>50MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <!-- 追加方式记录日志 -->
    <append>true</append>
    <!-- 日志文件的格式和编码 -->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <pattern>%d{yyyy/MM/dd' 'HH:mm:ss.SSS} %X{req.requestId}[line:%L %msg] %n</pattern>
      <charset>utf-8</charset>
    </encoder>
     <!--此日志文件只记录info级别的-->
    <!--filter是日志过滤器-->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <!--过滤级别-->
      <level>info</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender> 
 
  <!-- 运行日志记录器,日期滚动记录 -->
  <appender name="bizAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 正在记录的日志文件的路径及文件名 -->
    <file>${LOG_HOME}/${APPNAME}/bizLog/${APPNAME}.log</file>
    <!-- 日志记录器的滚动策略,按日期,按大小记录-->
 
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      
      <fileNamePattern>${LOG_HOME}/${APPNAME}/bizLog/${APPNAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
      <!-- 除按日志记录之外,还配置了日志文件不能超过50M,若超过50M,日志文件会以索引0开始, 命名日志文件,例如bizlog-biz-20181219.0.log -->
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>50MB</maxFileSize>
        <!--保存时间3天-->
        <!--<MaxHistory>3</MaxHistory>-->
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <!-- 追加方式记录日志 -->
    <append>true</append>
    <!-- 日志文件的格式 -->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <pattern>%d{yyyy/MM/dd' 'HH:mm:ss.SSS} %X{req.requestId}[line:%L %msg] %n</pattern>
      <charset>utf-8</charset>
    </encoder>
    <!-- 此日志文件只记录info级别的 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>info</level>
      <level>error</level>
      <!--<onMatch>ACCEPT</onMatch>-->
      <!--<onMismatch>DENY</onMismatch>-->
    </filter>
  </appender>
 
  <!--ConsoleAppender是打印到控制台的-->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!--encoder 默认配置为PatternLayoutEncoder-->
    <encoder>
      <pattern>${MDC_LOG_PATTERN}</pattern>
      <charset>utf-8</charset>
    </encoder>
    <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>all</level>
    </filter>
  </appender>
 
  <!--使用LoggerFactory.getLogger("performanceLogger") 使用这个logger-->
  <logger name="performanceLogger" additivity="false">
    <!--使用哪1个Appender-->
    <appender-ref ref="performanceAppender" />
 
  </logger>
  <!--根loger。只有1个level属性,应为已经被命名为"root".-->
  <root level="info">
    <appender-ref ref="bizAppender" />
    <appender-ref ref="STDOUT" />
 
  </root> 
</configuration>

< configuration > Root tag. All tags are in it.

< property > Attribute tag, set variable, name for variable name, value for value, can use ${variable name}.

< appender > When a logging event is initiated, logback sends the event to appender, which is frequently used as ch. qos. logback. core. ConsoleAppender and ch. qos. logback. core. rolling. RollingFileAppender. RollingFileAppender is a scrolling log file. ConsoleAppender is first logged to a specified file, and when a certain condition is met, it is logged to other files.

< file > : In < appender > The path and file name of the log file used and recorded in.

< rollingPolicy > : Subcontracting strategy, that is, the storage file name, size, compression format and storage days of the log in the previous day. ch. qos. logback. core. rolling. TimeBasedRollingPolicy: Implements a time-based subcontracting policy with subcontracting intervals based on < fileNamePattern > Gets or sets the minimum unit of events specified in the.

< fileNamePattern > The path and name where the log is stored.

< maxFileSize > Maximum file per file.

< encoder > Format and encoding of log files.

< charset > Log encoding format.

< pattern > Format log printing.

< filter > Log filter.

< level > Log filtering levels, TRACE, DEBUG, INFO, WARN, ERROR, ALL, and OFF.

< logger > Use LoggerFactory. getLogger ("performanceLogger") Use this logger.

< root > : Root loger. There is only one level attribute, which should have been named "root".

% d {yyyy/MM/dd ''HH: mm: ss. SSS}: Is formatted for time, 2018/12/19 17:31: 17.126

% X {req. requestId}: You can use it in logback. xml by adding the req. requestId parameter to the MDC class, followed by the MDC class.

% p: Print out log level information such as error levels such as INFO, ERROR, etc.

% t: It is a log printed by a printing thread or which class.

% L: Prints out the current number of lines.

% msg: That's the log information. Is logger. info ("xxx"), xxx is% msg.

% n: Wrap.

MDC

Is a method tool class that appears to facilitate us to diagnose online problems.


public class MDC {
 //Put a context value as identified by key
 //into the current thread's context map.
 public static void put(String key, String val);
 
 //Get the context identified by the key parameter.
 public static String get(String key);
 
 //Remove the context identified by the key parameter.
 public static void remove(String key);
 
 //Clear all entries in the MDC.
 public static void clear();
}

Basic use


MDC.put("req.requestId", uuid);
MDC.put("req.remoteHost", request.getRemoteHost());
<pattern>%d{yyyy/MM/dd' 'HH:mm:ss.SSS} %X{req.requestId}[line:%L %msg] %n</pattern>

% X {req. requestId} can be used in logback. xml to obtain uuid.

Print to different files


private final static Logger performanceLogger = LoggerFactory.getLogger("performanceLogger");

So you can use logback. xml < logger > performanceLogger and performanceLogger refer to performanceAppender.


private static final Logger logger = LoggerFactory.getLogger(Class.class);

In this way, we use logback. xml < root > bizAppender in the label.

In this way, different business logic is basically printed to different files.

Supplement: Springboot uses logback to output logs at different levels to different paths

By default, SpringBoot already relies on some logging frameworks (such as Logback), and Logback is recommended. Therefore, in this project, we will output logs at different levels to different paths by adding Logback log configuration.

SpringBoot already relies on Logback, so you don't need to add dependencies manually.

SpringBoot will automatically identify and read the new logback-spring. xml under the resources directory, so no other configuration is needed in application. yml.

The configuration file is as follows:


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <!--  Project name  -->
  <property name="PROJECT_NAME" value="XXXXX" />
 
  <!--  File output format  -->
  <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
  <!--  Output file path  -->
  <property name="OPEN_FILE_PATH" value="logs/manager"/>
 
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${PATTERN}</pattern>
      <charset>UTF-8</charset>
    </encoder>
  </appender>
 
  <!-- ch.qos.logback.core.rolling.RollingFileAppender  File log output  -->
  <appender name="OPEN-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- This configuration cannot be available! ! ! ! ! -->
    <!--<Encoding>UTF-8</Encoding>-->
    <!--<File>${OPEN_FILE_PATH}/zqread.log</File>-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- File name of log file output -->
      <FileNamePattern>${OPEN_FILE_PATH}/all/zqread.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
      <!-- Log file retention days -->
      <MaxHistory>30</MaxHistory>
      <TimeBasedFileNamingAndTriggeringPolicy
          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- Maximum Log File Size -->
        <MaxFileSize>10MB</MaxFileSize>
      </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
 
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>${PATTERN}</pattern>
    </layout>
  </appender>
 
  <!-- Output to debug-->
  <appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <FileNamePattern>${OPEN_FILE_PATH}/debug/zqread.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
      <MaxHistory>30</MaxHistory>
      <TimeBasedFileNamingAndTriggeringPolicy
          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <MaxFileSize>10MB</MaxFileSize>
      </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <append>true</append>
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
      <charset>utf-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter"><!--  Print only DEBUG Journal  -->
      <level>DEBUG</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>
 
  <!-- Output to info-->
  <appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <FileNamePattern>${OPEN_FILE_PATH}/info/zqread.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
      <MaxHistory>30</MaxHistory>
      <TimeBasedFileNamingAndTriggeringPolicy
          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <MaxFileSize>10MB</MaxFileSize>
      </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <append>true</append>
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
      <charset>utf-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter"><!--  Print only INFO Journal  -->
      <level>INFO</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>
 
  <!-- Output to error-->
  <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <FileNamePattern>${OPEN_FILE_PATH}/error/zqread.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
      <MaxHistory>30</MaxHistory>
      <TimeBasedFileNamingAndTriggeringPolicy
          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <MaxFileSize>10MB</MaxFileSize>
      </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <append>true</append>
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
      <charset>utf-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter"><!--  Print only ERROR Journal  -->
      <level>ERROR</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>
 
  <!-- Output to warn-->
  <appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <FileNamePattern>${OPEN_FILE_PATH}/warn/zqread.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
      <MaxHistory>30</MaxHistory>
      <TimeBasedFileNamingAndTriggeringPolicy
          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <MaxFileSize>10MB</MaxFileSize>
      </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <append>true</append>
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
      <charset>utf-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter"><!--  Print only WARN Journal  -->
      <level>WARN</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>
 
  <root level="info">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="OPEN-FILE"/>
    <appender-ref ref="debug" />
    <appender-ref ref="info" />
    <appender-ref ref="error" />
    <appender-ref ref="warn" />
  </root>
</configuration>

Related articles: