Loading

mybatis+logback日志实现

前言

在学习mybatis过程中,我们知道。mybatis支持一下几种日志的实现

  • SLF4J

  • Apache Commons Logging

  • Log4j 2

  • Log4j

  • JDK logging

虽然logback不在mybatis的官方网站支持的日志目录里,但logback是SLF4J的框架

可以理解为:SLF4J是一种日志标准,logback是实现这个标准的一种框架。

mybatis如果想要使用日子,需要在mybatis的核心配置文件中加上

<settings>
     <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

如果在resources文件夹下配置了SLF4J等日志工具,这个setting可以不加。mybais会自动查找相关日志的配置。

logback日志配置

可以参考:https://blog.csdn.net/qq_20185737/article/details/131234076

配置文件

logback.xml 是 Logback 日志框架的配置文件

image-20240508214313187

通过 logback.xml 文件,可以配置日志的输出格式、日志级别、日志文件路径等信息

  • 配置文件必须放在类的根路径下,不能是其它位置

  • 配置文件的名字必须叫做:logback.xml或者logback-test.xml,不能是其它名字

Logback 是一个常用的日志框架,帮助开发人员记录应用程序中的各种事件和错误信息,便于问题排查和调试

logback日志配置项

logback日志配置文件中有几个重要的标签

configuration

<configuration  scan="true" scanPeriod="10 seconds" debug="false">
    ...
</configuration>

configuration根标签,所有的配置都在该标签内进行:

  • scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true

  • scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。

    • 当scan为true时,此属性生效。默认的时间间隔为1分钟
  • debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false

Pattern

<pattern>
    %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) 			  		%boldMagenta(%logger{36}%n) - %msg%n
</pattern>

指定日志输出的格式

  • 可查看文档https://blog.csdn.net/qq_20185737/article/details/131234076,这里不赘述

Appender

附加器,用来定义日志输出的目的地。有多个实现

ConsoleAppender

将日志输出到控制台

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  <!-- 日志输出格式 -->
  <encoder>
    <pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
  </encoder>
</appender>

说明:

  • name: Appender 的名称,可自定义。
  • class: 指定 Appender 的类,这里是 ConsoleAppender。
  • encoder: Encoder 用于将日志事件转换为输出字符串的格式,可以根据需要自定义。
  • pattern: 输出格式,这里使用了时间戳、日志级别、Logger 名称、消息文本等信息
    • 习惯上使用${property.name}表达式引用已经定义好的日志格式

FileAppender

将日志输出到文件中

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <!-- 日志输出路径 -->
  <file>/logs/file.log</file>
  <!-- 日志输出格式 -->
  <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - 	    	      	  %msg%n</pattern>
  </encoder>
</appender>

说明:

  • <file>:元素指定了日志文件的路径和名称

RollingFileAppender

是Logback常用的日志输出组件之一,可以**按照一定的条件对日志文件进行滚动输出 **

<!--RollingFileAppender 文件滚动输出-->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">

  <!-- 日志输出的路径 -->
  <file>logs/myapp.log</file>

  <!-- 基于时间和文件大小的滚动策略 -->
  <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <!-- 基于时间创建日志文件 -->
    <fileNamePattern>logs/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
    <!-- 最大文件大小,超过该大小则进行日志滚动 -->
    <maxFileSize>10MB</maxFileSize>
    <!-- 最大的历史日志文件数量 -->
    <maxHistory>7</maxHistory>
  </rollingPolicy>
    
  <!-- 日志输出格式 -->
  <encoder>
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - 	 		%msg%n</pattern>
  </encoder>
</appender>

说明:

image-20240508220331881

SMTPAppender

日志信息以电子邮件形式发送到指定的收件人

<!-- name的值是变量的名称,source为 yaml 配置文件中的变量。定义后,可以使“${}”来使用变量。 -->
<springProperty scope="context" name="user.host" source="spring.mail.host" defaultValue="smtp.qq.com"/>
<springProperty scope="context" name="user.email" source="spring.mail.username"/>
<springProperty scope="context" name="user.email.password" source="spring.mail.password"/>

<!--发QQ邮件-->
<appender name="QQEMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
  <!-- SMTP server的地址 -->
  <smtpHost>${user.host}</smtpHost>
  <!-- SMTP server的端口地址 -->
  <smtpPort>465</smtpPort>
  <!--发件人账号-->
  <username>${user.email}</username>
  <!--发件人密码-->
  <password>${user.email.password}</password>
  <!--SSL连接到日志服务器,默认值:false-->
  <SSL>true</SSL>
  <!--异步发送-->
  <asynchronousSending>true</asynchronousSending>
  <!--收件人账号,多个用逗号隔开-->
  <to>${user.email}</to>
  <!-- 发件人名称 -->
  <from>${user.email}</from>
  <!-- emial的标题 -->
  <subject>【Error】:%logger{0}</subject>
  <!-- 编码 -->
  <charsetEncoding>UTF-8</charsetEncoding>
  
  <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
    <!-- 每个电子邮件只发送一个日志条目 -->
    <bufferSize>10</bufferSize>
  </cyclicBufferTracker>
  
  <!--HTML展示-->
  <layout class="ch.qos.logback.classic.html.HTMLLayout" />
  <!--文本展示-->
  <!--<layout class="ch.qos.logback.classic.layout.TTLLLayout"/>-->
  
  <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <!--错误级别(只会提示大于该级别的错误)-->
    <level>ERROR</level>
  </filter>
</appender>

配置的说明参考:https://blog.csdn.net/qq_20185737/article/details/131234076

DBAppender

更改 Logback 的配置文件以引入 DBAppender,并配置连接数据库的相关参数

以下示例使用 MySQ 作为数据库:

<!-- 日志输出 MySQL -->
<appender name="MYSQL" class="ch.qos.logback.classic.db.DBAppender">
  <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
    <!--数据库驱动-->
    <driverClass>com.mysql.cj.jdbc.Driver</driverClass>
    <!--数据库 Url-->
    <url>jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</url>
    <!--数据库用户名-->
    <user>root</user>
    <!--数据库密码-->
    <password>root</password>
  </connectionSource>
</appender>

参数如下:

image-20240508220819768

Logger

Logback 中的 Logger 是一种记录日志的对象,其作用是在程序运行时记录日志信息

  • Logger 表示打印不同级别的日志,从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL

  • Logger 还可以通过添加 Appender 来控制日志信息的输出目标,比如输出到控制台或文件

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

说明:

image-20240508221345891

Root

在 Logback 中,root 是指最高级别的 Logger,它是所有 Logger 的父 Logger

所有未被其他日志记录器匹配的日志事件都会由 root处理

可以通过设置 root 的日志级别和输出目的地来控制应用程序的整个日志记录

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="info">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

Filter

Filter过滤器,是附加器的一个组件,它用于决定附加器是否输出日志

  • 一个附加器可以包含一个或多个过滤器
  • 每个过滤器部会返回一个枚举值:DENY、NEUTRAL、ACCEPT
    • DENY:不输出日志
    • ACCEPT:输出日志
    • NEUTRAL:中立,即不决定是否输出日志

Filter过滤器是一种可插拔的模块,有多个实现

image-20240508221924621

LevelFilter

根据日志级别进行过滤

  • 如果日志级别等于配置级别,过滤器会根据 onMath 和 onMismatch 接收或拒绝日志
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  <encoder>
    <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
  </encoder>
  <filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>INFO</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
  </filter>
</appender>

在这个过滤器中,表示只过滤INFO级别的日志,如果匹配成功就ACCEPT(接受,打印日志),失败就DENY(不打印)

ThresholdFilter

临界值过滤器

  • 日志级别低于临界值,不打印日志。不低于就打印
<!-- 定义一个Logger -->
<logger name="com.example" level="DEBUG" additivity="false">
  <appender-ref ref="stdout" />
  <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>INFO</level>
  </filter>
</logger>

说明:针对com.example包下 的日志,会阻止 com.example 包下面的 DEBUG 级别的日志消息输出到控制台,只允许INFO级别和更高级别的日志消息通过

EvaluatorFilter

<root level="DEBUG">
  <appender-ref ref="STDOUT" />
  <filter class="ch.qos.logback.classic.filter.EvaluatorFilter">
    <evaluator>
      <expression>return message.contains("error")</expression>
    </evaluator>
    <onMatch>DENY</onMatch>
    <onMismatch>NEUTRAL</onMismatch>
  </filter>
</root>

EvaluatorFilter 被用作根日志记录器的过滤器:

  • 表示日志消息中是否包含“error”字符串
    • 如果是,则过滤器的 onMatch 属性指示日志事件被拒绝
    • 如果不是,则 onMismatch 属性指示日志事件将继续向下传递
    • 最终,只有那些不包含“error”字符串的日志消息才会被输出到控制台,其他日志消息将被过滤掉。

logback.xml样例

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
    <property name="log.path" value="logs"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
    <!-- 日志控制台输出格式 -->
    <property name="log.console.pattern" value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>

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

    <!--INFO 文件输出-->
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 文件路径/文件名 -->
        <file>${log.path}/myapp-info.log</file>
        <!-- 基于时间和文件大小的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 基于时间创建日志文件 -->
            <fileNamePattern>${log.path}/info/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 最大文件大小,超过该大小则进行日志滚动 -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 最大的历史日志文件数量 -->
            <maxHistory>7</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>

    <!-- 系统日志输出 debug-->
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 文件路径/文件名 -->
        <file>${log.path}/myapp-debug.log</file>
        <!-- 基于时间和文件大小的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 基于时间创建日志文件 -->
            <fileNamePattern>${log.path}/debug/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 最大文件大小,超过该大小则进行日志滚动 -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 最大的历史日志文件数量 -->
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>DEBUG</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 系统日志输出 error-->
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 文件路径/文件名 -->
        <file>${log.path}/myapp-error.log</file>
        <!-- 基于时间和文件大小的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 基于时间创建日志文件 -->
            <fileNamePattern>${log.path}/error/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 最大文件大小,超过该大小则进行日志滚动 -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 最大的历史日志文件数量 -->
            <maxHistory>7</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>

    <!-- 用户访问日志输出  -->
    <appender name="USER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 文件路径/文件名 -->
        <file>${log.path}/myapp-user.log</file>
        <!-- 基于时间和文件大小的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 基于时间创建日志文件 -->
            <fileNamePattern>${log.path}/user/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 最大文件大小,超过该大小则进行日志滚动 -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 最大的历史日志文件数量 -->
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!--系统操作日志-->
    <root level="info">
        <!-- 全局日志输出级别,info 以上输出到控制台 -->
        <appender-ref ref="CONSOLE"/>
        <!--appender将会添加到logger-->
        <appender-ref ref="INFO"/>
        <appender-ref ref="DEBUG"/>
        <appender-ref ref="ERROR"/>
    </root>

    <!--系统用户操作日志-->
    <logger name="sys-user" level="info">
        <appender-ref ref="USER"/>
    </logger>
</configuration>

说明一下:

  • 在root标签中,引入了CONSOLE附加器,但是CONSOLE中没有定义日志级别,使用的就是root指定的info级
    • 表示大于等于info级别的日志输出到控制台,相当于默认使用的过滤器是ThresholdFilter临界值过滤器

mybatis基于logback日志实现

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 日志存放路径 -->
   <property name="log.path" value="logs/ruoyi-alg" />
   <!-- 日志输出格式 -->
   <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />

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

    <!-- 系统日志输出 -->
   <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
       <file>${log.path}/info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
         <fileNamePattern>${log.path}/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}/error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/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>

    <!--sql日志-->
    <appender name="sql" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--活动日志输出路径示例-->
        <file>${log.path}/sql.log</file>
        <append>true</append>
        <!--存档日志示例-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/sql.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--存档天数可自定义-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <!-- onMatch:意思是当前级别以及以上要怎么处理 -->
            <onMatch>ACCEPT</onMatch>
            <!-- onMismatch:意思是当前级别(不包括当前级别)以下要怎么处理 -->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--统一日志输出格式-->
        <encoder charset="UTF-8">
            <pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
        </encoder>
    </appender>

    <!--sql输出到控制台,并保存到sql日志文件中 additivity="false"不向上级传递日志-->
    <logger name="com.ruoyi" level="TRACE " additivity="false">
        <appender-ref ref="console"/>
        <appender-ref ref="sql"/>
    </logger>

    <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>

</configuration>
posted @ 2025-07-06 00:08  PursueExcellence  阅读(171)  评论(0)    收藏  举报