springboot+mybatis 写一个记录sql及sql执行时间的日志拦截类
程序员文章站
2022-06-12 16:10:11
...
日志是springboot自带的org.slf4j类型的日志
1、logback.xml 日志配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="3 seconds">
<property name="LOG_HOME" value="temp/logs">
<appender name="CONSOLE-LOGGER" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>UTF-8</charset>
<Pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %level %logger{200}.%M:%line - %msg%n</Pattern>
</encoder>
</appender>
<appender name="FILE-LOGGER" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>logFileName</key>
<defaultValue>testLog</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${logFileName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${logFileName}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %level %logger{200}.%M:%line -%msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/${logFileName}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--设置最多保留20天 -->
<maxHistory>20</maxHistory>
</rollingPolicy>
</appender>
</sift>
</appender>
<appender>
<discriminator>
<key>sqlFileName</key>
<defaultValue>testSql</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${logFileName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${logFileName}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %level %logger{200}.%M:%line -%msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/${logFileName}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--设置最多保留20天 -->
<maxHistory>20</maxHistory>
</rollingPolicy>
</appender>
</sift>
</appender>
<root level="info">
<appender-ref ref="FILE-LOGGER"></appender-ref>
<appender-ref ref="CONSOLE-LOGGER"></appender-ref>
</root>
<logger name="com.clj" level="debug" additivity="false">
<appender-ref ref="FILE-LOGGER"></appender-ref>
<appender-ref ref="CONSOLE-LOGGER"></appender-ref>
</logger>
<logger name="java.sql" level="debug" additivity="false">
<appender-ref ref="FILE-LOGGER"></appender-ref>
<appender-ref ref="CONSOLE-LOGGER"></appender-ref>
</logger>
<logger name="sqlLog" level="info" additivity="false">
<appender-ref ref="SQL-LOGGER"></appender-ref>
</logger>
</property>
</configuration>
2、springboot application.yml
在这里插入代码片server:
port:8080
tomcat:
uri-encoding:UTF-8
spring:
profiles:
active:dev
http:
encoding:
force:true
charset:UTF-8
enabled:true
application:
name:myTest
datasource:
druid:
driver-class-name:com.ibm.db2.jcc.DB2Driver
url:jdbc:db2://~~~~~~~~~~~~~~~~~~~~;
username:~~
password:~~
initial-size:5
min-idle:5
max-active:20
max-wait:60000
time-between-eviction-runs-millis:60000
min-evictable-idle-time-mills:30000
validation-query:select 1 from sysibm,sysdummy 1
test-while-idle:true
test-on-borrow:false
test-on-return:false
pool-prepared-statements:true
max-pool-prepared-statement-per-connection-size:20
filters:stat,wall,slf4j
connection-properties:druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
use-global-data-source-stat:true
filter:
config:
enabled:true
web-stat-filter:
enabled:true
start-view-servlet:
enabled:true
mybatis:
typeAliasesPackage:com.clj.model
mapperLocations:classpath:mapper/*Mapper.xml
configuration:
map-undersore-to-camel-case:true
pagehelper:
reasonable:true
support-methods-arguments:true
params:count = countsql
eureka:
client:
register-with-eureka:false
fetch-registry:false
management:
endpoints:
web:
exposure:
include:info,health,loggers
3、日志打印时间戳转毫秒String
package interceptor;
import java.text.SimpleDateFormat;
public class SimpleDateFormatUtil {
public static String getStringMillers(long date){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssS");
return simpleDateFormat.format(date);
}
}
4、SQL拦截器,日志打印sql及执行时间打印
package interceptor;
import java.beans.Statement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import io.swagger.annotations.Info;
@Intercepts({@Signature(type=StatementHandler.class,method="query",args={
Statement.class,ResultHandler.class
})})
@Component
@Configuration
public class SQLInterceptor implements Interceptor{
private static final Logger logger = LoggerFactory.getLogger("sqlLog");
private static final int INFO = 2;
private static final int ERROR = 1;
@Override
public Object intercept(Invocation invocation) throws Throwable{
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
BoundSql boundSql = statementHandler.getBoundSql();
String sql = boundSql.getSql();
//获取当前执行的sql
logger.info("mybatis interceptor sql:{"+sql+"}");
long _begin = logTime("beginTime");
Object object = null;
try{
object = invocation.proceed();
}catch (Throwable e) {
if(e instanceof SQLException){
logTime(ERROR,"endTime with SQLException",_begin);
}else{
logTime(ERROR,"endTime with Throwable",_begin);
}
throw e;
}
logTime("endTime",_begin);
return object;
}
private long logTime(String tStr){
return logTime(INFO,tStr,0);
}
private long logTime(int lvl,String tStr){
return logTime(lvl,tStr,0);
}
private long logTime(String tStr,long _begin){
return logTime(INFO,tStr,_begin);
}
private long logTime(int lvl,String tStr,long _begin){
String traceClz = traceClz();
long now = new Date().getTime();
String nowTime = SimpleDateFormatUtil.getStringMillers(now);
if(_begin > 0){
if(lvl == INFO){
logger.info(traceClz+"["+tStr+":"+nowTime+"timeDiff:"+(now-_begin)+"]");
}else if(lvl == ERROR){
logger.error(traceClz+"["+tStr+":"+nowTime+"timeDiff:"+(now-_begin)+"]");
}
}else{
if(lvl ==INFO){
logger.info(traceClz +"["+tStr+":"+nowTime+"]");
}else if(lvl == ERROR){
logger.error(traceClz +"["+tStr+":"+nowTime+"]");
}
}
return now;
}
private String traceClz(){
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("<"+Thread.currentThread().getId()+">");
if(stackTrace.length>24){
int start = 24;
while(true){
String clzName = stackTrace[start].getClassName();
String mtdName = stackTrace[start].getMethodName();
stringBuffer.append(clzName.substring(clzName.lastIndexOf(".")+1));
stringBuffer.append(".").append(mtdName.substring(mtdName.lastIndexOf(".")+1));
if(clzName.indexOf("controller")>-1){
break;
}
start++;
if(start == stackTrace.length) break;
stringBuffer.append("<-");
}
}
return stringBuffer.toString();
}
@Override
public Object plugin(Object arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void setProperties(Properties arg0) {
// TODO Auto-generated method stub
}
}
上一篇: C# 使用正则表达式判断文件后缀名
下一篇: C#正则表达式匹配HTML中的图片路径