数据库
首页 > 数据库> > SpringBoot+P6Spy实现优雅打印sql日志

SpringBoot+P6Spy实现优雅打印sql日志

作者:互联网

SpringBoot+P6Spy实现优雅打印sql日志

引言

此前做过的一个springBoot项目,sql日志打印十分优雅简洁,sql语句在控制台特殊标色比较显眼,而且打印出来的是包括参数在内的实际执行sql,还打印出了sql耗时和执行时间,对于问题定位分析特别有帮助。
在这里插入图片描述
正好最近在做一个门户网站开发的需求,所用的框架是SpringBoot+MybatisPlus,和上述的项目框架是一样的,就想着直接复用之前这个项目的sql日志打印方式(之前这个项目的日志相关开发我完全没接触),但是没想到因为对P6Spy框架的不了解踩了一些坑,通过一步步的摸索才最终达到了理想的效果。

踩坑历程

项目使用的日志框架是logback,这里我直接将之前项目的logback-spring.xmlspy.properties配置文件修改一些参数

复制过来使用,配置文件部分内容如下:

logback-spring.xml

<!-- 日志输出级别 -->
 <root level="info">
     <appender-ref ref="businessLogFile"/>
     <appender-ref ref="STDOUT"/>
     <!--<appender-ref ref="sqlLogFile"/>-->
 </root>

 <logger name="org.springframework.jdbc.core.JdbcTemplate" additivity="false" level="DEBUG">
     <appender-ref ref="sqlLogFile"/>
 </logger>

spy.properties

module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,batch,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 真实JDBC driver , 多个以 逗号 分割 默认为空
#driverlist=org.h2.Driver
driverlist=oracle.jdbc.OracleDriver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

我感觉这样就可以了,但是项目启动之后控制台却没有任何的sql日志打印,第一反应是MybatisPlus配置的问题,在yml文件中MybatisPlus的配置如下:

mybatis-plus:
  mapper-locations: classpath*:mapper/oracle/*/*.xml
  type-aliases-package: com.ztesoft.datasync.*.entity

在网上查了MybatisPlus控制台为什么不打印日志之后,我修改了配置文件:

mybatis-plus:
  mapper-locations: classpath*:mapper/oracle/*/*.xml
  type-aliases-package: com.ztesoft.datasync.*.entity
  configuration:
    # 是否将sql打印到控制面板(该配置会将sql语句和查询的结果都打印到控制台)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

重新启动项目,结果却没有任何变化。我就想着是不是logback配置文件的问题,是不是因为缺少sql日志的配置,但是logback的配置文件是直接复用之前项目的,应该没有问题。不过基于验证一下问题根源的想法,我还是在logback配置文件里增加了一条配置,用于扫描mapper接口,并且将日志级别定义为DEBUG级别:

<!--打印sql语句和参数-->
    <logger name="com.ztesoft.datasync.datasyncdao.mapper" level="DEBUG" />

重新启动项目,控制台能打印sql日志了!但是好像跟P6Spy框架优雅简洁的自定义sql日志没有什么关系,这个是mybatis框架的日志:
在这里插入图片描述

关于P6Spy

最后,我终于想到了问题是不是出在我对P6Spy的使用方式有误,通过搜索P6Spy框架的使用,我发现了P6Spy正确打开方式,其实非常简单:P6Spy是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架,通过劫持JDBC驱动,在调用实际JDBC驱动前拦截调用的目标语,达到SQL语句日志记录的目的。应用P6Spy只需要:

1.添加依赖

<dependency>
     <groupId>p6spy</groupId>
     <artifactId>p6spy</artifactId>
     <version>3.8.7</version>
</dependency>

2.替换你的JDBC Driver为com.p6spy.engine.spy.P6SpyDriver
3.修改JDBC Url为jdbc:p6spy:xxxx
4.配置spy.properties

1和4都没问题,问题出在了2和3,因为之前项目的数据源是mysql,现在这个项目是oracle,所以没注意到之前项目数据源的JDBC DriverJDBC Url都是p6spy的:
在这里插入图片描述
而我的却是这样的:
在这里插入图片描述
怪不得在配置文件一样的前提下怎么也达不到之前项目的效果。这就是只知道复制粘贴,不懂还不去研究技术实质的代价!修改完配置文件之后重启项目,完美实现:
在这里插入图片描述

拓展

p6spy的自定义日志打印实现方式有两种,第一种在配置文件中指定logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger,这也是我的项目使用的方式,P6SpyLogger实现了MessageFormattingStrategy接口,自定义了log格式信息:

public class P6SpyLogger implements MessageFormattingStrategy {
    public P6SpyLogger() {
    }

    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
        return StringUtils.isNotEmpty(sql) ? " Consume Time:" + elapsed + " ms " + now + "\n Execute SQL:" + sql.replaceAll("[\\s]+", " ") + "\n" : null;
    }
}

第二种是直接指定logMessageFormat的值,这样更加灵活,可以自己定义格式,比如:

logMessageFormat=%(currentTime) | SQL耗时: %(executionTime) ms | 连接信息: %(category)-%(connectionId) | 执行语句: %(sql)
可用的变量为:
#   %(connectionId)            connection id
#   %(currentTime)             当前时间
#   %(executionTime)           执行耗时
#   %(category)                执行分组
#   %(effectiveSql)            提交的SQL 换行
#   %(effectiveSqlSingleLine)  提交的SQL 不换行显示
#   %(sql)                     执行的真实SQL语句,已替换占位
#   %(sqlSingleLine)           执行的真实SQL语句,已替换占位 不换行显示

结语

开发一个新的项目,直接复用其他项目的功能是很正常的事情,使用自己之前没接触过的框架也很正常,但是如果接触到之后,不先简单了解和研究就直接一股脑的复制粘贴,那就很容易踩到各种各样的坑。而且因为自己根本就不熟悉,所以解决问题也会花费更多的时间,更难受的是问题解决以后才发现原来如此的简单和基础,但是却花费了自己大量的时间,感到非常后悔和不值。所以还是建议对于自己要用到的没接触过的技术和框架,还是先了解了解再上手使用。

标签:SpringBoot,P6Spy,配置文件,打印,sql,日志,p6spy
来源: https://blog.csdn.net/weixin_45087127/article/details/114365322