• logback(二)springboot配置日志文件格式、logback-spring配置文件详解


    参考官网直达车

    logback(一)理论概述
    logback(二)springboot配置日志文件格式、logback-spring配置文件详解
    logback(三)mybatis-plus结合logback将sql语句输出到日志文件

    一 springboot自带的的格式

    首先看一下,我们启动springboot项目默认会出现如下格式
    在这里插入图片描述

    当我们输出一行日志时,会打印如下日志

    Logger logger = LoggerFactory.getLogger(当前类名字.class);
    log.info("哈哈哈");
    
    // 输出如下
    2022-06-16 10:36:53.829  INFO 28492 --- [           main] c.c.s.w.u.a.Test     : 哈哈哈
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这个时候发现“哈哈哈”不知道是那个方法、哪行,我们就可以按照自己想要的格式来修改日志输出格式

    二 自定义logback配置

    下面这个配置是可以直接使用的
    logback-spring.xml文件,放到resource下面

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
        <!--日志文件的存储路径-->
        <springProperty scope="context" name="logPath" source="logging.file.path"/>
    
        <!--日志输出格式-->
        <property name="logPattern" value="%d %-5level PID=${PID:- } [%-20thread] %-40.40logger{40} [line = %-5line] [method = %-20.20method]: %msg%n"/>
    
        <!-- 控制台输出 -->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>${logPattern}</pattern>
            </encoder>
        </appender>
    
        <!-- info信息输出到文件 -->
        <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <encoder>
                <pattern>${logPattern}</pattern>
            </encoder>
    
            <file>${logPath}/sys-info.${hostname}.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${logPath}/sys-info.%d{yyyy-MM-dd}.${hostname}.log</fileNamePattern>
                <!-- 将30天的历史记录的总大小限制在3GB  -->
                <maxHistory>30</maxHistory>
                <totalSizeCap>3GB</totalSizeCap>
            </rollingPolicy>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <!-- error信息输出到文件 -->
        <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <encoder>
                <pattern>${logPattern}</pattern>
            </encoder>
    
            <file>${logPath}/sys-error.${hostname}.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${logPath}/sys-error.%d{yyyy-MM-dd}.${hostname}.log</fileNamePattern>
                <maxHistory>30</maxHistory>
                <totalSizeCap>3GB</totalSizeCap>
            </rollingPolicy>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!-- 过滤的级别 -->
                <level>ERROR</level>
                <!-- 匹配时的操作:接收(记录) -->
                <onMatch>ACCEPT</onMatch>
                <!-- 不匹配时的操作:拒绝(不记录) -->
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
    	<!-- debug及以上级别的信息【可以包括sql信息】输出到文件 TODO 不需要可以自行删除 -->
        <appender name="file_debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <encoder>
                <pattern>${logPattern}</pattern>
            </encoder>
    
            <file>${logPath}/sys-debug.${hostname}.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${logPath}/sys-debug.%d{yyyy-MM-dd}.${hostname}.log</fileNamePattern>
                <maxHistory>7</maxHistory>
            </rollingPolicy>
        </appender>
    
        <!--将mybatis-plus的sql记录的日志文件 TODO name改成自己的项目的mapper包路径-->
        <logger name="com.fox.test.mapper" level="debug" />
        
        <!--将appender都加入到root根标签-->
        <root level="info">
            <appender-ref ref="console"/>
            <appender-ref ref="file_info"/>
            <appender-ref ref="file_error"/>
            <appender-ref ref="file_debug"/>
        </root>
    
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    置文件的最基本结构可以描述为<configuration>元素,包含零个或多个<appender>元素,然后是零个或多个<logger>元素,最多包含一个<root>元素。下图说明了此基本结构。
    
    • 1

    在这里插入图片描述

    从 Logback 版本 0.9.17 开始,与显式规则有关的标记名称不区分大小写。例如,<logger>,<Logger>和<LOGGER>是有效的配置元素
    
    • 1

    三 配置详细讲解

    1 configuration标签,这个没啥讲的,根标签

    2 springProperty标签,作用:配置日志文件的存储路径的

    <springProperty scope="context" name="logPath" source="logging.file.path"/>
    
    • 1
    属性名字描述
    scope作用域(设置属性的范围,例local(默认)、context、system)
    name名字(一般作为当前文件的一个变量名字)
    source日志文件存放路径
    • scope
    <property>元素,<define>元素(动态定义属性名)或<insertFromJNDI>元素的 scope 属性可用于设置属性的范围。
    
    • 1
    1. local 从配置文件中定义其属性的位置到该配置文件的解释/执行结束为止,都存在具有本地范围的属性。因此,每次解析和执行配置文件时,都会重新定义本地作用域中的变量。

    2. context 具有上下文范围的属性被插入到上下文中,并且持续时间与上下文一样长,直到被清除为止。一旦定义,上下文范围内的属性就是上下文的一部分。这样,它在所有日志记录事件中都可用,包括那些通过序列化发送到远程主机的事件。

    3. system 具有系统范围的属性被插入 JVM 的系统属性中,并且持续时间与 JVM 一样长,或者直到被清除为止。

    • name 是将配置文件的路径作为当前文件的一个变量,然后用${logPath}来引用(面向对象思想,一样的东西尽量写一份)

    • source 的值logging.file.path是读取了yml文件的配置,可以分环境配置不同路径
      我的yml配置

    logging:
      file:
        path: /mnt/logs/fox/test
    
    • 1
    • 2
    • 3

    3 property标签,作用:定义变量的

    比如我们定义一个日志打印格式的变量

    <property name="logPattern" value="%d %-5level PID=${PID:- } [%thread] %-40.40logger{40} [line = %-5line] [method = %-20.20method]: %msg%n"/>
    
    • 1
    属性名字描述
    name变量名字
    value变量的值

    这里详细介绍一下value里面的含义,以%开头为占位符,是logback自带的格式,输出日志时可以对应填充进去。

    其他字符一般是普通的字符:例[]、空格

    • %d 日期时间,也可以自定义格式%d{yyyy-MM-dd HH:mm:ss.SSS},大括号里面的格式只要是正常的计算机日期格式即可
    • %method 方法名字,或者%M
    • %level 日志级别,或者%-5level或者
    • ${PID:- } 进程号,或者 $PID
    • %thread 线程名字,或者%t
    • %logger{40} 包名字符个数,会在长度为40的空间尽可能显示较全的类名,太长会保留首字母并用点号分割
    • %line 行号,或者%L
    • %msg 消息,或者%m或者%message
    • %n 换行
    • %c类的完整名称
    • %-40.40logger{40} 其中的“-”表示左对齐,不够40个字符给右侧补空格。".40“表示超过40个字符的情况下从左侧切断。{40}表示输出字符最长40个字符,否则按照句点分割。其他同理

    4 appender标签,作用:日志输出源

    结构图如下
    在这里插入图片描述

     <appender name="file_info" class="ch.qos.logback.core.ConsoleAppender"></appender>
    
    • 1
    属性名字描述
    name输出源名字(自定义)
    classlogback的一种输出源的class路径

    class的值,常用的前两种,其他了解

    1. 控制台输出源(默认)ch.qos.logback.core.ConsoleAppender
    2. 滚动文件输出源ch.qos.logback.core.rolling.RollingFileAppender
    3. SocketAppender and SSLSocketAppender
    4. SMTPAppender
    5. ServerSocketAppender and SSLServerSocketAppender
    6. DBAppender
    7. SyslogAppender
    8. SiftingAppender
    9. AsyncAppender

    4.1 encoder标签、pattern标签,一般一起用。作用:编码器格式

    ${}是引用当前文件里面的property 标签的name属性,其实就是引用一个名字为logPattern的变量

    <encoder>
        <pattern>${logPattern}</pattern>
    </encoder>
    
    • 1
    • 2
    • 3

    4.2 file标签,作用:日志文件的绝对路径和名字

    <file>${logPath}/sys-info.${hostname}.log</file>
    
    • 1

    ${hostname}是获取当前计算机的登录名字,我谁便写了个xiaobai

    4.3 rollingPolicy标签,作用:日志文件的滚动策略(核心)

    class的值:前两种常用。其他了解即可(不是简单的换个class就行啊,还有一些特殊的标签需要加的啊,这里不做赘述了,感兴趣的宝宝们可以去官网学习)

    4.3.1 按日期滚动ch.qos.logback.core.rolling.TimeBasedRollingPolicy
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    	<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.${hostname}.log</fileNamePattern>
    	<!-- 将30天的历史记录的总大小限制在3GB  -->
    	<maxHistory>30</maxHistory>
    	<totalSizeCap>3GB</totalSizeCap>
    	<cleanHistoryOnStart>false</cleanHistoryOnStart>
    </rollingPolicy>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    里面的具体标签属性

    属性名字描述
    fileNamePattern日志文件名字格式(下面介绍它和file的区别)
    maxHistory保留日志历史记录天数
    totalSizeCap日志大小限制
    cleanHistoryOnStart是否删除日志(默认false)一般情况用不到
    • fileNamePattern
      通过设置包含fileNamePattern的文件属性,可以将活动日志文件的位置与归档日志文件的位置解耦。 当前日志将始终以file属性指定的文件为目标。 因此,当前活动日志文件的名称不会随时间而改变。
      这句话可能很难理解,我解释一下,你就会豁然开朗
      日志是如何反转、滚动、归档的呢?下面的案例必须看

      仔细对比你会发现fileNamePattern的值比file的值多了一个%d{yyyy-MM-dd},也就是当天的年月日
      启动项目,谁便打印几行日志(假设日志目录是空的)
      他的文件是这样滚动的
    日期当天日志文件名字描述
    2022年6月22日sys-info.xiaobai.log生成一个日志文件记录当天日志
    2022年6月23日sys-info.xiaobai.log将22日的sys-info.xiaobai.log改名为sys-info.2022-06-22.xiaobai.log。再生成一个今天的sys-info.xiaobai.log文件
    2022年6月24日sys-info.xiaobai.log将23日的sys-info.xiaobai.log改名为sys-info.2022-06-23.xiaobai.log。再生成一个今天的sys-info.xiaobai.log文件
    2022年6月27日sys-info.xiaobai.log将24日的sys-info.xiaobai.log改名为sys-info.2022-06-24.xiaobai.log。再生成一个今天的sys-info.xiaobai.log文件

    假如隔了3天没有日志文件,当27日有日志文件后,修改的上一个日志文件并不一定是昨天的

    • cleanHistoryOnStart如果设置为true,将在appender启动时执行删除历史日志。 默认情况下,该属性设置为false。
      历史日志删除通常在滚转期间执行。 但是,一些应用程序的存活时间可能不够长,无法触发滚转。 因此,对于这种短命的应用程序,归档删除可能永远没有机会执行。 通过将cleanHistoryOnStart设置为true,归档删除将在appender启动时执行。

    • 这个地方说明一下,文件夹是不能动态获取当前日期的,即便官网给了方案,


    4.3.2 基于大小和时间的滚动策略ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy
    	<file>sys-info.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    		<fileNamePattern>sys-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
    		<!-- 每个文件应该不超过100MB,保留60天的历史记录,总大小不超过20GB  -->
    		<maxFileSize>100MB</maxFileSize>    
    		<maxHistory>60</maxHistory>
    		<totalSizeCap>20GB</totalSizeCap>
    	</rollingPolicy>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意除了“%d”之外还有“%i”转换标记。 %i和%d标记都是必须的。 在当前时间段结束之前,每当当前日志文件达到maxFileSize时,它将以递增的索引进行归档,从0开始。

    基于大小和时间的归档支持删除旧的归档文件。 您需要指定使用maxHistory属性保留的周期数。 当您的应用程序停止并重新启动时,日志记录将在正确的位置继续,即当前期间的最大索引号。

    例如

    • 22日生成240MB的日志,会出现三个文件:
      sys-info.2022-06-23.0.log 100多MB
      sys-info.2022-06-23.1.log 100多MB
      sys-info.log 不到40MB

    • 23日生成30MB的文件
      sys-info.log 30MB
      而且会把上一个文件的日期修改为它当天的日期比如:sys-info.log 40MB改为sys-info.2022-06-23.2.log 40MB

    • 以此类推

    这里解释一下为什么是100多MB和不到40MB,日志记录的时候是写入到文件的,假如第一个文件到了99MB,这个时候写入一个5MB的日志,它不会说第一个文件写入1MB,第二个文件写入4MB,这样太麻烦了。所以呢就一次性写完,当文件超过100MB就增加一个新的文件。到最后总大小可能就不够40MB了,所以是不到40MB
    4.3.3 固定窗口滚动策略ch.qos.logback.core.rolling.FixedWindowRollingPolicy
    	
    	<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
    		<fileNamePattern>tests.%i.log.zip</fileNamePattern>
    		<minIndex>1</minIndex>
    		<maxIndex>3</maxIndex>
    	</rollingPolicy>
    
    	<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    		<maxFileSize>5MB</maxFileSize>
    	</triggeringPolicy>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    属性名字描述
    minIndex窗口索引的下界
    maxIndex窗口索引的上界

    SizeBasedTriggeringPolicy查看当前活动文件的大小。 如果它大于指定的大小,它将通知所属的RollingFileAppender触发现有活动文件的翻转。

    SizeBasedTriggeringPolicy只接受一个参数,即maxFileSize,默认值为10 MB。

    maxFileSize选项可以通过在数值后面分别加上KB、MB和GB来指定字节、千字节、兆字节或千兆字节。 例如,5000000、5000KB、5MB和2GB都是有效值,前三个值是等价的。

    下面是一个示例配置,在日志文件达到5MB大小时,RollingFileAppender与SizeBasedTriggeringPolicy一起触发翻转。

    %i是必须的

    由于固定窗口滚动策略需要和窗口大小一样多的文件重命名操作,因此强烈建议使用大窗口大小。 当用户指定较大的值时,当前实现将自动将窗口大小减少到20。

    让我们来看一个关于固定窗口翻转策略的更具体的示例。 假设minIndex设置1,maxIndex设置为3,filenampattern属性设置为foo%i.log,file属性设置为foo.log。

    翻转次数活跃的输出目标归档日志文件描述
    0foo.log还没有发生翻身,日志返回记录到初始文件中。
    1foo.logfoo1.log第一次翻转。 Foo.log被重命名为Foo1.log。 一个新的foo.log文件被创建并成为活动输出目标。
    2foo.logfoo1.log, foo2.log第二个翻转。 foo1.log被重命名为foo2.log。 foo.log被重命名为foo1.log。 一个新的foo.log文件被创建并成为活动输出目标。
    3foo.logfoo1.log, foo2.log, foo3.log第三个翻转。 foo2.log被重命名为foo3.log。 foo1.log被重命名为foo2.log。 foo.log被重命名为foo1.log。 一个新的foo.log文件被创建并成为活动输出目标。
    4foo.logfoo1.log, foo2.log, foo3.log在这几轮和随后几轮中,翻转从删除foo3.log开始。 其他文件可以通过增加索引来重命名,如前面步骤所示。 在这次和后续的翻转中,将有三个归档日志和一个活动日志文件。

    下面的表格是我最后的倔强

    在这里插入图片描述

    4.4 filter标签,作用:

    常规的 logback-classic 过滤器扩展了Filter抽象类,该类基本上由一个以ILoggingEvent实例作为参数的decide()方法组成。

    过滤器被组织成一个有序列表,并基于三元逻辑。依次调用每个过滤器的decide(ILoggingEvent event)方法。此方法返回FilterReply枚举值之一,即DENY,NEUTRAL或ACCEPT之一。

    • 如果decide()返回的值为DENY(否认拒绝),则立即丢弃日志事件,而无需咨询其余过滤器。
    • 如果返回的值为NEUTRAL(中立的),则查询列表中的下一个过滤器。如果没有其他过滤器可参考,则将正常处理日志记录事件。
    • 如果返回的值为ACCEPT(接受同意),则将立即跳过其余过滤器的调用来处理日志记录事件。

    在经典的 logback 模式中,可以将过滤器添加到Appender个实例。通过将一个或多个过滤器添加到附加程序,可以按任意条件过滤事件,例如日志消息的内容,MDC 的内容,一天中的时间或日志事件的任何其他部分。

    前两种常用,其他了解

    4.4.1 级别过滤器LevelFilter
    		<filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!-- 过滤的级别 -->
                <level>INFO</level>
                <!-- 匹配时的操作:接收(记录) -->
                <onMatch>ACCEPT</onMatch>
                <!-- 不匹配时的操作:拒绝(不记录) -->
                <onMismatch>DENY</onMismatch>
            </filter>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    属性名字描述
    level过滤的级别
    onMatch匹配时的操作
    onMismatch不匹配时的操作
    4.4.2 阈(yu)值过滤器ThresholdFilter
    	<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    		<level>INFO</level>
        </filter>
    
    • 1
    • 2
    • 3

    ThresholdFilter过滤低于指定阈值的事件。对于等于或高于阈值的事件,当ThresholdFilter的decide()方法被调用时,它将响应 NEUTRAL。但是,级别低于阈值的事件将被拒绝。这是一个示例配置文件。

    由低到高TRACE(跟踪)< DEBUG< INFO < WARN < ERROR < OFF(关闭)

    4.4.3 评估者过滤器EvaluatorFilter

    GEventEvaluator是具体的EventEvaluator实现,它采用任意 Groovy 语言布尔表达式作为评估标准

    	<filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
          <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> 
            <expression>
               e.level.toInt() >= WARN.toInt() &amp;&amp;  <!-- Stands for && in XML -->
               !(e.mdc?.get("req.userAgent") =~ /Googlebot|msnbot|Yahoo/ )
            </expression>
          </evaluator>
          <OnMismatch>DENY</OnMismatch>
          <OnMatch>NEUTRAL</OnMatch>
        </filter>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    4.4.4 JaninoEventEvaluator

    Logback-classic 附带了另一个名为JaninoEventEvaluator的具体EventEvaluator实现,它采用任意 Java 语言块返回布尔值作为评估标准

    4.4.5 TurboFilters和前面的类似,但对象是绑定到日志记录上下文
    4.4.6 DuplicateMessageFilter该过滤器检测重复的消息,并在超过一定重复次数后丢弃重复的消息
    4.4.7 CountingFilter可以提供有关对 Web 服务器的访问的统计数据
    4.4.8 EvaluatorFilter是封装EventEvaluator的通用过滤器

    如果还达不到你的需求可以自定义过滤器,更高级的自定义形式请参考官网

    下面显示的 SampleFilter 类提供了一个示例。其decide方法返回 ACCEPT 来记录其消息字段中包含字符串“ sample”的事件。对于其他事件,返回值 NEUTRAL。

    package chapters.filters;
    
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import ch.qos.logback.core.filter.Filter;
    import ch.qos.logback.core.spi.FilterReply;
    
    public class SampleFilter extends Filter<ILoggingEvent> {
    
      @Override
      public FilterReply decide(ILoggingEvent event) {    
        if (event.getMessage().contains("sample")) {
          return FilterReply.ACCEPT;
        } else {
          return FilterReply.NEUTRAL;
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    而xml中的filter只写下面一句话即可

    	<filter class="chapters.filters.SampleFilter" />
    
    • 1

    5 logger标签,作用:定义自己的包路径的日志以什么级别输出

    <logger name="com.fox.test" level="info" />
    
    • 1

    name 名字,一般是你的项目的包名

    level 级别,允许使用不区分大小写的字符串值 TRACE,DEBUG,INFO,WARN,ERROR,ALL 或 OFF 之一的 level 属性值。(这个级别是由低到高,只能打印当前级别 以及更高级别)

    logger元素可以包含零个或多个appender-ref元素;如此引用的每个附加程序都会添加到命名 Logger 中。请注意,与 log4j 不同,logback-classic 在配置给定 Logger 时不会关闭或删除任何以前引用的追加器。

    上面这个标签的意思是com.fox.test包下面的所有类,日志输出级别为info以上(包括),但是,它也有其他限制(root标签),也是接下来要讲一个重点有效级别(又称级别继承)

    假如我的代码结构是这样
    在这里插入图片描述

    package com.fox.test;
    
    import com.fox.test.MyApplication;
    import org.junit.jupiter.api.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest(classes = MyApplication.class)
    public class Demo1 {
    
        private Logger logger = LoggerFactory.getLogger(Demo1.class);
    
        @Test
        public void t1() {
            logger.trace("Demo1-----trace哈哈哈");
            logger.debug("Demo1-----debug哈哈哈");
            logger.info("Demo1-----info哈哈哈");
            logger.warn("Demo1-----warn哈哈哈");
            logger.error("Demo1-----error哈哈哈");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Demo1 3 5就是数字不一样,其他一样

    xml文件是这样的(其他标签也得有,我就不写了)

    5.1 案例1:仅为根 root 分配了一个级别。该级别值info由其他com和com.fox和com.fox.test继承

        <root level="info">
            <appender-ref ref="console"/>
            <appender-ref ref="file_info"/>
            <appender-ref ref="file_error"/>
        </root>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    demo1的日志为

    Demo1-----info哈哈哈
    Demo1-----warn哈哈哈
    Demo1-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo3的日志为

    Demo3-----info哈哈哈
    Demo3-----warn哈哈哈
    Demo3-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo5的日志为

    Demo5-----info哈哈哈
    Demo5-----warn哈哈哈
    Demo5-----error哈哈哈
    
    • 1
    • 2
    • 3

    然后发现demo3的类的trace和debug级别没有打印出来,这是为什么呢?

    好,我们分析一下

    logger标签name属性指定的级别有效(继承)级别
    root标签(特殊)infoinfo
    com没指定info
    com.fox没指定info
    com.fox.test没指定info

    类demo5包名com.fox.test没有指定日志级别,继承类demo3包名为com.fox的级别,而它没有指定日志级别,所以继承了上一级别com包的日志级别,而com包也没指定日志级别,所以继承root标签的日志级别。所以demo1 3 5的日志级别都是info

    如果未为给定的 Logger 分配一个级别,则它将从其最接近的祖先那里继承一个已分配的级别

    5.2 案例2:所有 Logger 都有一个分配的级别值。级别继承不起作用

        <logger name="com" level="info" />
        <logger name="com.fox" level="debug" />
        <logger name="com.fox.test" level="warn" />
    
        <root level="error">
            <appender-ref ref="console"/>
            <appender-ref ref="file_info"/>
            <appender-ref ref="file_error"/>
        </root>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    logger标签name属性指定的级别有效(继承)级别
    root标签(特殊)errorerror
    cominfoinfo
    com.foxdebugdebug
    com.fox.testwarnwarn

    demo5的包为com,指定了级别为info,所以为info以上(包括)

    Demo5-----info哈哈哈
    Demo5-----warn哈哈哈
    Demo5-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo3的包为com.fox,指定了级别为debug,所以为debug以上(包括)

    Demo3-----debug哈哈哈
    Demo3-----info哈哈哈
    Demo3-----warn哈哈哈
    Demo3-----error哈哈哈
    
    • 1
    • 2
    • 3
    • 4

    demo1的包为com.fox.test,指定了级别为warn,所以为warn以上(包括)

    Demo1-----warn哈哈哈
    Demo1-----error哈哈哈
    
    • 1
    • 2

    5.3 案例3 分别为root和com和com.fox.test分配了级别debug和info和error。com.fox从其父级com继承其级别值。

    	<logger name="com" level="info" />
        <logger name="com.fox.test" level="error" />
        
        <root level="debug">
            <appender-ref ref="console"/>
            <appender-ref ref="file_info"/>
            <appender-ref ref="file_error"/>
        </root>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    logger标签name属性指定的级别有效(继承)级别
    root标签(特殊)errorerror
    cominfoinfo
    com.fox没指定info
    com.fox.testwarnwarn

    demo5的日志

    Demo5-----info哈哈哈
    Demo5-----warn哈哈哈
    Demo5-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo3的日志

    Demo3-----info哈哈哈
    Demo3-----warn哈哈哈
    Demo3-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo1的日志

    Demo1-----error哈哈哈
    
    • 1

    5.4 案例4 分别为root和com分配了级别debug和info。com.fox从其父级com.fox.test继承其级别值。

        <logger name="com" level="info" />
    
        <root level="debug">
            <appender-ref ref="console"/>
            <appender-ref ref="file_info"/>
            <appender-ref ref="file_error"/>
        </root>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    logger标签name属性指定的级别有效(继承)级别
    root标签(特殊)debugdebug
    cominfoinfo
    com.fox没指定info
    com.fox.test没指定info

    demo5的日志

    Demo5-----info哈哈哈
    Demo5-----warn哈哈哈
    Demo5-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo3的日志

    Demo3-----info哈哈哈
    Demo3-----warn哈哈哈
    Demo3-----error哈哈哈
    
    • 1
    • 2
    • 3

    demo1的日志

    Demo1-----info哈哈哈
    Demo1-----warn哈哈哈
    Demo1-----error哈哈哈
    
    • 1
    • 2
    • 3

    相信看到这里,你已经学会了,那实际开发中该如何定义级别呢?
    下一篇文章我就结合mybatis-plus讲一下

    6 root标签,作用:将日志输出源加入root根中

        <root level="info">
            <appender-ref ref="console"/>
            <appender-ref ref="file_info"/>
            <appender-ref ref="file_error"/>
        </root>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    level是级别
    appender-ref写刚才的appender标签的name属性的值,
    root标签可以包含0个或多个appender-ref标签

    root的级别始终设置为非空值,默认情况下为debug

  • 相关阅读:
    图像识别技术如何改变智能家居的体验?
    2021年认证杯SPSSPRO杯数学建模C题(第一阶段)破局共享汽车求解全过程文档及程序
    网鼎杯初赛--web1
    Java多线程【三种实现方法】
    【CSS】grid 布局一行自动填充,每行最大限定px
    09-13-Hbase-shell入门操作
    服务器数据恢复-服务器硬盘指示灯黄灯闪烁的数据恢复案例
    Linux-9-信号
    知识图谱增强的KG-RAG框架
    每日一题 —— LC. 792 匹配子序列的单词数
  • 原文地址:https://blog.csdn.net/lh155136/article/details/125312351