React 前端导航

SpringBoot框架中使用P6Spy打印全部SQL

在日常Java开发中经常用到MyBatis框架,在调试的时候,经常因为看不到全部的SQL而不得不手动去拼接SQL。因为笔者查阅了大量资料发现P6Spy框架可以解决此类问题。

首先需要继承P6Spy的依赖

 <!--配置打印SQL语句,执行时间,执行参数-->        <dependency>            <groupId>com.github.gavlyukovskiy</groupId>            <artifactId>p6spy-spring-boot-starter</artifactId>            <version>${p6spy.version}</version>        </dependency>

此处我使用的版本是

    <p6spy.version>1.8.0</p6spy.version>

接下来需要配置spy.properties配置文件,我的配置文件如下:

#MODULE p6spy提供了两种模块进行日志记录:log和outage,两者有不同的功能,配置参数也有专属,但是它们也共享一些配置参数,如哪些表被记录,日志文件名称和地址,是否显示sql执行轨迹等。#log用来拦截和记录任何使用jdbc的应用的数据库声明日志,默认为开启。#outage主要是用来最低化log所带来的性能问题,只记录超过一定时间的执行语句,默认为关闭。module.log=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactorymodule.outage=com.p6spy.engine.outage.P6OutageFactorylogMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger#实际的数据库驱动,真正的数据库驱动#realdriver=com.mysql.jdbc.Driver#实际的数据库驱动备份,当前面的数据库驱动不对时,顺序查找下一驱动,直到找到合适为止,默认为空。#realdriver2=#realdriver3=#无效化已注册的驱动,如果在其他地方已经定义好了真正的数据库驱动,那么p6spy driver就不会生效,也就不能起到作用,所以需#要把此选项置为true。deregisterdrivers=true#log模块专属的参数,当log模块开启时,如果执行语句超出这个时间(单位为毫秒),才能被记录在文件中,可以重新被载入,默认为0。executionthreshold=#outage专属的参数,当outage模块开启时,outagedetection为true时,会根据outagedetectioninterval(单位为秒)的大小, 间隔的去捕获执行语句,一般用来捕获长时间执行的语句。。outagedetection=trueoutagedetectioninterval=2#以下参数是公共的属性,log和outage都可以公用的参数过滤器开关,是否根据参数过滤一些记录内容filter=true#当过滤器开启时,需要记录的表,默认为都记录#include=#当过滤器开启时,不需要记录的表,默认为都记录exclude= foreign_key_checks,variable_name,GET_LOCK,RELEASE_LOCK,flyway_schema_history,information_schema,@,SELECT DATABASE(),SELECT version(),ACT_,QRTZ_# 过滤 Log 时的 SQL 正则表达式名称  默认为空#当过滤器开启时,根据sql表达式过滤#sqlexpression =#是否自动刷新autoflush   = true#输出的日志文件的日期格式,也就是用Java的SimpleDateFormat程序。dateformat= yyyy-MM-dd HH:mm:ss#定义包含的日志级别,当日志级别属于此类型时,才能被记录,属性值有error, info, batch, debug, statement, commit, rollback 和result#includecategories=statement#定义不包含的日志级别,当日志级别属于此类型时,不会被记录;#可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.excludecategories=info,debug,result,commit,resultset#使用正则表达式来过滤 Log,匹配时才会被记录,例如: #stringmatcher=com.p6spy.engine.common.GnuRegexMatcher #stringmatcher=com.p6spy.engine.common.JakartaRegexMatcher#stringmatcher=#是否对每一SQL的执行语句进行打印堆栈跟踪信息,通常在进行长时间执行SQL的情况下打开进行监控。stacktrace=false#当上一轨迹开关打开时,可以指定具体的类名来进行过滤。stacktraceclass =#监测属性配置文件是否进行重新加载,一般应用服务器在启动时进行加载一次就够了。reloadproperties=false#当是否重新加载开关打开时,定义重新加载时间周期。reloadpropertiesinterval = 60#是否加上前缀,设置为 true,会加上 p6spy: 作为前缀useprefix=false#指定 Log 的 appender,与 Log4J 有点同义,取值:com.p6spy.engine.logging.appender.Log4jLogger com.p6spy.engine.logging.appender.StdoutLogger com.p6spy.engine.logging.appender.FileLogger# 日志只输出到控制台,不会记录到日志文件appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger# 使用日志系统记录 sql#appender=com.p6spy.engine.spy.appender.Slf4JLogger
#指定记录的日志文件名称和地址,根目录在应用服务器的发布端.如tomcat在%TOMCAT_HOME%/bin目录下。logfile = ./logs/logs.log#文件续载标识,在log的appender类型为FileLogger时,才生效,如果为true,则在生成的日志文件后面继续进行记录,否则删除之前的内容。#append=true#类似与log4j的记录器的布局:#log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender#log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout#log4j.appender.STDOUT.layout.ConversionPattern=p6spy - #%m%n

其中会涉及到两个类

pro.skywalking.configuration.p6spy.P6spyLogFormatStrategy

以及

pro.skywalking.configuration.p6spy.P6SpyLogger

这两个类的主要作用是自定义日志打印规则。

下面是这两个类的主要内容

package pro.skywalking.configuration.p6spy;
import com.p6spy.engine.logging.Category;import com.p6spy.engine.spy.appender.FormattedLogger;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils;
/** * @author Singer create by singer - Singer email:singer-coder@qq.com * @projectName multi-platform * @Description: * @date 2024-05-22 */@Slf4jpublic class P6SpyLogger extends FormattedLogger {
@Override public void logException(Exception e) { log.info("", e); }
@Override public void logText(String text) { log.info(text); }
/** * 根据类别打印不同等级的日志 * * @param connectionId: 连接ID * @param now: 当前时间 * @param elapsed: 花费时间 * @param category: 类别 * @param prepared: 预编译SQL * @param sql: 最终执行的SQL * @param url: 数据库连接地址 * @date 2020/1/16 9:52 * @author lixiangx@leimingtech.com **/ @Override public void logSQL(int connectionId, String now, long elapsed, Category category, String prepared, String sql, String url) {
final String msg = strategy.formatMessage(connectionId, now, elapsed, category.toString(), prepared, sql, url); if (StringUtils.isEmpty(msg)) { return; } if (Category.ERROR.equals(category)) { log.error(msg); } else if (Category.WARN.equals(category)) { log.warn(msg); } else if (Category.DEBUG.equals(category)) { log.debug(msg); } else { log.info(msg); } }
/** * 根据类别开启指定的日志级别 * * @param category 日志类别 * @return 是否开启 * @date 2020/1/16 10:42 * @author lixiangx@leimingtech.com **/ @Override public boolean isCategoryEnabled(Category category) { if (Category.ERROR.equals(category)) { return log.isErrorEnabled(); } else if (Category.WARN.equals(category)) { return log.isWarnEnabled(); } else if (Category.DEBUG.equals(category)) { return log.isDebugEnabled(); } else { return log.isInfoEnabled(); } }
}
package pro.skywalking.configuration.p6spy;
import cn.hutool.core.util.StrUtil;import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
/** * @author Singer create by singer - Singer email:singer-coder@qq.com * @projectName multi-platform * @Description: * @date 2024-05-22 */public class P6spyLogFormatStrategy implements MessageFormattingStrategy {
/** * 日志格式化方式(打印SQL日志会进入此方法,耗时操作,生产环境不建议使用) * * @param connectionId: 连接ID * @param now: 当前时间 * @param elapsed: 花费时间 * @param category: 类别 * @param prepared: 预编译SQL * @param sql: 最终执行的SQL * @param url: 数据库连接地址 * @return 格式化日志结果 * @date 2020/1/16 9:52 * @author lixiangx@leimingtech.com **/ @Override public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) { String sqlMessage = StrUtil.format("链接ID:{},SQL耗时:{}毫秒,\n 连接信息:{},\n 最终执行SQL:{}\n ",connectionId,elapsed,url,sql); return sqlMessage; }}

完成以上操作,启动项目,部署系统,即可打印SQL到控制台。

下面是spy.properties配置文件的其他配置说明,以供参考。

# 指定应用的日志拦截模块,默认为com.p6spy.engine.spy.P6SpyFactory #modulelist=com.p6spy.engine.spy.P6SpyFactory,com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory# 真实JDBC driver , 多个以 逗号 分割 默认为空#driverlist=# 是否自动刷新 默认 flase#autoflush=false# 配置SimpleDateFormat日期格式 默认为空#dateformat=# 打印堆栈跟踪信息 默认flase#stacktrace=false# 如果 stacktrace=true,则可以指定具体的类名来进行过滤。#stacktraceclass=# 监测属性配置文件是否进行重新加载#reloadproperties=false# 属性配置文件重新加载的时间间隔,单位:秒 默认60s#reloadpropertiesinterval=60# 指定 Log 的 appender,取值:#appender=com.p6spy.engine.spy.appender.Slf4JLogger#appender=com.p6spy.engine.spy.appender.StdoutLogger#appender=com.p6spy.engine.spy.appender.FileLogger# 指定 Log 的文件名 默认 spy.log#logfile=spy.log# 指定是否每次是增加 Log,设置为 false 则每次都会先进行清空 默认true#append=true# 指定日志输出样式  默认为com.p6spy.engine.spy.appender.SingleLineFormat , 单行输出 不格式化语句#logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat# 也可以采用  com.p6spy.engine.spy.appender.CustomLineFormat 来自定义输出样式, 默认值是%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)# 可用的变量为:#   %(connectionId)            connection id#   %(currentTime)             当前时间#   %(executionTime)           执行耗时#   %(category)                执行分组#   %(effectiveSql)            提交的SQL 换行#   %(effectiveSqlSingleLine)  提交的SQL 不换行显示#   %(sql)                     执行的真实SQL语句,已替换占位#   %(sqlSingleLine)           执行的真实SQL语句,已替换占位 不换行显示#customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)# date类型字段记录日志时使用的日期格式 默认dd-MMM-yy#databaseDialectDateFormat=dd-MMM-yy# boolean类型字段记录日志时使用的日期格式 默认boolean 可选值numeric#databaseDialectBooleanFormat=boolean# 是否通过jmx暴露属性 默认true#jmx=true# 如果jmx设置为true 指定通过jmx暴露属性时的前缀 默认为空# com.p6spy(.<jmxPrefix>)?:name=<optionsClassName>#jmxPrefix=# 是否显示纳秒 默认false#useNanoTime=false# 实际数据源 JNDI#realdatasource=/RealMySqlDS# 实际数据源 datasource class#realdatasourceclass=com.mysql.jdbc.jdbc2.optional.MysqlDataSource# 实际数据源所携带的配置参数 以 k=v 方式指定 以 分号 分割#realdatasourceproperties=port;3306,serverName;myhost,databaseName;jbossdb,foo;bar# jndi数据源配置 # 设置 JNDI 数据源的 NamingContextFactory。 #jndicontextfactory=org.jnp.interfaces.NamingContextFactory# 设置 JNDI 数据源的提供者的 URL。 #jndicontextproviderurl=localhost:1099# 设置 JNDI 数据源的一些定制信息,以分号分隔。 #jndicontextcustom=java.naming.factory.url.pkgs;org.jboss.naming:org.jnp.interfaces# 是否开启日志过滤 默认false, 这项配置是否生效前提是配置了 include/exclude/sqlexpression#filter=false# 过滤 Log 时所包含的表名列表,以逗号分隔 默认为空#include=# 过滤 Log 时所排除的表名列表,以逗号分隔 默认为空#exclude=# 过滤 Log 时的 SQL 正则表达式名称  默认为空#sqlexpression=#显示指定过滤 Log 时排队的分类列表,取值: error, info, batch, debug, statement,#commit, rollback, result and resultset are valid values# (默认 info,debug,result,resultset,batch)#excludecategories=info,debug,result,resultset,batch# 是否过滤二进制字段# (default is false)#excludebinary=false# P6Log 模块执行时间设置,整数值 (以毫秒为单位),只有当超过这个时间才进行记录 Log。 默认为0#executionThreshold=# P6Outage 模块是否记录较长时间运行的语句 默认false# outagedetection=true|false# P6Outage 模块执行时间设置,整数值 (以秒为单位)),只有当超过这个时间才进行记录 Log。 默认30s# outagedetectioninterval=integer time (seconds)

至此,完成配置spy.properties配置文件的其他配置内容说明,读者可以自行参考。

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/251

#springboot#p6spy

相关推荐

Java 关于SpringBoot的常用的四种读取配置文件的方式

前几天有粉丝问,不能在代码层面将一些常量写死,怎么办?当时我给的回答是可以将常量值放在nacos中,并且项目实现随时刷新nacos的属性值,或是我们可以写在properties当中,当然了你有yml配置文件也是可以的,但是这里需要注意的是两个配置文件同时存在的话优先级首选application.properties中。接下来我们步入正题

JDK升级到17、Springboot升级到3.0.4

JDK升级到17、Springboot升级到3.0.4。JDK升级安装、Sprinbboot升级到3.0.4以及升级过程中过的通用问题及解决办法记录分享。