参考官网直达车

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     : 哈哈哈

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

二 自定义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>
置文件的最基本结构可以描述为<configuration>元素,包含零个或多个<appender>元素,然后是零个或多个<logger>元素,最多包含一个<root>元素。下图说明了此基本结构。

在这里插入图片描述

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

三 配置详细讲解

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

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

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

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

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

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

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

logging:
  file:
    path: /mnt/logs/fox/test

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

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

<property name="logPattern" value="%d %-5level PID=${PID:- } [%thread] %-40.40logger{40} [line = %-5line] [method = %-20.20method]: %msg%n"/>
属性名字描述
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个字符,否则按照句点分割。其他同理

自定义颜色
支持的颜色字符编码
%black 黑色
%red 红色
%green 绿色
%yellow 黄色
%blue 蓝色
%magenta 洋红色
%cyan 青色
%white 白色
%gray 灰色
%highlight 高亮色

加粗的颜色字符编码
%boldRed
%boldGreen
%boldYellow
%boldBlue
%boldMagenta
%boldCyan
%boldWhite

看一下使用方法和效果
把需要加颜色的部分用上面的关键字后面加个小括号包裹起来
%red(%d)

下面的规则大家可以根据自己的想法设计

<property name="logPattern" value="%highlight(%d) %cyan(%-5level) %green(PID=${PID:- }) %magenta([%-20thread]) %yellow(%-40.40logger{40}) [line = %-5line] [method = %-20.20method]: %cyan(%msg%n)"/>

将withJansi设置为true的作用:如果操作系统底层不支持颜色转义,可以自动忽略颜色转义

<!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    	<withJansi>true</withJansi>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

将Jansi设置为true启用Jansi库解释ANSI颜色代码,如果底层终端不兼容,则会透明地过滤掉ANSI转义序列。这是跨平台部署最安全的选择,但需要在类路径上设置org.fusesource.jansi:jansi:1.17或更高。请注意,Linux和Mac OS X等基于unix的操作系统本身就支持ANSI颜色代码,通常不需要启用Jansi库,但这样做是无害的。然而,在Windows上,建议启用Jansi以受益于DOS命令提示的彩色代码解释,否则就会有发送它们无法解释的ANSI转义序列的风险。

看一下效果,比没颜色稍微好看一些
在这里插入图片描述

在这里插入图片描述


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

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

 <appender name="file_info" class="ch.qos.logback.core.ConsoleAppender"></appender>
属性名字描述
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>
4.2 file标签,作用:日志文件的绝对路径和名字
<file>${logPath}/sys-info.${hostname}.log</file>

${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>

里面的具体标签属性

属性名字描述
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>

注意除了“%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>
属性名字描述
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>
属性名字描述
level过滤的级别
onMatch匹配时的操作
onMismatch不匹配时的操作
4.4.2 阈(yu)值过滤器ThresholdFilter
	<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
		<level>INFO</level>
    </filter>

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>
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;
    }
  }
}

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

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

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

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

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哈哈哈");
    }
}

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>

demo1的日志为

Demo1-----info哈哈哈
Demo1-----warn哈哈哈
Demo1-----error哈哈哈

demo3的日志为

Demo3-----info哈哈哈
Demo3-----warn哈哈哈
Demo3-----error哈哈哈

demo5的日志为

Demo5-----info哈哈哈
Demo5-----warn哈哈哈
Demo5-----error哈哈哈

然后发现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>
logger标签name属性指定的级别有效(继承)级别
root标签(特殊)errorerror
cominfoinfo
com.foxdebugdebug
com.fox.testwarnwarn

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

Demo5-----info哈哈哈
Demo5-----warn哈哈哈
Demo5-----error哈哈哈

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

Demo3-----debug哈哈哈
Demo3-----info哈哈哈
Demo3-----warn哈哈哈
Demo3-----error哈哈哈

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

Demo1-----warn哈哈哈
Demo1-----error哈哈哈
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>
logger标签name属性指定的级别有效(继承)级别
root标签(特殊)errorerror
cominfoinfo
com.fox没指定info
com.fox.testwarnwarn

demo5的日志

Demo5-----info哈哈哈
Demo5-----warn哈哈哈
Demo5-----error哈哈哈

demo3的日志

Demo3-----info哈哈哈
Demo3-----warn哈哈哈
Demo3-----error哈哈哈

demo1的日志

Demo1-----error哈哈哈
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>
logger标签name属性指定的级别有效(继承)级别
root标签(特殊)debugdebug
cominfoinfo
com.fox没指定info
com.fox.test没指定info

demo5的日志

Demo5-----info哈哈哈
Demo5-----warn哈哈哈
Demo5-----error哈哈哈

demo3的日志

Demo3-----info哈哈哈
Demo3-----warn哈哈哈
Demo3-----error哈哈哈

demo1的日志

Demo1-----info哈哈哈
Demo1-----warn哈哈哈
Demo1-----error哈哈哈

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

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

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file_info"/>
        <appender-ref ref="file_error"/>
    </root>

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

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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐