根节点

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<configuration debug="true" scan="true" scanPeriod="2">
<!--TODO : 子节点信息-->
</configuration>

属性

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

  • scan : 配置文件如果发生改变, 将会重新加载, 默认值为true;

  • scanPeriod : 检测配置文件是否有修改的时间间隔, 如果没有给出时间单位, 默认单位时毫秒, 当scan为true时, 这个属性生效, 默认时间间隔为1min。

  • 可以这样描述配置文件的基本结构: 以<configuration>开头, 后面有零
    个或多个<appender>元素, 有零个或多个<logger>元素, 有最多一个<root>元素

子节点

  1. <appender></appender>
  2. <logger></logger>
  3. <root></root>

appender

  • <appender><configuration> 的子节点, 是负责写日志的组件。

  • appender 有两个必要属性 name , class

    • name指定appender 的名称,
    • class 指定appender的全限定名
  • class 包括 :

    • ch.qos.logback.core.ConsoleAppender
    • ch.qos.logback.core.FileAppender
    • ch.qos.logback.core.RollingFileAppender
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?xml version="1.0" encoding="utf-8"?>
    <configuration debug="true" scan="true" scanPeriod="2">
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    </appender>

    <!-- conf file out -->
    <appender name="file_out" class="ch.qos.logback.core.FileAppender">
    </appender>

    <!-- conf file out -->
    <appender name="file_out" class="ch.qos.logback.core.RollingFileAppender">
    </appender>

    <root></root>
    <loger></loger>
    </configuration>

ConsoleAppender

把日志添加到控制台, 有如下节点:

  • <encoder> : 对日志进行格式化。

  • <target> : 字符串System.out 或者 System.err, 默认 System.out;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%M - %m%n</pattern>
    <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
    <charset>UTF-8</charset>
    </encoder>
    </appender>

    <root level="INFO">
    <appender-ref ref="console_out" />
    </root>
    </configuration>

FileAppender

把日志添加到文件, 有如下节点:

  • <file> : 被写入的文件名,可以是相对目录 , 也可以是绝对目录 , 如果目录不存在则会自动创建

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

  • <encoder> : 对日志进行格式化 [具体的转换符说明请参见官网.

  • <prodent> : 如果是true, 日志会被安全的写入文件 , 即使其他的FileAppender也会向此文件做写入操作 , 默认是false

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
    <pattern>%date [%thread] %-5level %logger - %message%newline</pattern>
    </encoder>
    </appender>

    <!-- conf file out -->
    <appender name="file_out" class="ch.qos.logback.core.FileAppender">
    <file>logs/debug.log</file>
    <append>false</append>
    <encoder>
    <pattern>%date [%thread] %-5level %logger - %msg%n</pattern>
    </encoder>
    </appender>
    </configuration>

RollingFileAppender [常用]

滚动纪录文件, 先将日志记录到指定文件, 当符合某种条件时, 将日志记录到其他文件, 有如下节点:

  • <file> : 被写入的文件名, 可以是相对目录, 也可以解决目录, 如果目录不存在则自动创建。

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

  • <encoder> : 对日志进行格式化 [具体的转换符说明请参见官网.]

  • <rollingPolicy> : 当发生滚动时, 决定 RollingFileAppender 的行为, 涉及文件移动和重命名。

滚动策略

可以在 Logback 的官方文档中找到更多详细信息和示例,这里提供了一些相关的链接:

  1. Logback Manual
  2. Rolling Policies
  3. SizeAndTimeBasedRollingPolicy

TimeBaseRollingPolicy

  • TimeBasedRollingPolicy继承了RollingPolicyBase且实现了TriggeringPolicy接口,。这样的policy可以同时实现流转策略触发策略两种功能

  • RollingFileAppender 的file 子节点可有可无, 通过设置file, 可以为活动文件和归档文件制定不同位置

    • 当前日志总是纪录到file指定的文件, 活动文件的名称不会改变

    • 如果没有设置file, 活动文件 的名称会根据fileNamePattern的值, 每隔一段时间改变一次, “/”或者“\” 会被当作目录分隔符。

    • 只设置了fileNamePattern,没有设置file:不管是实时生效日志文件名还是归档文件名都是通过fileNamePattern计算出来的,会随着时间的变化而发生日志文件名的差异

  • <rollingPolicy> :告知RollingFileAppender 激活RollingFileAppender滚动

  • <fileNamePattern>: 必要节点, 包含文件及%d 转换符, %d可以包含一个java.text.SimpleDateFormat 制定的时间格式, 如: %d{yyyy-MM},如果直接使用 %d , 默认格式是yyyy-MM-dd,注:任何一个正斜杠或者是反斜杠都会被当做是目录分隔符。而且当目录不存在的时候也会自动创建,所以我们可以很容易的就把日志放在我们的目标目录。

    1. /Wombat/foo.%d (天级更新): 当没有指定具体的格式的时候 ,那么就使用默认格式yyyy-MM-dd
      每天0点进行日志滚动
      因为没有设置file配置项,那么在2006年12月23日,日志会输出到文件/wombat/foo.2006-12-23。在24号0点的时候,日志会定向输出到/wombat/foo.2006-12-24
      如果设置了file配置项的值为 /wombat/foo.txt,那么在2006年12月23号的时候,会输出日志到 /wombat/foo.txt。在24号零点的时候 /wombat/foo.txt会被重命名为 /wombat/foo.txt.2006-12-23。一个新的文件 /wombat/foo.txt将会被创建,用来接收24号输出的日志
    2. /wombat/%d{yyyy/MM}/foo.txt (月级更新)这个会按日期分文件夹
      在每个月月初的时候,进行日志滚动
      如果没有设置file配置项,那么在2006年12月的时候,日志会输出到/wombat/2006/12/foo.txt,等到过了12月,到达2007年1月的时候,日志会被重定向到/wombat/2007/01/foo.txt
      如果设置了file配置项的值为/wombat/foo.txt,那么实时日志将总是输出到/wombat/foo.txt。且在2006年12月的时候,日志会输出到/wombat/foo.txt,等到过了12月,到达2007年1月的时候,/wombat/foo.txt会被重命名为/wombat/2006/12/foo.txt,并且会创建一个/wombat/foo.txt用来接收2007年1月份的日志。等到1月31号结束到达2月1号的时候,/wombat/foo.txt会被重命名为/wombat/2007/01/foo.txt,依次类推
    3. /wombat/foo.%d{yyyy-ww}.log (周级更新)
      每周的第一天进行日志的滚动,注意这里每周的第一天的判断是依赖于本地的日历系统
      关于file配置项设置与否的差异和上述描述类似
    4. /wombat/foo%d{yyyy-MM-dd_HH}.log (小时级更新)
      每一个小时滚动一次日志
      关于file配置项设置与否的差异和上述描述类似
    5. wombat/foo%d{yyyy-MM-dd_HH-mm}.log (分钟级更新)
      每一分钟滚动一次日志
      关于file配置项设置与否的差异和上述描述类似
    6. wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log (指定时区)
      每一分钟滚动一次日志,在UTC时区下
      关于file配置项设置与否的差异和上述描述类似
    7. foo/%d{yyyy-MM,aux}/%d.log (aux 主从使用)
      可以看到有两个%d标识符,其中第一个有aux修饰,另一个没有,那么就说明,没有aux修饰的日期为主,有aux修饰的为辅。也可以理解为没有aux修饰的格式为实时写入日志的格式,有aux修改的为归档日志的存储格式
      那么在这个例子中,归档日志被存储在/foo/2006-12/这个文件夹中。因为主%d没有指明具体的日期时间格式,所以默认为是YYYY-MM-dd。所以日志的文件名为2006-12-01.log
    8. wombat/foo.%d.gz (压缩使用)
      • TimeBasedRollingPolicy 也是支持日志的自动压缩的,如果日志文件名是以 .gz 或者.zip结尾的话, 那么就会触发这一操作
      • 因为没有指定具体的日期时间格式,所以也是天级滚动日志
      • 如果没有设置file配置项,那么在2006年12月23日的时候,日志会输出到/wombat/foo.2006-12-23,等到2006年12月24日的时候,日志会被重定向到/wombat/foo.2006-12-24。而且/wombat/foo.2006-12-23会被压缩到/wombat/foo.2006-12-23.gz
      • 如果设置了file配置项的值为/wombat/foo.txt,那么实时日志将总是输出到/wombat/foo.txt。么在2006年12月23日的时候,日志会输出到/wombat/foo.txt,等到2006年12月24日的时候,/wombat/foo.txt会被重命名为/wombat/foo.2006-12-23.gz,并且会创建一个/wombat/foo.txt用来接收2006年12月24日的日志
  • <maxHistory>: 可选节点, 控制保留的归档文件的最大数量, 超出数量就删除旧文件, 假设设置每个月滚动, 且<maxHistory> 是 6, 则只保存最近6个月的文件, 删除之前的旧文件, 注意: 删除旧文件是哪些为了归档而创建的目录也会被删除。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!-- 按照每天和固定大小(5MB)生成日志文件【最新的日志,是没有日期没有数字的】 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_HOME}/项目名.log</file>
    <append>true</append>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${LOG_HOME}/项目名_%d{yyyy-MM-dd}.%i.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>
    <!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>TRACE</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
    </filter>-->
    </appender>

SizeBasedTriggeringPolicy

  • 查看当前活动文件的大小 , 如果超过指定大小会告知 RollingFileAppender , 触发当前活动滚动 , 只有一个节点 , 用来规定文件大小

  • <maxFileSize> : 活动文件的大小 , 默认10MB,单位有:KB,MB,GB

  • wombat/foo.%i.log.gz 引递增%i 将会自动在生成的文件名中添加一个数字索引,这个数字会根据滚动的次数递增。比如说,假设您配置的文件名模式为:项目名_%d{yyyy-MM-dd}.%i.log

    • 那么在某一天的日志中,如果您第一次滚动文件,您会得到类似以下的文件名:
    • 项目名_2023-10-01.0.log(第一次)
    • 项目名_2023-10-01.1.log(第二次,表示第一个文件已经达到了 5MB 的大小并被滚动)
    • 项目名_2023-10-01.2.log(第三次,以此类推)
  • 注意

    • 不支持也不允许文件压缩
    • 不能设置file属性 . 必须留空
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 按照每天和固定大小(5MB)生成日志文件【最新的日志,是日期最大数字最大的】 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/项目名_%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!-- 日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
<!-- 日志文件最大的大小 -->
<MaxFileSize>5MB</MaxFileSize>
</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>5MB</MaxFileSize> -->
<MaxFileSize>5KB</MaxFileSize>
</triggeringPolicy> -->
</appender>

SizeAndTimeBasedRollingPolicy

SizeAndTimeBasedRollingPolicy 是 Logback 中用于实现基于时间和文件大小的日志文件滚动策略。它允许开发者在满足一定的时间间隔和文件大小条件下进行日志文件的滚动,从而有效地管理日志文件。按照日期来对日志进行归档,但是同时你又希望限制每个日志文件的大小,

  • fileNamePattern: 定义生成的日志文件名模式。可以使用 %d 表示日期,%i 用于索引。例如,上述配置表示日期格式为 yyyy-MM-dd 的日志文件,超过大小限制的文件将有递增的数字后缀。
  • maxHistory: 定义日志文件的最大保留天数,以便在超过这个天数后自动删除过期的日志文件。
  • maxFileSize: 定义每个日志文件的最大大小。当达到此大小限制时,日志文件滚动将会发生,新的文件将会创建。
  • totalSizeCap: 限制合并归档日志的总大小,。当归档日志文件的总大小超过这个限制时,Logback 会开始删除最旧的归档文件,以确保总大小不超过设定的 totalSizeCap 值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名 -->
<fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件的最大保留天数 -->
<maxHistory>30</maxHistory>
<!-- 文件最大大小 -->
<maxFileSize>5MB</maxFileSize>
<!-- 限制归档日志总大小 -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="ROLLING" />
</root>
</configuration>

过滤节点

  • Logback 的过滤器基于三值逻辑(ternary logic), 允许把它们组装或成链, 从而组成任 意的复合过滤策略。

  • 这里的所谓三值逻辑是说, 过滤器的返回值只能是 ACCEPT、DENY 和 NEUTRAL 的其中一个。

    • 如果decide()方法返回DENY,则日志事件被丢弃,并且不会考虑后续的过滤器。

    • 如果返回的是NEUTRAL,则会考虑列表中的下一个过滤器。如果没有其他过滤器可供考虑,则正常处理日志事件。

    • 如果返回的是ACCEPT,则日志事件会立即被处理,并跳过剩余的过滤器调用

  • 过滤器一般分为如下几类

级别过滤器(LevelFilter)

  • LevelFilter 根据记录级别对记录事件进行过滤。

  • 如果事件的级别等于配置的级别, 过滤 器会根据 onMatch 和 onMismatch 属性接受或拒绝事件。

  • 下面是个配置文件例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
    <!-- 过滤掉非INFO级别 -->
    <level>INFO</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
    </filter>

    <encoder>
    <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
    </encoder>
    </appender>
    <root level="DEBUG">
    <appender-ref ref="console_out" />
    </root>
    </configuration>

临界值过滤器(ThresholdFilter)

  • ThresholdFilter 过滤掉低于指定临界值的事件 . 当记录的级别等于或高于临界值时 , ThresholdFilter 的decide()方法会返回NEUTRAL ;

  • 当记录级别低于临界值时 , 事件会被拒绝

  • 下面是个配置文件例子 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <!-- 过滤掉TRACE和DEBUG级别的日志 -->
    <level>INFO</level>
    </filter>

    <encoder>
    <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
    </encoder>
    </appender>
    <root level="DEBUG">
    <appender-ref ref="console_out" />
    </root>
    </configuration>

求值过滤器(EvaluatorFilter)

  • EvaluatorFilter 封装了 EventEvaluator(ch.qos.logback.core.boolex.EventEvaluator) , 评估 是否符合指定的条件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.EvaluatorFilter">
    <evaluator>
    <!--过滤掉所有日志中不包含hello字符的日志-->
    <expression>
    message.contains("hello")
    </expression>
    <onMatch>NEUTRAL</onMatch>
    <onMismatch>DENY</onMismatch>
    </evaluator>
    </filter>

    <encoder>
    <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
    </encoder>
    </appender>
    <root level="DEBUG">
    <appender-ref ref="console_out" />
    </root>
    </configuration>

匹配器(Matchers)

  • 尽管能通过调用 String 类的 matches()方法进行模式匹配, 但这会导致每次调用过滤器时都会创建一个全新的 Pattern 对象。

  • 为消除这种开销, 你可以预先定义一个或多个 Matcher 对象。一旦定义 matcher 后, 就可以在求值表达式里重复引用它。

    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
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.EvaluatorFilter">
    <evaluator>
    <matcher>
    <Name>odd</Name>
    <!-- 过滤掉序号为奇数的语句-->
    <regex>statement [13579]</regex>
    </matcher>
    <expression>odd.matches(formattedMessage)</expression>
    <onMatch>NEUTRAL</onMatch>
    <onMismatch>DENY</onMismatch>
    </evaluator>
    </filter>

    <encoder>
    <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
    </encoder>
    </appender>
    <root level="DEBUG">
    <appender-ref ref="console_out" />
    </root>
    </configuration>

至此 , Appender 节点已经介绍完毕.

logger 节点

  • 定义logger 节点用于定义特定的 Logger,这些 Logger 可以具有特定的名称、日志级别和不同的 Appender。

  • 用途:为程序的特定包、类或模块设置不同的日志级别和处理方式,从而实现更加 granular 的日志控制。

  • logger 节点通常包含以下几个主要的属性和子节点:

    1. name: 表示 Logger 的名称,可以是一个具体的类名、包名或根 Logger。
    2. level: 定义此 Logger 的日志级别,如 TRACEDEBUGINFOWARNERROROFF
    3. additivity: 可选属性,默认为 true。如果设置为 false,则表示该 Logger 不会将日志事件传递给父 Logger。这对于控制日志输出的层级非常有用。
    4. appender-ref: 指定一个或多个所使用的 Appender,即将输出的日志消息发送到哪里,不同的 Logger 可以引用不同的 Appender 或共享同一个 Appender。。
  • 下面是一个包含 logger 节点的示例配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <configuration>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
    </encoder>
    </appender>

    <logger name="com.example.service" level="DEBUG">
    <appender-ref ref="CONSOLE" />
    </logger>

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

    <root level="INFO">
    <appender-ref ref="CONSOLE" />
    </root>
    </configuration>
  • 解析示例

    • name="com.example.service":表示此 Logger 仅适用于该包名下的所有类。日志级别设置为 DEBUG,因此将记录所有 DEBUG 及以上级别的日志。
    • name="com.example.dao":仅适用于 com.example.dao 包,级别设置为 ERROR,只记录 ERROR 日志。additivity="false" 意味着这部分日志不会传递到根 Logger,只有这部分定义的 Appender 才会处理日志。
    • com.example.service Logger 的 additivity 默认设置为 true(隐式),这意味着如果在该 Logger 中记录了一个日志事件,它将传递到根 Logger,最终也会被根 Logger 的 Appender 处理。
    • com.example.dao Logger 的 additivity 设置为 false,因此对于此 Logger 记录的日志事件,只有其直接引用的 Appender(在此例中是 CONSOLE)会处理这些日志,根 Logger 不会记录这些日志。

root 节点

  • 定义root 节点用来定义根 Logger,它是所有 Logger 的祖先。所有未明确设置的 Logger 都会继承根 Logger 的配置。

  • 用途:定义一个全局的日志级别和 Appender,以捕获所有未指定的 Logger 的日志事件。

  • Level 属性的值大小写无关, 其值为下面其中一个字符串: TRACE、DEBUG、INFO、 WARN、ERROR、ALL 和 OFF。注意不能设置为“INHERITED” 或“NULL”

  • 元素可以包含零个或多个元素。声明元素后, 会先关闭然后移除全部当前 appender, 只引用声明了的 appender。

  • 如果 root 元素没有引用任何 appender, 就会失去所有 appender。

  • 如下完整案例配置 :

    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
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <!-- conf consoel out -->
    <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
    <!-- 过滤掉非INFO级别 -->
    <level>INFO</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
    </filter>
    </appender>

    <!-- 01:conf infoAppender out -->
    <appender name="infoAppender" class="ch.qos.logback.core.RollingFileAppender">

    <file>logs/info.log</file>
    <!-- 设置滚动策略 -->
    <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!--设置日志命名模式-->
    <fileNamePattern>infoFile.%d{yyyy-MM-dd}.log</fileNamePattern>
    <!--最多保留30天log-->
    <maxHistory>30</maxHistory>
    </rollingPoliy>
    <!-- 超过150MB时, 触发滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    <maxFileSize>150</maxFileSize>
    </triggeringPolicy>
    <encoder>
    <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
    </encoder>
    </appender>

    <!-- 02:conf debugAppender out -->
    <appender name="debugAppender" class="ch.qos.logback.core.RollingFileAppender">
    <file>logs/debug.log</file>
    <!-- 设置滚动策略 -->
    <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!--设置日志命名模式-->
    <fileNamePattern>debugFile.%d{yyyy-MM-dd}.log</fileNamePattern>
    <!--最多保留30天log-->
    <maxHistory>30</maxHistory>
    </rollingPoliy>
    <!-- 超过150MB时, 触发滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    <maxFileSize>150</maxFileSize>
    </triggeringPolicy>
    <encoder>
    <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
    </encoder>
    </appender>

    <!-- 03:conf errorAppender out -->
    <appender name="errorAppender" class="ch.qos.logback.core.RollingFileAppender">
    <file>logs/error.log</file>
    <!-- 设置滚动策略 -->
    <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!--设置日志命名模式-->
    <fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>
    <!--最多保留30天log-->
    <maxHistory>30</maxHistory>
    </rollingPoliy>
    <!-- 超过150MB时, 触发滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    <maxFileSize>150</maxFileSize>
    </triggeringPolicy>
    <encoder>
    <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
    </encoder>
    </appender>

    <root level="ALL">
    <appender-ref ref="infoAppender"/>
    <appender-ref ref="debugAppender"/>
    <appender-ref ref="errorAppender"/>
    </root>
    </configuration>

logger 和 root的关系

  • 层次结构:每个 logger 节点都有一个名称,它可以是一个特定的包(例如 com.example)或类(例如 com.example.MyClass)。这些 Logger 按树状结构组织,根 Logger 是所有 Logger 的祖先。

  • 传递性:如果一个 logger 节点没有设置 additivity=false,则它的日志事件会传递到根 Logger,根 Logger 将根据其配置进行处理。

  • 根节点(root:全局 Logger,适用于所有未单独定义的 Logger,通常配置最基本的日志处理策略。

  • Logger 节点(logger:用于定义具体的 Logger,针对特定的 logger 可以设置不同的级别和处理方式。

  • 用途和结构的不同:根 Logger 用于管理全局日志设置,而 Logger 节点用于特定区域或功能模块的详细日志管理。两者结合使用,可以实现灵活的日志记录控制。

logback 执行流程

  1. 获得过滤链的策略

    依据过滤器链返回的结果做出不同的响应。共有三个响应结果:
    FilterReply.DENY, 直接退出, 不执行后续流程
    FilterReply.NEUTRA, 继续向下执行
    FilterReply.ACCEPT, 不进行步骤二,即类型输出类型检查

  2. 执行基本的选择规则

    主要是比较下level, 如果级别低直接退出后续执行

  3. 创建LoggingEvent对象

    这个对象包裹一些基本信息, 包括日志界别, 信息本身, 可能的异常信息, 执行时间, 执行线程, 其实一些随日志请求一起发出的数据和MDC。其中MDC是用来装一些额外的上下文信息的。

  4. 调用appenders

    此时logback会调用appender的doAppender, 如果appender里有一些filer的话, 此时也会调用

  5. 格式化输出结果

    通常情况下都是由layout层将event格式化成String型。当然也有意外比如说SocketAppender就是将event格式化成流。

  6. 输出LoggingEvent

    将格式化好的结果, 输出到appender中记录的地址

pattern语法元素

在 Logback 中,encoderpattern 属性用于定义日志的输出格式。通过 pattern,可以指定要包含的时间戳、日志级别、线程名、类名、消息等信息。Logback 使用了一种类似于 printf 风格的格式化方式来定义这些输出。

您可以在 Logback 官方文档中找到有关 pattern 的详细信息和指导,以下是相关链接:

这些文档提供了对 Pattern 的详细解析、示例以及如何使用这些占位符进行日志格式化的更多信息,非常适合用作学习与参考

以下是 Logback 中 pattern 的基本语法元素和常用占位符:

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
时间:
%d 或 %date:输出当前的日期和时间。
例如,%d{yyyy-MM-dd HH:mm:ss} 将输出成 2023-10-01 12:00:00。
日志级别:

%level 或 %p:输出日志的级别(如 DEBUG、INFO、ERROR 等)。
线程信息:

%thread:输出当前线程的名称。
日志记录器名称:

%logger:输出记录日志的类名或 Logger 名称,通常会使用 {} 指定字符数以限制输出长度。
例如 %logger{36} 会限制 Logger 名称的输出为 36 个字符。
消息内容:

%msg:输出日志消息的内容。
行分隔符:

%n:输出换行符。
其他信息:

%F:当前日志被输出的文件名。
%L:当前日志被输出的行号。
%C:当前输出日志的类的全名。
%M 来获取调用日志记录的类中的方法名

示例:以下是一个包含各种元素的 pattern 示例:

1
2
3
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
  • %d{yyyy-MM-dd HH:mm:ss}:输出格式化的日期和时间。
  • [%thread]:输出当前线程名。
  • %-5level:输出日志级别,并左对齐,占用 5 个字符宽度。
  • %logger{36}:输出 Logger 名称,最多显示 36 个字符。
  • %msg:输出实际的日志消息。
  • %n:在每条日志信息的末尾换行。

这个示例将产生如下格式的输出:

1
2023-10-01 12:00:00 [main] INFO  com.example.MyClass - 这是一个日志消息