logback

发布时间 2023-06-30 09:24:20作者: 党王

1.logback是什么?

  Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-classiclogback-accesslogback-core是其它两个模块的基础模块。logback-classiclog4j的一个改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日记系统如log4jJDK14 Logging

2.logback有效不冗余的使用技巧

  1. 使用合适的日志级别:在编写日志语句时,要根据日志的重要性选择合适的日志级别。一般来说,ERROR 级别的日志记录了严重的错误,WARN 级别的日志记录了潜在的问题,INFO 级别的日志记录了一般的信息,DEBUG 级别的日志记录了调试信息,TRACE 级别的日志记录了更详细的调试信息。

  2. 配置日志输出格式:在 logback.xml 文件中可以配置日志输出的格式,包括时间戳、日志级别、线程名、类名、方法名、日志信息等等。通过配置输出格式可以使日志更易读。

  3. 避免在生产环境输出过多的日志:在生产环境中,日志输出量应该尽量减少,以避免对系统性能的影响。可以通过配置日志级别和日志输出目的地来控制日志的输出。

  4. 使用 MDC 和 NDC:MDC(Mapped Diagnostic Context)和 NDC(Nested Diagnostic Context)是 Logback 提供的两种上下文信息传递机制。通过使用 MDC 和 NDC,可以在日志中输出一些上下文信息,比如用户 ID、请求 ID 等等。这些信息可以在出现问题时帮助快速定位问题。

  5. 使用异步日志:异步日志可以将日志记录和日志输出分离,从而提高系统的性能。在 Logback 中,可以通过配置异步 Appender 来实现异步日志。

  6. 使用 RollingFileAppender:RollingFileAppender 可以自动分割日志文件,防止日志文件过大。可以通过配置 RollingFileAppender 来实现日志文件的分割和压缩。

  7. 使用 LoggerContext:LoggerContext 是 Logback 中的上下文对象,可以通过它来管理 Logger、Appender、Filter 等组件。可以通过 LoggerContext 来配置和管理 Logback。

3.日志级别

ALL < TRACE < DEBUG < INFO < WARN < ERROR <FATAL <OFF

4,logback的使用

 

       <!--slf4j日志门面-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>
        <!--logback日志实现-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>${logback.version}</version>
    </dependency>

 

 

 

5,logback的Spring项目基本使用

public class MyTest{

    public static final Logger LOGGER = LoggerFactory.getLogger(MyTest.class);

    @Test
    public void test() {
            LOGGER.error("error");
            LOGGER.warn("wring");
            LOGGER.info("info");
            LOGGER.debug("debug");
            LOGGER.trace("trace");
    }
}


//打印信息如下
18:05:38.202 [main] ERROR cn.ybzy.Logback - error
18:05:38.206 [main] WARN cn.ybzy.Logback - wring
18:05:38.207 [main] INFO cn.ybzy.Logback - info
18:05:38.207 [main] DEBUG cn.ybzy.Logback - debug

6,logback与springboot整合(logback.xml配置信息见8标题内容)

#在application文件中配置logback的路径
logging:
  config: classpath:logback.xml    

 7,与lombok集成。

   <!--  lombok和logback依赖 -- >
 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

7.1,lombok继承后使用方法

@Slf4j //使用注解初始化logback
public class MyTest {

    public static void main(String[] args) {
        log.info("info.....");
        log.warn("warn" + ".....");
        log.error("error,msg={}", "error....");
    }
}

8,logback配置

  8.1,logback组件,及之间的关系

 

logger:日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
layout:负责把事件转换成字符串,格式化的日志信息的输出。在logback中Layout对象被封装在encoder中。
logger context:
各个logger 都被关联到一个 LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各logger。其他所有logger也通过org.slf4j.LoggerFactory 类的静态方法getLogger取得。 getLogger方法以 logger名称为参数。用同一名字调用LoggerFactory.getLogger 方法所得到的永远都是同一个logger对象的引用。

 

  8.2,logger配置基本结构:以<configuration>开头,后面有零个或多个<appender>元素,有零个或多个<logger>元素,有最多一个<root>元素。

    8.2.1:根节点<configuration>,包含下面三个属性:     

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

    8.2.2:子节点<contextName>:用来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改

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

    8.2.3:子节点<property> :用来定义变量值,它有两个属性name和value,通过<property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量。

 

<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
   <property name="APP_Name" value="myAppName" /> 
   <contextName>${APP_Name}</contextName> 
   <!--其他配置省略--> 
    <property name="log.path" value="./logs"/>
    <property name="console.log.pattern" value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/>
</configuration>

    8.2.4:子节点<timestamp>:获取时间戳字符串,他有两个属性key和datePattern

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

   8.2.5:子节点<appender>:负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名

     (1)、ConsoleAppender 把日志输出到控制台,有以下子节点:
       <encoder>:对日志进行格式化。
       <target>:字符串System.out(默认)或者System.err(区别不多说了)

 

<configuration> 
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <encoder>
<!--控制输出流对象 默认 System.out(黑色) 改为 System.err(红色)-->  
      <target>System.err</target>
<!-- 对记录事件进行格式化。1.把日志信息转换成字节数组 2.把字节数组写入到输出流 -->  
      <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- console.log.pattern 这个参数在上面property参数定义了,Class的值标识将数据输入到控制台-->
      <pattern>${console.log.pattern}</pattern>  
      <charset>utf-8</charset>
      </encoder>
   </appender> 
<!-- 下述配置表示把>=DEBUG级别的日志都输出到控制台 -->
   <root level="DEBUG">
      <appender-ref ref="STDOUT" />
    </root>
</configuration>

 

    (2)、FileAppender:把日志添加到文件,有以下子节点:

 

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

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

       <encoder>:对记录事件进行格式化。(具体参数稍后讲解 )
       <prudent>:如果是 true,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n"></property>
    <!--定义日志文件保存路径属性-->
    <property name="log_dir" value="d:/logs"></property>
    <!--日志文件输出的 appender-->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!--日志文件保存路径-->
        <file>${log_dir}/logback.log</file>
     <append>true</append>
     <!--日志消息格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> </appender> <!--root logger 配置--> <root level="ALL"> <appender-ref ref="file"/> </root> </configuration>

 

      (3)、RollingFileAppender配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!--属性配置管理,供引用使用-->
    <!--定义日志输出内容的格式-->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n"></property>

    <!--定义日志文件保存路径属性-->
    <property name="log_dir" value="d:/logs"></property>
    
    <!--日志拆分和归档压缩的appender对象-->
    <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件保存路径-->
        <file>${log_dir}/roll_logback.log</file>
        <!--日志消息格式配置-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!--指定拆分规则-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按照时间和压缩格式声明拆分的文件名-->
            <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}.log%i.zip</fileNamePattern>
            <!-- <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}.log%i</fileNamePattern>-->
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <!--按照文件大小拆分,日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始 -->
            <maxFileSize>1MB</maxFileSize>
        </rollingPolicy>
<!-- 当文件大于5MB时,生成新的日志文件。-->
      <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
          <maxFileSize>5MB</maxFileSize>
      </triggeringPolicy
    </appender>
    <!--root logger 配置-->
    <root level="ALL">
        <appender-ref ref="rollFile"/>
    </root>

</configuration>

      (4)、子节点<logger>:用来设置某一个包或具体的某一个类的日志打印级别、以及指定<appender>

        <logger>仅有一个name属性,一个可选的level和一个可选的additivity属性。

<!--常用logger配置 -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
<!--myibatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>

      (5)、子节点<root>:它也是<logger>元素,但是它是根logger,是所有<logger>的上级。只有一个level属性,因为name已经被命名为"root",且已经是最上级了。

        level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,不能设置为INHERITED或者同义词NULL。 默认是DEBUG。

 <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="async_info" />
        <appender-ref ref="async_error" />
        <appender-ref ref="file_console" />
<!--        <appender-ref ref="sky_log"/>-->
    </root>

       (6)、filter配置

        根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据 onMath (用于配置符合过滤条件的操作) 和 onMismatch (用于配置不符合过滤条件的操作)接收或拒绝日志

<!--日志拆分和归档压缩的appender对象-->
    <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <!--日志级别过滤器-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--日志过滤规则-->
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

      8.3:异步日志配置

 <!-- info异步输出 -->
    <appender name="async_info" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="file_info"/>
    </appender>

    <!-- error异步输出 -->
    <appender name="async_error" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="file_error"/>
    </appender>

 9、example

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="log.path" value="./logs"/>
    <property name="console.log.pattern"
              value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/>

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

    <!-- 控制台输出 -->
    <appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-console.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大 1天 -->
            <maxHistory>1</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
            <charset>utf-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
        </filter>
    </appender>

    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- info异步输出 -->
    <appender name="async_info" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="file_info"/>
    </appender>

    <!-- error异步输出 -->
    <appender name="async_error" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="file_error"/>
    </appender>

    <!-- 整合 skywalking 控制台输出 tid -->
<!--    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
<!--        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!--            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!--                <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!--            </layout>-->
<!--            <charset>utf-8</charset>-->
<!--        </encoder>-->
<!--    </appender>-->

    <!-- 整合 skywalking 推送采集日志 -->
<!--    <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
<!--        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!--            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!--                <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!--            </layout>-->
<!--            <charset>utf-8</charset>-->
<!--        </encoder>-->
<!--    </appender>-->

    <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="async_info" />
        <appender-ref ref="async_error" />
        <appender-ref ref="file_console" />
<!--        <appender-ref ref="sky_log"/>-->
    </root>

</configuration>