java日志框架总结(五、logback日志框架)

一、logback概述 

Logback是由log4j创始人设计的又一个开源日志组件。
Logback当前分成三个模块:
        1、logback-core,
        2、logback- classic
        3、logback-access。

1)logback-core是其它两个模块的基础模块。
2)logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API。使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。
3)logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。

二、Logback中组件与配置

1)logback依赖jar包
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version>
</dependency>

        SpringBoot项目默认就是使用的就是logback日志系统,创建SpringBoot项目时引入的spring-boot-starter或者spring-boot-starter-web依赖jar包中已经包含了spring-boot-starter-logging的依赖,里面同时包含多种日志系统依赖,如下图所示:

包括logback和log4j,所以,无需额外添加依赖,直接配置logback.xml就可以了。

此外,如果需要切换为log4j2,那么需要在spring-boot-starter-web依赖中排除springboot自带的commons‐logging,然后在引入log4j2的依赖jar包,如下所示:

<!--排除 commons‐logging-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>commons‐logging</groupId><artifactId>commons‐logging</artifactId></exclusion></exclusions>
</dependency>
<!--引入log4j2 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2)相关组件

1、Logger: 日志的记录器,主要用于存放日志对象,也可以定义日志类型、级别。

2、Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。

3、Layout: 负责把事件转换成字符串,格式化的日志信息的输出。在Logback中Layout对象被封装在encoder中。也就是说我们使用的encoder其实就是Layout。

     与前几个日志框架类似!

3)日志级别(log level):

        用来控制日志信息的输出,从高到低分为共分为七个等级:

A:off 最高等级,用于关闭所有日志记录。
B:fatal 指出每个严重的错误事件将会导致应用程序的退出。
C:error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
D:warm 表明会出现潜在的错误情形。
E:info 一般和在粗粒度级别上,强调应用程序的运行全程。
F:debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
G:all 最低等级,用于打开所有日志记录。 

 4)  Logback配置文件

Logback提供了3种配置文件

  • logback.groovy
  • logback-test.xml
  • logback.xml(常用)
    如果都不存在则采用默认的配置

配置文件下面会详解。

5)什么是logback的context上下文?

        每一个logger都被关联到一个loggerContext中,loggerContext负责生产logger,也负责以树形结构排列各个logger。
        logger的获取主要是通过org.slf4j.LoggerFactory的getLogger()方法获取。

        getLogger()方法有两种实现方式
           a) getLogger(Class Obj)通过传入一个类的形式,来进行logger对象和类的绑定。
           b) getLogger(String name)方式是通过传入一个contextName的形式,来指定一个logger。

        其中,用同一个名字调用该方法获取的永远都是同一个logger对象。

三、logback应用

1)入门案例
    public static void main(String[] args) {Logger logger = LoggerFactory.getLogger(LogDemo.class);logger.trace("======trace");logger.debug("======debug");logger.info("======info");logger.warn("======warn");logger.error("======error");}

没有加任何配置,会使用默认配置,但是记得要引入SpringBoot的依赖包。

 2)logback.xml 配置文件

     下面是一个比较完整的示例,那这个介绍一下各个标签的含义:

<?xml version="1.0" encoding="UTF-8"?>
<!-- scan 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
<!-- scanPeriod 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false"><!-- 读取application.properties配置 --><!--    <property resource="application.properties" />--><!-- 生成文件名前缀 --><property name="FILE_PREFIX" value="yyzRead" /><!-- 输出文件路径 --><property name="OPEN_FILE_PATH" value="D:\log_yyzDevelopRead"/><!-- 文件保存时间 这里是7天 --><property name="EXIST_TIME" value="7"/><!-- 文件输出格式 --><property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/><!-- 日志文件最大的大小 --><property name="MAX_FILE_SIZE" value="10MB"/><!--  控制台输出  --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${PATTERN}</pattern><charset>UTF-8</charset></encoder></appender><!-- 输出到all文件 这里是全部的日志内容 --><appender name="OPEN-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!--不能有这项配置!!!!!--><!--<Encoding>UTF-8</Encoding>--><!--<File>${OPEN_FILE_PATH}/${FILE_PREFIX}.log</File>--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${OPEN_FILE_PATH}/all/${FILE_PREFIX}_%d{yyyy-MM-dd}-%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>${EXIST_TIME}</MaxHistory><TimeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!--日志文件最大的大小--><MaxFileSize>${MAX_FILE_SIZE}</MaxFileSize></TimeBasedFileNamingAndTriggeringPolicy></rollingPolicy><layout class="ch.qos.logback.classic.PatternLayout"><pattern>${PATTERN}</pattern></layout></appender><!--输出到debug文件--><appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${OPEN_FILE_PATH}/debug/${FILE_PREFIX}_%d{yyyy-MM-dd}-%i.log</FileNamePattern><MaxHistory>30</MaxHistory><TimeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><MaxFileSize>${MAX_FILE_SIZE}</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><!-- 只打印DEBUG日志, --><filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 过滤的级别 --><level>DEBUG</level><!-- 匹配时的操作:接收(记录) --><onMatch>ACCEPT</onMatch><!-- 不匹配时的操作:拒绝(不记录) --><onMismatch>DENY</onMismatch></filter></appender><!--输出到info文件--><appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${OPEN_FILE_PATH}/info/${FILE_PREFIX}_%d{yyyy-MM-dd}-%i.log</FileNamePattern><MaxHistory>30</MaxHistory><TimeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><MaxFileSize>${MAX_FILE_SIZE}</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><!-- 只打印INFO日志 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><!-- 匹配时的操作:接收(记录) --><onMatch>ACCEPT</onMatch><!-- 不匹配时的操作:拒绝(不记录) --><onMismatch>DENY</onMismatch></filter></appender><!--输出到error文件--><appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${OPEN_FILE_PATH}/error/${FILE_PREFIX}_%d{yyyy-MM-dd}-%i.log</FileNamePattern><MaxHistory>30</MaxHistory><TimeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><MaxFileSize>${MAX_FILE_SIZE}</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><!-- 只打印ERROR日志 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><!-- 匹配时的操作:接收(记录) --><onMatch>ACCEPT</onMatch><!-- 不匹配时的操作:拒绝(不记录) --><onMismatch>DENY</onMismatch></filter></appender><!--输出到warn文件--><appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${OPEN_FILE_PATH}/warn/${FILE_PREFIX}_%d{yyyy-MM-dd}-%i.log</FileNamePattern><MaxHistory>30</MaxHistory><TimeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><MaxFileSize>${MAX_FILE_SIZE}</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><!-- 只打印WARN日志 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><!-- 匹配时的操作:接收(记录) --><onMatch>ACCEPT</onMatch><!-- 不匹配时的操作:拒绝(不记录) --><onMismatch>DENY</onMismatch></filter></appender><!--  默认输出info等级,然后再根据各自的拦截过滤规则去处理  --><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>
3)  配置文件中各个标签介绍:

1.logback-spring.xml的配置项

共有一个父标签、两种属性、三个节点:

  一个父标签:configuration
  两种属性:contextName和property
  三个节点:appender、root、logger

2.父标签 configuration:

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

三个属性:
        1、scan   当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true
        2、scanPeriod     设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
        3、debug     当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

3.子节点:<contextName>

<contextName>logback</contextName>

每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置好,就不能修改。可以通过%contextName来打印日志上下文名称,一般来说我们不用这个属性,可有可无。

4.属性标签property

  <!-- 文件输出格式 --><property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>

用来定义变量值的标签,它有两个属性 name 和 value:

  • name的值是变量的名称
  • value的值是变量的定义的值,通过该标签定义的值会被插入到logger上下文中,定义变量后可以通过 “ ${变量名} ” 来使用变量

    这个标签就是可以把通用的属性设置好,如果后面有需要用到的地方可以直接引用。

5.子节点:<appender>

    <!--  控制台输出  --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${PATTERN}</pattern><charset>UTF-8</charset></encoder></appender>

appender用来格式化日志输出节点,有连个属性name和class,class用来指定那种输出策略。
appender跟前几个框架中的用法类似,其实可以认为是一个输出器,指定输出的名字和样式,如果检测到配置文件中有这个输出器,就会按照输出器配置的格式输出。

 输出策略:

1.ConsoleAppender:日志输出到控制台,类名ch.qos.logback.core.ConsoleAppender。
2.FileAppender:日志输入到文件,类名ch.qos.logback.core.FileAppender。作用是将日志输出到文件。目标文件可以指定,如果该文件已经存在,它将根据附加属性的值被追加或截断。
3.RollingFileAppender:滚动记录文件,FileAppender的子类,当符合条件(大小、时间),日志进行切分处理,类名:ch.qos.logback.core.rolling.RollingFileAppender。将FileAppender的功能进行扩展,提供了切割日志文件的功能。例如:RollingFileAppender可以记录日志到一个名为log.txt的文件,一旦满足一定条件,将其日志目标更改为另一个文件。在使用时,RollingFileAppender必须同时具有RollingPolicy和TriggeringPolicy设置。但是,如果它的RollingPolicy也实现TriggeringPolicy接口,那么只需要显式地指定前者。
4.TimeBasedRollingPolicy:时间基准滚动策略可能是最流行的滚动策略。它定义了一个基于时间的滚动策略,例如每日或每月。时间的滚动策略承担了翻转的责任,同时也承担了触发的滚动。TimeBasedTriggeringPolicy实现了RollingPolicy和TriggeringPolicy接口。类名ch.qos.logback.core.rolling.TimeBasedRollingPolicy
5.SizeAndTimeBasedRollingPolicy:有时候可能希望按日期对文件进行存档,但同时限制每人日志文件的大小,这时候可以使用SizeAndTimeBasedRollingPolicy达到目的。类名ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy
6.SiftingAppender:筛选附加器,类名ch.qos.logback.classic.sift.SiftingAppender ,他下面有个子节点<discriminator>(辨别)discriminator 下有2个子节点<key>和<defaultValue> 其实就是定义与MDC关联的变量key=MDC中put的key defaultValue需要我们随便给个值,不过最好是有意义的SiftingAppender 下有个<sift>子节点这个子节点可以按照appender进行配置

6、<appender>标签中各个子标签:

        依输出策略为RollingFileAppender为例:

   <!-- 输出到all文件 这里是全部的日志内容 --><appender name="OPEN-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!--不能有这项配置!!!!!--><!--<Encoding>UTF-8</Encoding>--><!--<File>${OPEN_FILE_PATH}/${FILE_PREFIX}.log</File>--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${OPEN_FILE_PATH}/all/${FILE_PREFIX}_%d{yyyy-MM-dd}-%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>${EXIST_TIME}</MaxHistory><TimeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!--日志文件最大的大小--><MaxFileSize>${MAX_FILE_SIZE}</MaxFileSize></TimeBasedFileNamingAndTriggeringPolicy></rollingPolicy><layout class="ch.qos.logback.classic.PatternLayout"><pattern>${PATTERN}</pattern></layout></appender>

<file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。

<append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。

<rollingPolicy>: 当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类,"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"是最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。 

        RollingFileAppender要想实现滚动功能,必须同时设置具体的RollingPolicy类与具体的TriggerPolicy类。如果某个类A实现了RollingPolicy与TriggerPolicy,那么只需要设置类A就可以了。

rollingPolicy属性值的类型有:FixedWindowRollingPolicy类、TimeBasedRollingPolicy类(常用)。FixedWindowRollingPolicy,TimeBasedRollingPolicy 支持自动压缩文件。

这些属性是需要配置的,因此我们可以通过在xml配置文件中的标签中创建以属性名为标签名的标签,并为这些标签进行配置。

注意:中不同的class属性值表明使用不同的目的地,因此会有不同的参数,从而表现出在配置文件中的标签有所差异。

1.最受欢迎的滚动策略TimeBaseRollingPolicy

TimeBaseRollingPolicy:最流行的滚动策略。根据时间来制定滚动策略。由于TimeBaseRollingPolicy实现了RollingPolicy接口和TriggeringPolicy接口,因此TimeBaseRollingPolicy即负责滚动也负责触发条件。

<fileNamePattern>:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。

<maxHistory>:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且<maxHistory>是6,则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。"ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"是查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender 触发当前活动文件滚动。只有一个节点:

<maxFileSize>:这是活动文件的大小,默认值是10MB。 

<prudent>:当为true时,不支持FixedWindowRollingPolicy。支持TimeBasedRollingPolicy,但是有两个限制,1不支持也不允许文件压缩,2不能设置file属性,必须留空。 

<triggeringPolicy >: 告知 RollingFileAppender 合适激活滚动。"ch.qos.logback.core.rolling.FixedWindowRollingPolicy" 根据固定窗口算法重命名文件的滚动策略。

<minIndex>:窗口索引最小值

<maxIndex>:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为12。

<fileNamePattern>:必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip

<encoder>  和  <layout> :简单来说 encoder 和 layout 都是控制日志输出格式的,如果使用layout就需要如下样式:需要指定一个实例。

<layout class="ch.qos.logback.classic.PatternLayout">

 其中layout仅仅完成了将一个event事件转换成一个字符串这一个功能。此外,layout不能控制将字符串写出到文件。layout不能整合event事件到一组中。与encoder相比,不仅仅能按照格式进行转化,而且还能将数据写入到文件中。

<encoder> 标签默认就是使用的patternLayoutEncoder这个实例,既有layout将一个事件转化为字符串,又有将字符创写入到文件中的作用。他是encoder标签的默认类实例。

具体可参考这篇文章:
logback和slf4j的使用之encoder和Layout-CSDN博客

<filter>:  logback具有过滤器支持。logbcak允许给日志记录器appender配置一个或多个Filter(或者给整体配置一个或多个TurboFilter),来控制:当满足过滤器指定的条件时,才记录日志(或不满足条件时,拒绝记录日志)。logback支持自定义过滤器,当然logback也自带了一些常用的过滤器,在绝大多数时候,自带的过滤器其实就够用了,一般是不需要自定义过滤器的。

ch.qos.logback.core.filter.Filter
ch.qos.logback.classic.turbo.TurboFilter

Filter:
1、LevelFilter:对指定level的日志进行记录(或不记录),对不等于指定level的日志不记录(或进行记录)
2、ThresholdFilter:对指定level的日志进行记录(或不记录),对不等于指定level的日志不记录(或进行记录)
3、EvaluatorFilter:对满足指定表达式的日志进行记录(或不记录),对不满足指定表达式的日志不作记录(或进行记录)

TurboFilter:
1、MDCFilter : 若MDC域中存在指定的key-value,则进行记录,否者不作记录
​​​​​​​2、DuplicateMessageFilter : 根据配置不记录多余的重复的日志
3、MarkerFilter :针对带有指定标记的日志,进行记录(或不作记录)

TurboFilter的性能是优于Filter的,这是因为TurboFilter的作用时机是在创建日志事件ILoggingEvent对象之前,而Filter的作用时机是在创建之后。若一个日志注定是会被过滤掉不记录的,那么创建ILoggingEvent对象(包括后续的参数组装方法调用等)这个步骤无疑是非常消耗性能的

这里主要介绍一下ThresholdFilter和LevelFilter:

ThresholdFilter为系统定义的拦截器,例如我们用ThresholdFilter来过滤掉ERROR级别以下的日志不输出到文件中。如果不用记得注释掉,不然你控制台会发现没日志

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

LevelFilter如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,所以我们使用下面的策略,可以避免输出 Error 的日志

<filter class="ch.qos.logback.classic.filter.LevelFilter"><!--过滤 Error--><level>ERROR</level><!--匹配到就禁止--><onMatch>DENY</onMatch><!--没有匹配到就允许--><onMismatch>ACCEPT</onMismatch>
</filter>


FilterReply有三种枚举值:

  • DENY:表示不用看后面的过滤器了,这里就给拒绝了,不作记录。
  • NEUTRAL:表示需不需要记录,还需要看后面的过滤器。若所有过滤器返回的全部都是NEUTRAL,那么需要记录日志。
  • ACCEPT:表示不用看后面的过滤器了,这里就给直接同意了,需要记录。

7、子节点:<logger>

用来指定某一个包或者具体某一个类的日志打印级别,以及指定<appender> ,<logger>只有一个name属性,一个可选的level和一个可选的addtivity

name:用来指定受此loger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
addtivity:是否向上级loger传递打印信息。默认是true。
示例:

<logger name="com.example" additivity="false" level="ERROR"><appender-ref ref="error"/></logger>

控制com.example包下的日志打印,打印级别为“ERROR”;additivity属性为false,表示此loger的打印信息不再向上级传递;指定了名字为“error”的appender;

logger中可以有多个appender-ref

8、子节点:<root>

root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。level默认是DEBUG。

<root level="debug"><appender-ref ref="console" /><appender-ref ref="error" />
</root>

​​​​​​​

Logback配置文件详解——项目架构-CSDN博客

【Logback】<logger>、<root>标签详解 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/458309.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云服在手,轻松过年!告别沉重电脑包,随时随地工作无忧

临近春节&#xff0c;不少人都要准备回老家了 但回了老家&#xff0c;就不能像回自己家一样&#xff0c;资料文件都在自己电脑&#xff0c;处理事务能随时随地&#xff0c;毕竟舟车劳顿&#xff0c;总不能身上带着台式机/手提电脑来回折腾。 那么如何既能轻装回家&#xff0c…

“掌握温度,感知湿度,一触即知!”DHT11温湿度传感器,为您的生活增添一份关怀与精准。#非标协议【下】

“掌握温度&#xff0c;感知湿度&#xff0c;一触即知&#xff01;”DHT11温湿度传感器&#xff0c;为您的生活增添一份关怀与精准。#非标协议【下】 前言预备知识1.DHT11温湿度传感器初识1.1产品概述1.2与51单片机接线1.3数据传送逻辑和数据格式 2.发送时序检测DHT11温湿度传感…

【01】判断素数/质数(C语言)

目录 &#xff08;1&#xff09;素数特点&#xff1a;只能被1和本身整除 &#xff08;2&#xff09;代码如下&#xff1a; &#xff08;3&#xff09;运行结果如下 ​编辑 &#xff08;4&#xff09;函数引申 &#xff08;1&#xff09;素数特点&#xff1a;只能被1和本身…

leetcode 1.两数之和(C++详细题解)DAY1

文章目录 1.题目描述示例提示 2.解答思路&#xff08;1&#xff09;暴力解法&#xff08;2&#xff09;哈希表 3.实现代码结果 4.总结 1.题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c…

Mysql MGR搭建

一、架构说明 1.1 架构概述 MGR(单主)VIP架构是一种分布式数据库架构&#xff0c;其中数据库系统采用单主复制模式&#xff0c; 同时引入虚拟IP(VIP)来提高可用性和可扩展性。 这种架构结合了传统主从复制和虚拟IP技术的优势&#xff0c;为数据库系统提供了高可用、 高性能和…

游戏服务器多少钱一台?腾讯云32元,阿里云26元

游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;游戏服务器配置从4核16G、4核32G、8核32G、16核64G等配置可选&#xff0c;可以选择轻量应用服务器和云服务器&#xff0c;阿腾云atengyu…

OpenCV与机器学习:使用opencv和sklearn实现线性回归

前言 线性回归是一种统计分析方法&#xff0c;用于确定两种或两种以上变量之间相互依赖的定量关系。在统计学中&#xff0c;线性回归利用线性回归方程&#xff08;最小二乘函数&#xff09;对一个或多个自变量&#xff08;特征值&#xff09;和因变量&#xff08;目标值&#…

手把手教你开发Python桌面应用-PyQt6图书管理系统-图书类别信息修改实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…

怎么加密电脑磁盘?磁盘加密软件哪个好?

磁盘是电脑储存数据的基础工具&#xff0c;可以存放大量数据。为了避免数据泄露&#xff0c;可以使用专业的磁盘加密软件加密保护电脑磁盘。那么&#xff0c;磁盘加密软件哪个好呢&#xff1f;下面我们就来了解一下。 磁盘加锁专家 磁盘加锁专家是一款专业的磁盘加锁软件&…

Anaconda超详细安装教程(Windows环境下)

每个人电脑不同&#xff0c;特别是配置环境变量&#xff0c;不要直接复制粘贴。 &#xff08;本人技术小白一个&#xff0c;如有错误&#xff0c;欢迎各位大神指正。&#xff09; 说明&#xff1a;其实要是装Anaconda的话&#xff0c;就不用再单独装Python了。但是吧&#xf…

UsernamePasswordAutheticationFilter源码解读和实践

UsernamePasswordAuthenticationFilter的目录 一、概述&#xff08;重点&#xff09;二、标红小步骤解读2.1 步骤1&#xff08;标红1&#xff09;2.1.1 AbstractAuthenticationProcessingFilter2.1.2 UsernamePasswordAuthenticationFilter 2.3 步骤2 和 步骤3&#xff08;标红…

【Linux系统 02】Shell脚本

目录 一、Shell概述 二、输入输出 三、分支控制 1. 表达式 2. if 分支 3. case 分支 四、循环控制 1. for 循环 2. while 循环 3. select 循环 五、函数 一、Shell概述 Shell是Linux系统连接用户和操作系统的外壳程序&#xff0c;将用户的输入和请求选择性传递给操…