首页 > 其他分享 >Logback日志输出配置和使用-要点攻略

Logback日志输出配置和使用-要点攻略

时间:2023-04-27 20:11:31浏览次数:53  
标签:输出 logback appender 攻略 日志 Logback logger 级别

Logback是由log4j创始人设计的另一个开源日志组件,比log4j功能更强大,效率更高。官方网站:http://logback.qos.ch/documentation.html。

本文较为详细地讲述logback的日志输出使用原理、如何配置,并结合具体的代码,给出程序调用的方法。为了讲清原理,本文从log4j的日志级别开讲,然后讲述主配置文件log4j2.xml的配置方法、程序调用方法,并给出一个比较完整的log4j2配置文件。

一、Logback的级别解读

Logback共定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。目前log4j官方推荐的共四个级别:ERROR、WARN、INFO、DEBUG。

OFF-第8级,最高等级,虚拟级别,用于关闭所有日志记录。

FATAL-第7级,不可用的致命级别,已被slf4j弃用,官方解释是和ERROR没有绝对的界限。

ERROR-第6级,可用的错误级别,很常用,推荐级别,用于捕获错误事件。

WARN-第5级,可用的告警级别,用得相对较少但位置很关键,表示潜在的可能错误。

INFO-第4级,可用的信息级别,最常用,推荐级别,用于打出程序的关键信息、阶段性的历程碑信息。

DEBUG-第3级,可用的调试级别,详尽的、可用于程序调试的级别,看日志类似看代码的执行过程。

TRACE-第2级,可用的追踪级别,但一般不建议使用,用于极为详尽的step-by-step日志追踪。

ALL-第1级,最低等级,虚拟级别,用于打开所有日志记录。

二、Logback的配置文件

1 配置文件原理

(1) 配置文件查找顺序

Logback查找配置文件的先后顺序是:

1.logback-test.xml;

2.logback.groovy;

3.logback.xml;

如果上述三个配置文件都没有找到,则使用默认配置打印到控制台。

附上Logback查找配置文件的过程:

20:35:42,642 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
20:35:42,644 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
20:35:42,648 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/F:/Study/workspace/logBackTest/bin/logback.xml]

Logback优先读取测试环境配置,后读取生产环境配置。此外,相比于XML,Groovy风格的配置文件更加直观,当前已有工具支持自动把logback.xml文件迁移至logback.groovy,但当前使用较少,因此本文的讲述,都基于logback.xml。

Logback配置文件中所有的element、属性值、属性名、类名、文件、目录名、PatternLayout的字符串等均区分大小写。

(2) 配置文件基本结构

Logback.xml的基本结构如下所示:

根element为configuration,一个configuration至少要包含一个root和一个appender,logger为可选项,如有需要appender和logger可配置多个。

......
<configuration debug="false" scan="true" scanPeriod="1 seconds">
......
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<filter ......>
		<rollingPolicy
        <encoder ......>
        ......   
	</appender>
    ......
    

    <logger name=......>
     .....
    </loggers>
     ...... 
        
     
     <root ......>
        ......
     </root>
</configuration>   

(3)关于对appender和logger的理解

logger用来收集日志,appender用来输出日志,此外root是一种特殊的logger,所以整体来说,configuration里面配置的其实就是两类内容:appender和logger。

关于对其关系的理解,笔者看到了一个非常好的比喻,即logger是会写字的人,appender是文字的输出或者展现方式,可以理解为黑板、本子等等。logger和appender共同完成的就是:一个人在收集到日志后,根据需要可以将字写在黑板上,也可以将字写在本子上,供给需要的人看。

(4) logback.xml的配置优势

logback.xml配置起来方便灵活,比如某级别日志独立输出、异步日志等,通过调用不同的class即可实现。

2 起始和Configuration总段落

(1) xml起始

起始段落为固定的写法,注意encoding写为UTF-8,!DOCTYPE用以声明文件类型,后续文件类型不区分大小写。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>

(2) Configuration根节点属性

Configuration共有三个属性:

debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

scan:配置是否对配置文件修改进行检测,默认值为true,即:配置文件如果发生改变,将会被重新加载。

scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。

<configuration debug="false" scan="true" scanPeriod="30 seconds">

(3) Properties段落

这个段落主要用于配置Logback的属性,更有用的是配置一些变量,用在后面的appenders段落和loggers段落用${VARIABLE}引用。

这里配置日志存放目录、历史日志存放目录、日志文件切换大小这3个变量。

		<Property name="logDir" value="./logs" />
		<Property name="histLogDir" value="./logs/hist"/>
		<Property name="splitSize" value="1MB" />

3 appenders段落

本段落可包括多个appender,每个appender均代表一种日志输出格式。

每个appender都有两个属性name和class,name用来给当前appender命名,以便logger使用。class用来指定输出策略,常用就是控制台输出策略和文件输出策略,而文件输出策略包括基础的FileAppender,以及基于时间等维度的RollingFileAppender。

如:控制台输出

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

如:滚动日志输出

<appender name="ErrorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">

此外,appender主要包括以下子节点:

  • filter 过滤器,可以自定义拦截器也可以用系统一些定义好的拦截器
  • file &append fileappender策略开启时,用来指明日志文件的输出位置,可以是绝对路径也可以是相对路径
  • encoder 指定具体输出的日志格式
  • rollingPolicy 日志滚动策略
  • triggerPolicy 触发

我们将逐一介绍上述各子节点。

(1)filter

任一输出策略类型的appender均可使用filter,主要分两种,一是级别过滤器,根据日志级别进行输出,一是阈值过滤器,与log4j类似,用以过滤掉低于指定级别的日志。相较log4j,Logback对不同级别日志的过滤方式更为丰富灵活。下面我们来看两种过滤器的范例。

  • 级别过滤器
       <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>info</level>
          <onMatch>ACCEPT</onMatch>   
          <onMismatch>DENY</onMismatch> 
       </filter>

执行结果:

2022-12-17 15:50:57.635 [main] INFO  com.yangchr.sb002.entity.logBackTest 日志输出,INFO 日志---256,托尼

在级别过滤器中,共有三个子element,level用以设置过滤级别,onMatch和onMismatch用以配置满足和不满足过滤条件时的操作,包括ACCEPT、DENY、NEUTRAL。在上面的例子中,onMatch="ACCEPT" onMismatch="DENY"表示,高于等于DEBUG级别的日志给与输出,非INFO级别的日志不予输出。

从这个例子可以看出,Logback在实现单一级别日志输出的时候,相较log4j来说,是非常方便的,仅通过调用级别过滤器即实现了姊妹篇《log4j2日志输出配置和使用-要点攻略》中的专题三内容。

  • 阈值过滤器

阈值处理器中仅一个子element,即level。当日志级别等于或高于临界值level时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志返回DENY。

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

输出结果为:

2022-12-17 16:28:58.185 [main] ERROR com.yangchr.sb002.entity.logBackTest 日志输出,ERROR日志---256,托尼
2022-12-17 16:28:58.185 [main] WARN  com.yangchr.sb002.entity.logBackTest 日志输出,WARN 日志---256,托尼
2022-12-17 16:28:58.185 [main] INFO  com.yangchr.sb002.entity.logBackTest 日志输出,INFO 日志---256,托尼

从上面的例子看出,Logback通过阈值过滤器实现了log4j2中的ThresholdFilter 功能。

(2)file & append

当日志输出策略为fileappend时,用到file & append两个子element。其中file用以指定待写入的文件名,可带绝对或相对路径。append为true时,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。

      <appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
        <file>./FileLog/File.log</file> 
        <append>true</append> 
        <encoder> 
          <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern> 
        </encoder> 
      </appender> 

(3)rollingPolicy

Logback共有三种滚动策略,但与log4j略有不同。Logback中的基础滚动策略不支持onlySizeBased滚动,该策略可通过固定窗口滚动策略+按大小触发滚动间接实现。

特别需说明,logback的rolling不是时间驱动的,而是事件驱动,如果配置按天,不一定是0点0分会触发切分,需要产生日志才会触发是否切分的判断。总结来说,虽迟但到。

三种滚动策略简介如下,调用时仅需指定相对应的class、并配置相应的子element即可。

  • TimeBasedRoolingPolicy 基于时间滚动策略

​ 本策略共有以下三个子element:

​ fileNamePattern:必需的element,可以用来设置指定时间的日志归档。

​ maxHistory:可选element,控制保留的归档文件的最大数量,超出数量就删除旧文件,加入设置为2的话,则除当日日志外,仅保留过去2天内的日志。

​ 特别需要说明的是,经笔者多次尝试,本element需结合cleanHistoryOnStart一起使用。原因为由于logback的时间范围计算策略问题,maxHistory可能不生效。

​ totalSizeCap:(示例未予展示)可选element,用来指定日志文件的上限大小,例如设置为1MB的话,那么当日至总大小到了这个值,就会删除旧的日志

       <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名,不支持%i-->
            <FileNamePattern>${logDir}/info.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>2</MaxHistory>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>

​ 本策略有一点需注意:即TimeBasedRollingPolicy不可与trigger policy中的SizeBasedTriggeringPolicy共同使用,该需求可通过后续要讲的SizeAndTimeBasedRollingPolicy实现。

  • SizeAndTimeBasedRollingPolicy基于大小和时间的滚动策略

​ 本策略同时基于时间和文件大小进行滚动,子element也比较简单。

       <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名,日期必须加,如果单天需要生成多个日志,则需要添加%i-->
            <FileNamePattern>${logDir}/error.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
            <!--历史日志文件保留天数,不包含当日日志,且需结合cleanHistoryOnStart字段使用-->
            <!--可以按“文件数量、小时、天、月、年”等策略实现文件保留 -->
            <MaxHistory>3</MaxHistory>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!-- 单天单个日志最大size -->
            <maxFileSize>1MB</maxFileSize>
            <!--仅针对当天的日志进行总size控制,日志名中的“i”保留最后数值 -->
            <totalSizeCap>10MB</totalSizeCap>    
        </rollingPolicy>

上述示例中的配置表示:单个日志最大1MB,总日志最大10MB(即最多保留九或十个日志文件),日志日期最多保留过去3天。

注:每天生成的多个文件,根据大小滚动起来后,其文件名后缀的%i不断累加,在上例中仅保留最后9个文件。

即:

image-20230129213815100
  • Fixed Window Rolling Policy 固定窗口的滚动策略

    本策略element主要有两个:minIndex和maxIndex用以明确窗口索引的最大最小值,如这两个值分别设置为1和3,即该日志最多归档文件为3个。

    本策略使用场景较少,一般结合triggeringPolicy来使用,示例如下:

     <file>${logDir}/debug.log</file>
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
          <fileNamePattern>${logDir}/debug.%i.log</fileNamePattern>
          <minIndex>1</minIndex>
          <maxIndex>3</maxIndex>
     </rollingPolicy>
     <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
     </encoder>
     <!--日志文件最大的大小-->
     <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
          <MaxFileSize>10MB</MaxFileSize>
          </triggeringPolicy>
     </appender>
    

    本策略配合triggeringPolicy,实现了log4j中的onlySizeRollingPolicy。上述示例配置表示:单个日志文件通过triggeringPolicy超过1OMB时触发滚动,历史日志滚动最小保留1个文件,最多保留3个文件。示例结果为:

    image-20230129221935535

(4)encoder

Logback自0.9.19版本开始支持encoder。encoder 用于将日志信息转为字节数组,并将字节数据写入到输入流。除了个别appender已经内置了日志格式,每个appender中都必须有一个encoder,其属性class最常用的值为:

ch.qos.logback.classic.encoder.PatternLayoutEncoder

唯一一个子element即pattern。先看下述示例:

        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
        </encoder>

pattern格式详见后续专题一。

4 loggers段落

loggers段落负责将日志按照指定级别过滤,并输出到指定预定义好的Appender中。

在loggers段落中,包括必须有的root段和可选的logger,如果没有root端,将会默认不过滤日志并将日志输出到控制台。此外非常重要的是,root是一种特殊的logger。继续使用前面的比喻,logger可以有多个,就是有多个会写字的人。logger默认的打印级别是继承root的,如果它不想继承,想自立门户的话,就自行设置level;若不愿和root打重复日志,则需加上additivity=false,这是非常重要的配置技巧。

logger示例如下

    <logger name="com.yangchr.sb002.entity" level="INFO" additivity="false">
    <appender-ref ref="Console" />
    <appender-ref ref="RollingFileError" />
    <appender-ref ref="RollingFileInfo" />
    <appender-ref ref="RollingFileDebug" />
    <appender-ref ref="RollingFileYCR" />
    </logger>

    <!-- 日志输出级别 -->
    <root level="TRACE">
        <appender-ref ref="Console" />
    	<appender-ref ref="RollingFileError" />
   	 	<appender-ref ref="RollingFileInfo" />
    	<appender-ref ref="RollingFileDebug" />
    </root>

三、程序调用Logback

目前流行的logback、log4j2,都是基于slf4j的实现,这里给出使用logback实现slf4j的代码和相关配置。

1 原生代码调用Logback

Logback调用共需3个jar包:

logback-classic-1.2.3.jar

logback-core-1.2.3.jar

slf4j-api-1.7.26.jar

2 代码中定义slf4j的logger

给出本攻略中一直在用的代码:

package com.yangchr.sb002.entity;

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

public class logBackTest {
		
		private Integer empID;
		private String empName;
		private static final Logger logger = LoggerFactory.getLogger(logBackTest.class);
		
		public logBackTest(Integer empID, String empName) {
			this.empID = empID;
			this.empName = empName;
		}
			
		@Override()
		public String toString() {
			return (this.empID +","+this.empName);
		}
		
		public void print(String output) {
			logger.error("日志输出,ERROR日志---{}", output);
			logger.warn ("日志输出,WARN 日志---{}", output);
			logger.info ("日志输出,INFO 日志---{}", output);
			logger.debug("日志输出,DEBUG日志---{}", output);
			logger.trace("日志输出,TRACE日志---{}", output);
		}
		
		public static void main(String[] args) {
			logBackTest employee = new logBackTest(256, "托尼");
			employee.print(employee.toString());
		}
}

四、一个完整的logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>

<configuration debug="true" scan="true" scanPeriod="30 seconds">
    	<!--定义日志文件的存储地址 -->
		<Property name="logDir" value="./logs" />
		<Property name="histLogDir" value="./logs/hist"/>
		<Property name="splitSize" value="1MB" />

    <!--appender01 控制台日志, 控制台输出 -->
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%logger:显示类名 %msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{10} %msg%n</pattern>
        </encoder>
    </appender>

    <!--appender02 日志输出,非滚动,每次新日志均追加到同一文件 -->
   <appender name="ALLLog" class="ch.qos.logback.core.FileAppender"> 
      <file>${logDir}/allinone.log</file> 
      <append>true</append> 
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
        	<level>error</level>
          	<onMatch>ACCEPT</onMatch>   
          	<onMismatch>DENY</onMismatch>  
       	</filter>
      <encoder> 
         <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern> 
      </encoder> 
   </appender> 

    <!--appender03 根据大小和时间策略的滚动日志输出,Error及以上级别输出 -->
    <appender name="RollingFileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        	<level>error</level>
        </filter>
		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名,日期必须加,如果单天需要生成多个日志,则需要添加%i-->
            <FileNamePattern>${logDir}/error.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
            <!--历史日志文件保留天数,不包含当日日志,且需结合cleanHistoryOnStart字段使用-->
            <!--可以按“文件数量、小时、天、月、年”等策略实现文件保留 -->
            <MaxHistory>3</MaxHistory>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!-- 单天单个日志最大size -->
            <maxFileSize>1MB</maxFileSize>
            <!--仅针对当天的日志进行总size控制,日志名中的“i”保留最后数值 -->
            <totalSizeCap>10MB</totalSizeCap>    
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%logger:显示类名 %msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
    </appender>

    <!--appender04 根据时间滚动策略的日志输出,Info及以上级别输出 -->    
    <appender name="RollingFileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        	<level>info</level>
        </filter>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名,不支持%i-->
            <FileNamePattern>${logDir}/info.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>2</MaxHistory>
            <totalSizeCap>1MB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%logger:显示类名 %msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
        </encoder>
    </appender>
 
     <!--appender05 固定窗口滚动策略的日志输出,Debug及以上级别输出 -->       
    <appender name="RollingFileDebug" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        	<level>debug</level>
        </filter>
        <file>${logDir}/debug.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${logDir}/debug.%i.log</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>3</maxIndex>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%logger:显示类名 %msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    

    <logger name="com.yangchr.sb002.entity" level="DEBUG" additivity="false">
    <appender-ref ref="Console" />
    <appender-ref ref="RollingFileError" />
    <appender-ref ref="RollingFileInfo" />
    <appender-ref ref="RollingFileDebug" />
    </logger>

    <!-- 日志输出级别 -->
    <root level="TRACE">
        <appender-ref ref="Console" />
    	<appender-ref ref="RollingFileError" />
   	 	<appender-ref ref="RollingFileInfo" />
    	<appender-ref ref="RollingFileDebug" />
    </root>
    
</configuration>

专题一、PatternLayout格式说明

对PatternLayout中,pattern属性做出参数说明。PatternLayout将决定每一行日志打出的内容和格式,对于让日志清晰可读有着重要作用。在实际使用中,应注意日志行打印内容的长度和内容全面性的关系,适当控制长度,对于日志的可读性,有很大的帮助。

%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

(a)%d %date,输出日期和时间,{}中可以格式化,一般配置为yyyy-MM-dd HH:mm:ss.SSS即可。

(b)%t %thread,输出产生日志的线程名。若要限制线程编号的字符长度,可在%和t之间做位数限制。例如正常输出是[main],经过配置可有以下变化。

编号 写法 输出 说明
1 [%t] [main] 标准输出,输出线程完整的名字
2 [%3t] [main] 从右算起,最少输出三个字符,多了不限,由于main是四个字符,因此全部输出
3 [%8t] [ main] 从右算起,最少输出八个字符,多了不限,于是出现左边补空格
4 [%-3t] [main] 从左算起,最少输出三个字符,由于main是四个字符,因此全部输出
5 [%.3t] [ain] 从右算起,最多输出三个字符,其余被截掉
6 [%.8t] [main] 从右算起,最多输出8个字符,其余被截掉,由于main只有四个字符,因此全部输出
7 [%5.8t] [ main] 从右算起,最少输出5个字符,最多输出8个字符,<5则左补空格,>8则左边的截断
8 [%2.3t] [ain] 从右算起,最少输出2个字符,最多输出3个字符,<2则左补空格,>3则左边的截断
9 [%2.2t] [in] 从右算起,固定输出2个字符,即<=2且>=2,那么就是=2,不足2个左补空格,多余2个左边截断
10 [%-2.3t] [ain] 从左算起,最少输出2个字符,最多输出3个字符,<2则右补空格,>3则左边的截断
11 [%-2.3t] [mai] 从左算起,最少输出2个字符,最多输出3个字符,<2则右补空格,>3则右边的截断
12 [%-2.-8t] [main] 从左算起,最少输出2个字符,最多输出8个字符,<2则右补空格,>8则右边的截断
13 [%-8.-8t] [main ] 从左算起,固定输出8个字符,<8右边补空格,>8右边的截断

(c)%level %p %le 输出日志的级别(priority),这个是一定要有的。%-5level的写法,表示最少输出5个字符,多了不限,不足5个右补空格。再次观察从高到低ERROR、WARN、INFO、DEBUG、TRACE五个级别,不是4个字符就是5个,这样就使得在日志级别这里又可以做到对齐了。

(d)%logger %lo 输出日志的类名

编号 写法 输出 说明
1 %logger com.yangchr.sb002.entity 输出完整的类名
2 %logger entity 只输出logger最右边点符号.之后的字符串
3 %logger c.y.s.entity entity为6字符,已经超过5,所以类名最后一个单词原样展示,之前的包路径首字母缩写展示。最后一个单词永远不会被缩写。
4 %logger c.y.s.entity entity为6字符,sb002为5字符,仅二者相加就超过10,因此最后输出效果与%logger{5}一致
5 %logger c.y.sb002.entity 最多输出17个字符(符号.也算一个字符)
6 %logger c.yangchr.sb002.entity 最多输出23个字符
7 %logger com.yangchr.sb002.entity 最多输出26个字符
8 %logger com.yangchr.sb002.entity logger名最大占用的字符位数为50,写50通常为了类名过长时显全类名

​ 综上,具体类名永远不会缩写,然后根据%logger中指定的字符串长度,包名从第一个开始进行首字母缩写,直到所有包名完成缩写。

(e)%msg %message %m 输出的日志信息

(f)%n 换行符

(g)%F %file 输出发出日志请求的 Java 源文件的名字。尽量避免使用,除非执行速度不造成任何问题。

(h)%L 输出执行日志请求的行号。尽量避免使用,除非执行速度不造成任何问题。

(i)%replace(p ){r, t} p 为日志内容,r 是正则表达式,将p 中符合r 的内容替换为t 。
例如, "%replace(%msg){'\s', ''}"

专题二、Rollover策略

RollingFileAppender扩展了FileAppender的功能,可以滚动生成历史日志。

比如:RollingFileAppender类负责将日志输出到 log.txt 文件,在满足了特定的条件之后,将日志输出到log1.txt文件。

与RollingFileAppender交互的两个重要的子组件 :

RollingPolicy:执行日志滚动的具体操作,比如文件移动、重命名。

TriggeringPolicy:确定是否以及何时触发日志的滚动策略。

也就是说,RollingPolicy负责what,TriggeringPolicy负责when。

为了发挥作用,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,如果RollingPolicy实现了TriggeringPolicy接口,则仅需配置RollingPolicy。

TimeBasedRollingPolicy基于时间滚动策略

因为TimeBasedRollingPolicy实现了TriggeringPolicy接口,所以我们使用的时候只需要配置rollingPolicy节点,不需要配置TriggeringPolicy。

TimeBasedRollingPolicy的参数如下:

fileNamePattern:定义历史日志的名称、保存格式(txt、gz)

maxHistory:设置历史日志的保存时间(超时的删除)默认设置为0,表示不会删除。

totalSizeCap :历史日志的总大小。当文件超过总大小上限时,最早的历史日志将被异步删除。默认设置为0,表示历史日志大小无限制。

cleanHistoryOnStart:如果设置为 true,则在appender运行时会将历史日志删除。默认设置为 false。

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${logDir}/debug.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

上面的error日志将会保留30天,超过30天的文件将删除。同时,下面还设置了triggeringPolicy,MaxFileSize为10MB,文件大小达到10MB的时候也会触发滚动,比如在测试阶段这个error日志特别庞大,一天之内就能达到10MB,那么因为这个设置就会提前触发滚动。但是由于FileNamePattern中缺少 %i 参数,滚动之后的文件名与当前日志文件名无法进行区分,因此笔者认为这里的triggeringPolicy是不生效的。

maxHistory的值与fileNamePattern设置的格式有关,如果保存格式为yyyyMMddHHmm,那maxHistory的时间单位就是分钟,如果保存格式为yyyyMMdd,那maxHistory的时间单位就是天。但是,有些应用程序的生存时间太短,短到不足以触发日志滚动策略。对于这样的应用程序,历史日志的删除可能永远不会有执行的机会。可以通过将 cleanHistoryOnStart 设置为 true,在appender启动时删除历史日志。

TimeBasedRollingPolicy支持自动文件压缩。如果 fileNamePattern 的参数以.gz 或 .zip 结尾,则会启用此功能。

日志的滚动不是由时钟触发,而是需要日志写入动作来触发。假设2022年12月18日 fileNamePattern 设置为yyyy-MM-dd 日志按天滚动,则滚动会发生在0点后第一个日志写入时,比如在00:23:47写入第一个event,那么日志会在 2022 年 12 月 19日 00:23:47进行滚动,而不是2022 年 12月 19日 00:00:00。

SizeAndTimeBasedRollingPolicy基于时间和文件大小的滚动策略

前面的TimeBasedRollingPolicy已经可以限制历史日志文件的时间和总文件的大小,如果需要限制每个文件的大小可以用SizeAndTimeBasedRollingPolicy

官网没有说SizeAndTimeBasedRollingPolicy是否实现了TriggeringPolicy接口,但从官网给出例子中看并没有配置TriggeringPolicy,况且TriggeringPolicy仅支持一个参数MaxFileSize,很明显基于时间和文件大小的RollingPolicy自己就可以触发,因此无需配置TriggeringPolicy。

官网示例:

<configuration>
  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>mylog.%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
       <!-- 每个文件最大 100MB, 最多保存60天 ,总的大小不超过20GB -->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>60</maxHistory>
       <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="ROLLING" />
  </root>
 
</configuration>

在这里%i 和%d 标记都是必需的参数,如果单个文件在当前时间段结束之前达到 maxFileSize,i 就会以从 0 开始的递增索引对日志文件进行归档如下:

mylog.2022-12-19.0.txt、mylog.2022-12-19.1.txt、mylog.2022-12-19.2.txt......

在这里,如果应用程序意外停止或重新启动时,仍会在程序停止时的日志文件中继续打印日志,也就是目录中索引号i最大的文件。

专题三、输出异步日志AsyncAppender

logback的异步日志输出很简单,在原有配置基础上添加一个基于异步写日志的appender,即AsyncAppender,并指向原先配置的appender即可。

AsyncAppender并不处理日志,只是将日志缓冲到一个BlockingQueue里面去,并在内部创建一个工作线程从队列头部获取日志,之后将获取的日志循环记录到附加的其他appender上去,从而达到不阻塞主线程的效果。因此AsynAppender仅仅充当事件转发器,必须引用另一个appender来做事。
默认情况下,AsyncAppender会在队列满80%的情况下删除TRACE、DEBUG和INFO级别的事件。这种策略以事件损失为代价,对性能却有很大的提升。

<!--异步输出 appender-->
    <appender name="ASYNC-TRACE" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 队列剩余容量小于discardingThreshold,则会丢弃TRACT、DEBUG、INFO级别的日志;默认值-1,为queueSize的20%;0表示不丢失日志 -->
        <discardingThreshold>-1</discardingThreshold>
        <!-- 队列满了,是否阻塞,默认为false;如果配置为true,则队列满了就丢弃日志; -->
        <neverBlock>true</neverBlock>
        <!-- 队列的最大容量,该值会影响性能.默认值为256 -->
       <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="TraceFile"/>
    </appender>

    <appender name="ASYNC-ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <neverBlock>true</neverBlock>
       <queueSize>256</queueSize>
        <appender-ref ref="ErrorFile"/>
    </appender>

    <appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <neverBlock>true</neverBlock>
       <queueSize>256</queueSize>
        <appender-ref ref="InfoFile"/>
    </appender>

标签:输出,logback,appender,攻略,日志,Logback,logger,级别
From: https://www.cnblogs.com/ycr1125/p/17360092.html

相关文章

  • jeecgboot启动时日志打印所有接口,作为开发时的参考作用吧。
    主要的方式是使用了RequestMappingHandlerMapping这个bean当中保存了所有的映射、对应的controller类、方法等等的信息。在单体启动类中取出这个bean然后遍历就可以了,代码如下:/***单体启动类(采用此类启动为单体模式)*/@Slf4j@SpringBootApplicationpublicclassJeecgSyste......
  • SpringBoot配置日志文件定期切割
    下面是我的配置:创建logback-spring.xml写入下面的配置<?xmlversion="1.0"encoding="UTF-8"?><configurationdebug="false"><!--定义日志文件的存储地址勿在LogBack的配置中使用相对路径--><propertyname="LOG_HOME"value=&quo......
  • Kivy中的Logger组件用于记录应用程序的日志信息
    name:可选参数,指定Logger组件的名称。默认为root。level:可选参数,指定Logger组件的记录级别。默认为debug。propagate:可选参数,指定是否向父Logger组件传递记录消息。默认为True。handlers:可选参数,指定Logger组件的处理程序。默认为None。disabled:可......
  • 隧道全幅表观产品开发日志(一)旧版软件的修改日志
    好久没写博客了,上一次写还是在上一家公司现在在的这家公司目前做的是隧道内的探伤项目,我现在主要的工作是做工控机,也就是控制各种硬件组织作业。目前的产品架构见https://github.com/LeventureQys/South_Gathering_Doc中多设备采集软件相关内容,这篇文章仅是记录旧版软件的修改......
  • nginx日志切割
    手动#!/bin/bashLOG_PATH="/var/log/nginx/"RECORD_TIME=$(date-d"yesterday"+%Y-%m-%d+%H:%H:%M)PID=/var/run/nginx/nginx.pidmv${LOG_PATH}/access.log${LOG_PATH}/access.${RECORD_TIME}.logmv${LOG_PATH}/error.log${LOG_PATH}/error.${R......
  • 系统日志管理审核
    系统日志管理系统日志记录协议(syslog)旨在标准化网络设备用于与日志服务器通信的消息格式。网络上的路由器、交换机、防火墙和Unix/Linux服务器等许多设备都支持它,从而更轻松地管理这些设备生成的日志。系统日志监控和管理对于每个组织减少系统停机时间、提高网络性能和加强企业......
  • python subprocess Popen非阻塞,读取adb日志
    简单版fromthreadingimportThreadfromqueueimportQueue,Emptyimportshlexif__name__=='__main__':print_hi('PyCharm')#Car().run()defenqueue_output(stdout,queue):withopen("www.log",'w......
  • go之logrus自定义日志样式
    日志功能配置:logrus.gopackagecoreimport("bytes""fmt""github.com/sirupsen/logrus""io""os""path")const(red=31yellow=33blue=36gray......
  • chatgpt代写---王者荣耀赵怀真攻略
    王者荣耀是一款备受欢迎的手机游戏,其中赵怀真作为一个高机动性、控制能力和输出能力出色的英雄备受玩家喜爱。在游戏中,玩家可以通过四个主要的技能来使用赵怀真打造自己的强力操作。首先是"four",这是赵怀真最重要的技能之一。四次蓄力攻击可以协助赵怀真进行快速高伤害打击。对......
  • 监控自建MySQL慢查询日志并上报到企业微信集群
    shell脚本如下#!/bin/bash#设置企业微信机器人webhook地址和机器人名称WEBHOOK_URL="你的WEBHOOK_URL"BOT_NAME="MySQLSlowLogBot"#设置慢日志文件路径和记录已发送行数的文件路径LOG_FILE="/data/mysql/mysql-slow-log.log"SENT_LINE_FILE="/tmp/mysql-slow-log.sent......