【Logback技术专题】「入门到精通系列教程」深入探索Logback日志框架的原理分析和开发实战技术指南(下篇)

news2025/1/13 9:31:08

深入探索Logback日志框架的原理分析和开发实战技术指南(下篇)

  • 根节点configuration包含的属性
    • 基本参数详解
    • 子节点介绍
      • 设置上下文名称`<contextName>`
        • 使用案例
      • 设置变量属性值`<property>`
      • 获取时间戳字符串`<timestamp>`
      • 设置logger
        • root根节点
        • additivity的继承传递模式
      • 常用配置详解 `<appender>`
        • ConsoleAppender
          • 例如:
        • FileAppender
          • 例如:
        • RollingFileAppender
          • **rollingPolicy**
            • fileNamePattern
            • maxHistory
            • 配置案例
          • **FixedWindowRollingPolicy**
          • triggeringPolicy
        • 其他的Appender
        • 案例分析
          • 每天生成一个日志文件,保存30天的日志文件
          • 按照固定窗口模式生成日志文件
      • 常用配置详解 `<encoder>`
        • <pattern>里面的转换符说明:
          • 输出logger名称
          • 输出Class类全限定名
          • 输出上下文名称
          • 日志的打印日期时间
          • 输出信息深度
            • 案例分析
          • F / file 输出源文件名
          • 其他格式符号
        • 格式修饰符
        • 配置详解 `<filter>`
          • LevelFilter(级别过滤器):
          • ThresholdFilter(临界值过滤器)
          • EvaluatorFilter(求值过滤器):
            • `<evaluator>`(鉴别器):
          • 过滤掉所有日志消息中不包含“billing”字符串的日志

根节点configuration包含的属性

在这里插入图片描述

基本参数详解

  • scan属性设置为true时,配置文件有改变时将会被重新加载,默认为true
  • scanPeriod设置监测配置文件是否有修改的时间间隔。如果未指定时间单位,将默认为毫秒。只有当scantrue时才生效。默认间隔为1分钟。
  • debug属性设置为true时将会打印出logback的内部日志信息,方便实时查看logback运行状态。默认为false
 <configuration scan="true" scanPeriod="60 seconds" debug="false">  
     <!-- 其他配置省略-->  
 </configuration>  

子节点介绍

设置上下文名称<contextName>

每个logger都默认关联到logger上下文,上下文名称默认为“default”。但是可以通过设置来将其设置为其他名称,以便于区分不同应用程序的记录。一旦设置,就无法修改。

使用案例

  <configuration scan="true" scanPeriod="60 seconds" debug="false">  
       <contextName>myApplication</contextName>  
       <!-- 其他配置省略-->  
  </configuration>  

设置变量属性值<property>

使用标签定义变量值,该标签有两个属性,分别是name和value。name表示变量名,value则是变量所需的值,在通过该标签定义的变量会被插入到logger上下文中。定义好变量后,可以在后续的程序中使用“${}”来引用这些变量。

使用<property>标签定义一个名属性,并在<contextName>标签中使用该属性的值,即可为logger设置上下文名称。

<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <property name="APP_Name" value="myAppName" />
    <contextName>${APP_Name}</contextName>
    <!-- 其他配置省略-->
</configuration>

举个例子,使用标签定义一个用于设置logger上下文的名称,然后在标签中使用该名称即可。

获取时间戳字符串<timestamp>

在标签内,使用属性来定义一个名称,为项目使用当前日期时间命名,设置属性来定义日期时间格式。示例代码如下:

<timestamp key="name" datePattern="yyyyMMddHHmm">

其中,key属性指定用于identifier的名称;datePattern属性定义将当前时间转换为字符串的模式。

您可以根据自己项目的需要修改日期时间格式。

例如将解析配置文件的时间作为上下文名称:

     <configuration scan="true" scanPeriod="60 seconds" debug="false">  
          <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>   
          <contextName>${bySecond}</contextName>  
          <!-- 其他配置省略-->  
    </configuration>   

设置logger

在Java应用程序的日志配置中,使用<logger>元素来设置某个包或具体的类的日志打印级别,并且可以指定日志输出的目的地(<appender>)。
在这里插入图片描述

  • <logger>元素只有一个必须的属性 name,用于指定要设置日志级别的包名或类名,可以包含通配符。
  • <logger>元素还可以包含可选的 level 属性,用于指定日志输出的级别,包括 TRACE、DEBUG、INFO、WARN、ERROR 和 OFF。
  • <logger>元素还可以包含可选的 additivity 属性,用于指定是否将日志事件发送给该Logger的父级Logger。

可以在<logger>中添加多个<appender-ref>元素来指定用于添加到该logger的各个appender

<logger name="com.campus.o2o" level="${log.level}" additivity="true">
    <appender-ref ref="debugAppender" />
    <appender-ref ref="infoAppender" />
    <appender-ref ref="errorAppender" />
</logger>
 <!-- 特殊的logger,根logger -->
 <root lever="info">
    <!-- 指定默认的日志输出 -->
    <appender-ref ref="consoleAppender" />
 </root>

root根节点

根logger是一个<logger>元素,它只有一个level属性,应为已经被命名为"root"。level属性用来设置打印级别,大小写无关,可选的级别有:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。它的默认级别是DEBUG。

 
 <!-- 特殊的logger,根logger -->
 <root lever="info">
     <!-- 指定默认的日志输出 -->
     <appender-ref ref="consoleAppender" />
 </root>

<root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。

additivity的继承传递模式

appender配置表示将日志打印到控制台。<logger name="logback" />控制logback包下所有类的日志打印,未设置打印级别,继承自上级的DEBUG级别。additivity未设置,默认为true,将此logger的打印信息向上传递。未设置appender,此logger本身不打印任何信息。

<root level="DEBUG">将root的打印级别设置为DEBUG并指定名为"STDOUT"的appender。

常用配置详解 <appender>

<appender><configuration>的子节点,用于写日志的组件。

在这里插入图片描述
<appender>必须包含两个属性:name和class。name用于指定appender的名称,class用于指定appender的全限定名。

在这里插入图片描述

ConsoleAppender

要将日志输出到控制台,您可以使用以下子节点:

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

  • <target>:使用字符串 “System.out” 或 “System.err”,默认为 “System.out”。

例如:
     <configuration>  
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
        <encoder>  
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>  
        </encoder>  
      </appender>     
      <root level="DEBUG">  
        <appender-ref ref="STDOUT" />  
      </root>  
    </configuration>

FileAppender

将日志写入文件时,可以使用以下子节点进行配置:

  • <file>: 指定要写入的文件名,可以是相对或绝对路径。如果上级目录不存在,系统会自动创建。如果没有指定,默认为空。(提示:可以根据需要指定文件名和路径)
  • <append>: 如果设置为 true,则日志会追加到文件末尾;如果设置为 false,则会清空现有文件内容。默认为 true。(提示:可以选择是否追加日志或覆盖文件内容)
  • <encoder>: 用于对记录的事件进行格式化的编码器参数。(提示:可以根据需要设置适当的编码器参数)
  • <prudent>: 如果设置为 true,即使其他 FileAppender 正在向该文件写入,日志也会被安全写入文件,但效率会较低。默认为 false。 (提示:可以选择是否启用安全写入模式)
例如:
<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>/path/to/testFile.log</file>
    <append>true</append>
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="FILE"/>
  </root>
</configuration>

RollingFileAppender

在这里插入图片描述
这个配置使用RollingFileAppender,满足以下要求:

  • <file>:指定主日志文件的路径,这里使用/path/to/logFile.log作为示例,请替换为你实际需要的路径。
  • <append>:设置为true,表示日志会追加到文件的结尾。
  • <encoder>:使用给定的模式对日志事件进行格式化。
  • <rollingPolicy>:使用TimeBasedRollingPolicy进行滚动记录,这里的fileNamePattern用于指定滚动后生成的文件名模式。
  • <triggeringPolicy>:使用SizeBasedTriggeringPolicy设置日志文件的最大大小为10MB,当日志文件大小达到上限时会触发滚动记录。
<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>/path/to/logFile.log</file>
    <append>true</append>
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

请确保将/path/to/logFile.log/path/to/logFile-%d{yyyy-MM-dd}.log替换为适合你的实际文件路径和命名模式。如有需要,请进行其他配置调整。如果你有任何其他问题,请随时向我提问。

RollingFileAppender的file节点是可选项,它用于设置活动文件和归档文件的位置。如果通过设置file节点,可以将当前日志记录到指定的活动文件,而活动文件的名称不会改变。如果未设置file节点,活动文件的名称将根据fileNamePattern的值,每隔一段时间变化一次。目录分隔符可使用"/“或”"来表示。

rollingPolicy

在这里插入图片描述

fileNamePattern

该内容包含文件名及"%d"转换符,其中"%d"可以包含java.text.SimpleDateFormat指定的时间格式,例如:%d{yyyy-MM}。如果未直接使用"%d",则默认的时间格式为yyyy-MM-dd。

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>/path/to/logFile-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
maxHistory

可选节点用于控制归档文件的最大保留数量。如果设置每月滚动,并且设置<maxHistory>为6,那么只会保留最近的6个月的文件,并删除之前的旧文件。需要注意的是,删除旧文件时,与归档相关的目录也会被删除。

配置案例
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>/path/to/logFile-%d{yyyy-MM-dd}.log</fileNamePattern>
    <maxHistory>30</maxHistory>    
</rollingPolicy>
FixedWindowRollingPolicy

该策略基于固定窗口算法对文件进行重命名,具有以下子节点:

  • <minIndex>: 窗口索引的最小值。
  • <maxIndex>: 窗口索引的最大值。如果用户指定的窗口大小超过该值,系统会自动将窗口大小设置为12。
  • <fileNamePattern>: 文件名的模式。

命名模式必须包含 “%i”,例如,假设最小值和最大值分别为 1 和 2,文件名模式可以是 “mylog%i.log”。这样将会生成归档文件 “mylog1.log” 和 “mylog2.log”。另外,您还可以选择文件的压缩选项,例如 “mylog%i.log.gz” 或 “mylog%i.log.zip”。

   
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
   <maxFileSize>10MB</maxFileSize>
</triggeringPolicy>
    
triggeringPolicy

SizeBasedTriggeringPolicy:该策略会监视当前活动文件的大小,如果其大小超过指定值,将触发 RollingFileAppender 执行文件滚动操作。此策略只适用于单一节点的情况。

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

其他的Appender

  • SocketAppender:SocketAppender用于将日志消息通过网络传输到远程的Socket服务器。它可以将日志发送到指定的远程Socket地址,并将日志消息传递给服务器进行处理和存储。

  • SMTPAppender:SMTPAppender用于通过邮件将日志消息发送给指定的收件人。它可以将日志消息作为邮件附件发送,并支持邮件服务器的配置,如SMTP服务器地址、认证信息等。

  • DBAppender:DBAppender用于将日志消息保存到数据库中。它可以将日志消息插入到指定的数据库表中,并支持各种数据库连接和配置选项。

  • SyslogAppender:SyslogAppender用于将日志消息发送到Syslog服务器。它可以将日志消息转发到指定的Syslog服务器,并支持Syslog协议的各种配置选项。

  • SiftingAppender:SiftingAppender用于根据不同的条件将日志消息路由到不同的目标Appender。它可以根据指定的条件(如日志级别、日志标签等)将日志消息发送到不同的Appender进行处理和存储。

案例分析

每天生成一个日志文件,保存30天的日志文件
     <configuration>   
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">   
          
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">   
          <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>   
          <maxHistory>30</maxHistory>    
        </rollingPolicy>   
       
        <encoder>   
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>   
        </encoder>   
      </appender>    
       
      <root level="DEBUG">   
        <appender-ref ref="FILE" />   
      </root>   
    </configuration>  
按照固定窗口模式生成日志文件

在文件大小超过20MB时,我们需要生成一个新的日志文件。同时,我们需要确保窗口大小在1到3之间。当我们保存了3个归档文件后,最早的日志将被覆盖。

此外,我们还有两个主要任务需要完成。首先,我们需要将日志信息转换成字节数组的形式。其次,我们需要将这些字节数组写入输出流中。

     <configuration>   
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <file>test.log</file>   
        <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>   
        <encoder>   
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>   
        </encoder>   
      </appender>   
               
      <root level="DEBUG">   
        <appender-ref ref="FILE" />   
      </root>   
    </configuration>  

常用配置详解 <encoder>

目前,我们使用的是PatternLayoutEncoder作为唯一有用且默认的编码器。在配置文件中,我们可以通过<pattern>节点来设置日志的输入格式。使用“%”加上转换符的方式,我们可以定义不同的日志输出格式。如果我们想要输出一个百分号“%”,那么我们需要使用反斜杠“\”对“%”进行转义。

     <encoder>   
       <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>   
    </encoder>  

里面的转换符说明:

输出logger名称

输出日志的logger名,可有一个整形参数,功能是缩短logger名,设置为0表示只输入logger最右边点符号之后的字符串。在这里插入图片描述

转移符号Logger nameResult
%loggermainPackage.sub.sample.BarmainPackage.sub.sample.Bar
%logger{0}mainPackage.sub.sample.BarBar
%logger{5}mainPackage.sub.sample.Barm.s.s.Bar
%logger{10}mainPackage.sub.sample.Barm.s.s.Bar
%logger{15}mainPackage.sub.sample.Barm.s.sample.Bar
%logger{16}mainPackage.sub.sample.Barm.sub.sample.Bar
%logger{26}mainPackage.sub.sample.BarmainPackage.sub.sample.Bar
输出Class类全限定名

输出执行记录请求的调用者的全限定名。参数与上面的一样。尽量避免使用,除非执行速度不造成任何问题。
在这里插入图片描述

输出上下文名称

在Logback中,可以通过contextName属性来获取Logger的上下文名称,通过cn来获取调用者的全限定名。这两个属性可以在Logback的配置文件中进行配置。

要获取contextName属性,可以使用以下方式:

<property name="contextName" value="${logback.contextName}" />

然后,在日志输出中使用${contextName}占位符来获取上下文名称。要获取调用者的全限定名,可以使用以下方式:

<encoder>
    <pattern>%X{cn} - %msg%n</pattern>
</encoder>

在这种情况下,会将调用者的全限定名存储在MDC(Mapped Diagnostic Context)的cn键中,然后在日志输出模式中使用%X{cn}来获取。

日志的打印日期时间

在Logback中,可以使用%d{pattern}来指定日期的格式化模式,其中pattern与SimpleDateFormat中的模式语法相同。
在这里插入图片描述
以下是一些常用的日期格式化模式示例:

  • %d{yyyy-MM-dd HH:mm:ss}:输出格式为年-月-日 时:分:秒
  • %d{yyyy/MM/dd HH:mm:ss}:输出格式为年/月/日 时:分:秒
  • %d{yyyy-MM-dd HH:mm:ss.SSS}:输出格式为年-月-日 时:分:秒.毫秒
  • %d{EEE MMM dd HH:mm:ss Z}:输出格式为星期几 月份 日 时:分:秒 时区
  • %d{HH:mm:ss.SSS}:输出格式为时:分:秒.毫秒

你可以根据需要选择合适的日期格式化模式,然后将其放置在Logback配置文件中的适当位置来格式化打印的日志信息中的日期。

Conversion PatternResult
%d2006-10-20 14:06:49,812
%date2006-10-20 14:06:49,812
%date{ISO8601}2006-10-20 14:06:49,812
%date{HH:mm:ss.SSS}14:06:49.812
%date{dd MMM yyyy ;HH:mm:ss.SSS}20 oct. 2006;14:06:49.812
输出信息深度

输出生成日志的调用者的位置信息,整数选项表示输出信息深度。

caller{depth}caller{depth, evaluator-1, ... evaluator-n}
案例分析

%caller{2}

0 [main] DEBUG - logging statement
Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)

%caller{3}

16 [main] DEBUG - logging statement
Caller+0 at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1 at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)
F / file 输出源文件名
Conversion PatternResult
%F输出执行记录请求的Java源文件名。请谨慎使用,可能会影响执行速度。
其他格式符号
Conversion PatternResult
%L输出执行日志请求的行号。请谨慎使用,可能会影响执行速度。
%m / %msg / %message输出应用程序提供的信息。
%M输出执行日志请求的方法名。请谨慎使用,可能会影响执行速度。
%n输出平台相关的分行符“\n”或者“\r\n”。
%p / %le / %level输出日志级别。
%r / %relative输出从程序启动到创建日志记录的时间,单位是毫秒。
%t / %thread输出产生日志的线程名。
%replace(%p, {r, t})p 为日志内容,r 是正则表达式,将p 中符合r 的内容替换为t。

格式修饰符

格式修饰符与转换符共同使用,可用于对输出进行格式修饰和优化。

第一个可选的修饰符是左对齐标志,用减号“-”表示。接下来是可选的最小宽度修饰符,用十进制数表示。如果字符数小于最小宽度,则会进行左填充或右填充,默认为左填充(即右对齐),使用空格作为填充符。

如果字符数大于最小宽度,则字符永远不会被截断。最大宽度修饰符由点号"."后跟十进制数表示。如果字符数大于最大宽度,则会从头部开始截断。点号后面加上减号“-”和数字表示从尾部截断。

例如,%-4relative 表示将输出从程序启动到创建日志记录的时间进行左对齐,并且最小宽度为4。

配置详解 <filter>

过滤器(<filter>)用于对日志进行过滤。

在这里插入图片描述

执行过滤器会返回一个枚举值,即DENY、NEUTRAL或ACCEPT中的其中一个。

  • 如果返回DENY,则日志将立即被抛弃,不再经过其他过滤器的处理;
  • 如果返回NEUTRAL,则下一个在有序列表中的过滤器会继续处理日志;
  • 如果返回ACCEPT,则日志会立即被处理,不再经过剩余的过滤器。

过滤器可以被添加到<Appender>(日志处理器)中。当为<Appender>添加一个或多个过滤器时,可以使用任意条件对日志进行过滤。如果<Appender>中存在多个过滤器,那么过滤器会按照配置顺序依次执行。

LevelFilter(级别过滤器):

级别过滤器是一种根据日志级别进行过滤的机制。当日志级别与配置的级别相等时,过滤器会根据onMatchonMismatch进行相应的操作。该过滤器包含以下子节点:

  • <level>:用于设置过滤级别。
  • <onMatch>:用于配置符合过滤条件的操作。
  • <onMismatch>:用于配置不符合过滤条件的操作。

例如,将过滤器的日志级别配置为INFO,那么所有INFO级别的日志都会被交给适当的appender进行处理,而非INFO级别的日志则会被过滤掉。

     <configuration>   
      <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">   
        <filter class="ch.qos.logback.classic.filter.LevelFilter">   
          <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" />   
      </root>   
    </configuration>  
ThresholdFilter(临界值过滤器)

临界值过滤器根据指定的临界值来过滤低于该临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL(中性);当日志级别低于临界值时,日志会被拒绝。

例如,如果希望过滤掉所有低于INFO级别的日志,则可以将临界值设置为INFO。如果还有其他需要帮助的地方,请随时告诉我。

     <configuration>   
      <appender name="CONSOLE"   
        class="ch.qos.logback.core.ConsoleAppender">   
        <!-- 过滤掉 TRACE 和 DEBUG 级别的日志-->   
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">   
          <level>INFO</level>   
        </filter>   
        <encoder>   
          <pattern>   
            %-4relative [%thread] %-5level %logger{30} - %msg%n   
          </pattern>   
        </encoder>   
      </appender>   
      <root level="DEBUG">   
        <appender-ref ref="CONSOLE" />   
      </root>   
    </configuration>  
EvaluatorFilter(求值过滤器):

求值过滤器用于评估和鉴别日志是否符合指定条件。

<evaluator>(鉴别器):

鉴别器是常用的求值器,其中最常用的是JaninoEventEvaluator(Janino事件评估器),也是默认的鉴别器。它接受一个任意的 Java 布尔值表达式作为求值条件,并在配置文件解释过程中动态编译这个布尔值表达式。如果布尔值表达式返回 true,则表示符合过滤条件。evaluator 还包含一个子标签 <expression>,用于配置求值条件。

求值表达式作用于当前日志,logback向求值表达式暴露日志的各种字段:

NameTypeDescription
eventLoggingEvent与记录请求相关联的原始记录事件,下面所有变量都来自 event,例如,event.getMessage() 返回下面 “message” 相同的字符串
messageString日志的原始消息,例如,设有 logger mylogger,“name” 的值是 “AUB”,对于 mylogger.info(“Hello {}”,name); “Hello {}” 就是原始消息
formattedMessageString日志被格式化的消息,例如,设有 logger mylogger,“name” 的值是 “AUB”,对于 mylogger.info(“Hello {}”,name); “Hello Aub” 就是格式化后的消息
loggerStringlogger 名
loggerContextLoggerContextVO日志所属的 logger 上下文
levelint级别对应的整数值,所以 level > INFO 是正确的表达式
timeStamplong创建日志的时间戳
markerMarker与日志请求相关联的 Marker 对象,注意 “Marker” 有可能为 null,所以你要确保它不能是 null
mdcMap包含创建日志期间的 MDC 所有值的 map。访问方法是:mdc.get(“myKey”) 。mdc.get() 返回的是 Object 不是 String,要想调用 String 的方法就要强转
throwablejava.lang.Throwable如果没有异常与日志关联,“throwable” 变量为 null。不幸的是,“throwable” 不能被序列化。在远程系统上永远为 null。对于与位置无关的表达式请使用下面的变量 throwableProxy
throwableProxyIThrowableProxy与日志事件关联的异常代理。如果没有异常与日志事件关联,则变量 “throwableProxy” 为 null。当异常被关联到日志事件时,“throwableProxy” 在远程系统上不会为 null
过滤掉所有日志消息中不包含“billing”字符串的日志
     <configuration>   
       
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">   
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">         
          <evaluator> <!-- 默认为 ch.qos.logback.classic.boolex.JaninoEventEvaluator -->   
            <expression>return message.contains("billing");</expression>   
          </evaluator>   
          <OnMatch>ACCEPT </OnMatch>  
          <OnMismatch>DENY</OnMismatch>  
        </filter>   
        <encoder>   
          <pattern>   
            %-4relative [%thread] %-5level %logger - %msg%n   
          </pattern>   
        </encoder>   
      </appender>   
       
      <root level="INFO">   
        <appender-ref ref="STDOUT" />   
      </root>   
    </configuration>  

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CDH 之 Hive 中文乱码平定通用法则

一、乱象 1.1 中文注释乱码 hive> DESCRIBE test; OK # col_name data_type comment id string ??ID ?? pcs string ????? …

java实现远程执行Linux下的shell脚本

java实现远程执行Linux下的shell脚本 背景导入Jar包第一步&#xff1a;远程连接第二步&#xff1a;开启Session第三步&#xff1a;新建测试脚本文件结果报错 背景 最近有个项目&#xff0c;需要在Linux下的服务器内写了一部分Python脚本&#xff0c;业务处理却是在Java内&…

采用三五555时基电路的简易/自动温度控制器电路设计

采用 555 时基电路的简易温度控制器 本电路是采用555时基集成电路和很少的外围元件组成的一个温度自动控制器。因为电路中各点电压都来自同一-直流电源&#xff0c;所以不需要性能很好的稳压电源&#xff0c;用电容降压法便能可靠地工作。电路元件价格低、体积小、便于在业余条…

喜报!Coremail实力上榜“邮件安全网关”和“反钓鱼”等三大赛道!

6月28日&#xff0c;由国内首家专业聚焦网络安全商业市场研究分析和加速服务的机构斯元商业咨询出品的「网安新兴赛道厂商速查指南|短名单精选」&#xff08;以下简称「短名单精选」&#xff09;正式出炉。 Coremail凭借出色的综合能力&#xff0c;成功上榜“邮件安全网关&…

最新导则下生态环评报告编制要求与规范

根据生态环评内容庞杂、综合性强的特点&#xff0c;依据生态环评最新导则&#xff0c;将内容分为4大篇章(报告篇、制图篇、指数篇、综合篇)、10大专题(生态环评报告编制、土地利用图的制作、植被类型及植被覆盖度图的制作、物种适宜生境分布图的制作、生物多样性测定、生物量及…

Django 的 REST framework 基础知识

系列文章目录 提示&#xff1a;阅读本章之前&#xff0c;请先阅读目录 文章目录 系列文章目录前言1. 创建django项目2. 修改settings.py3. 根目录创建static文件夹4. 启动项目5. 创建数据表6. 创建一个超级管理员7. 登录django的admin后台8. 安装 REST framework9. 配置setting…

Quiz 16_3-2: Databases | Python for Everybody 配套练习_解题记录

文章目录 Python for Everybody课程简介Quiz 16_3-2: Databases单选题&#xff08;1-10&#xff09;操作题Autograder 1: Counting Email in a DatabaseAutograder 2: Multi-Table Database - Tracks Python for Everybody 课程简介 Python for Everybody 零基础程序设计&…

数据库管理-第八十七期 19c OCM之路-第一堂(02)(20230630)

第八十六期 19c OCM之路-第一堂&#xff08;02&#xff09; 本来计划是昨天写的&#xff0c;但是昨天突发膝盖筋膜炎&#xff0c;去骨科医院做了下治疗&#xff0c;前后两夜几乎无眠。本期内容主要是针对第一堂第四个考点&#xff1a;Manage application containers内容去做的…

Spring Boot中的@MessageMapping注解:原理及使用

Spring Boot中的MessageMapping注解&#xff1a;原理及使用 简介 在Web应用程序中&#xff0c;实现实时的双向通信是一项重要的功能。为了实现这种功能&#xff0c;需要使用WebSocket协议。Spring框架提供了Spring WebSocket模块来实现WebSocket通信。Spring Boot是基于Sprin…

《刷题日记03》链表

题目描述力扣https://leetcode.cn/problems/LGjMqU/ 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln-1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → … 不能只是单纯的改变节点内部的值…

实例003 像开始菜单一样漂亮的菜单

实例说明 Windows的开始菜单非常的独特&#xff0c;在菜单的旁边有一条竖着的彩条&#xff0c;彩条中还写着文字。这种独特的菜单能够使程序的界面看起来更加的漂亮。本例中就实现了这种菜单&#xff0c;运行本例弹出“打开菜单”时&#xff0c;就会看到菜单的左边有一个紫色的…

ChatGPT微调系列一:微调 流程

文章目录 前言一、啥叫微调二、为啥要微调三、不是所有模型都可以微调的四、总述微调的基本流程&#xff0c;以及涉及的主要函数&#xff0c;参数1. 安装2. 准备训练数据3. openai.api_key os.getenv() 进行一个说明4. 通过API 调用模型 常用函数5. 微调模型 常用函数6. OpenA…

【论文阅读】Self-supervised Image-specific Prototype Exploration for WSSS

一篇CVPR2022上的论文&#xff0c;用于弱监督分割 论文标题&#xff1a; Self-supervised Image-specific Prototype Exploration for Weakly Supervised Semantic Segmentation 作者信息&#xff1a; 代码地址&#xff1a; https://github.com/chenqi1126/SIPE 论文链接&…

【doxygen】markdown 表格中插入换行与缩进

文章目录 markdown 表格换行markdown 标准换行doxygen 中 markdown 表格换行 markdown 表格缩进 doxygen 中使用 markdown markdown 表格换行 markdown 表格生成 doxygen 时换行与标准的 markdown 语法稍有差异 markdown 标准换行 markdown 中可以使用 html 的换行标签 <…

Python学习之文件操作【基本操作,JSON文件操作】

前言 Python的文件操作是一个非常重要的主题&#xff0c;它可以用来读取&#xff0c;写入和操作各种类型的文件&#xff0c;包括文本文件、图像文件、音频文件等。在这里&#xff0c;我们将讨论一些基本的Python文件操作和JSON文件操作。 Python文件操作 Python提供了多种方…

73、基于51单片机温湿度光照检测控制esp8266无线WiFi app远程监测报警(程序+原理图+PCB源文件+参考论文+开题报告+元器件清单等)

研究目的 现代的生活中&#xff0c;许多情况都对环境的温湿度有比较严格的要求&#xff0c;因此&#xff0c;必须在某些特定环境安装温湿度报警器对环境的温湿度进行监控和调节。为此&#xff0c;本题目选用花卉温室的温湿度调节为背景环境&#xff0c;研究利用集成温湿度传感…

赛效:PDF文件怎么加密

1&#xff1a;在网页上打开并登录91ai工具&#xff0c;在特色功能里点击“PDF加密”。 2&#xff1a;点击上传文件&#xff0c;将本地PDF文件添加上去。 3&#xff1a;文件上传成功后&#xff0c;在文件下方设置密码后点击“开始加密”。 4&#xff1a;加密完成后点击下方下载按…

YOLOv5改进系列(12)——更换Neck之BiFPN

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制

浅谈安科瑞电力监控系统解决方案 安科瑞 许敏

摘要&#xff1a;随着经济的发展&#xff0c;能源消耗速度正不断加快&#xff0c;因此我国提出了绿色可持续发展战略&#xff0c;要求在发展建设中以节能为主&#xff0c;不断减少资源能耗&#xff0c;而电能便是首要控制内容。如今我国为电能使用&#xff0c;对计量表进行了优…

Web 应用程序综合监控

综合监控是什么意思 模拟用户通过 Web 应用程序的旅程并对其进行监控以检测任何增加延迟的元素的过程被广泛称为综合监控或综合测试。 为什么需要综合监测 为了确保最终用户的无缝体验&#xff0c;综合性能监控势在必行。监视综合事务以帮助您了解用户如何与 Web 应用程序交…