对数据库连接池Proxool比較熟悉的读者,都知道Proxool能够记录SQL运行内容和时间等信息日志。

我们能够将该日志记录专门的SQL日志文件。对于查找运行特别耗时的SQL起了不小的作用。

对于一些其它连接池,没有该特性时。本文介绍Spring AOP切面方法来记录SQL日志。

当然也能够通过数据库提供的特性来查询运行效率较低的SQL,本文不做探讨。

本文介绍使用SpringJdbcTemplate运行SQL,使用其它方法或者ORM思路类似(Hibernate提供了日志记录功能)。

使用AOP,能够使用Around通知。在JdbcTemplate运行方法前。记录当前时间,在方法运行完后,计算SQL耗时,并记录日志。思路非常easy,只是多介绍。代码例如以下。

package org.enyes.sql.util;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; /**
* 对Spring JdbcTemplate进行切面,记录每一个sql运行时间。
*/
@Aspect
public class SqlExecutionTimeAspect {
/**
* logger
*/
private static final Logger LOG = Logger
.getLogger(SqlExecutionTimeAspect.class); /**
* 当Sql运行时间超过该值时。则进行log warn级别题型,否则记录INFO日志。 */
private long warnWhenOverTime = 2 * 60 * 1000L; @Around("execution(* org.springframework.jdbc.core.JdbcTemplate.*(..))")
public Object logSqlExecutionTime(ProceedingJoinPoint joinPoint)
throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long costTime = System.currentTimeMillis() - startTime;
if (costTime > warnWhenOverTime) {
StringBuilder sb = new StringBuilder();
sb.append("execute method :").append(joinPoint.getSignature());
sb.append("args: ").append(arrayToString(joinPoint.getArgs()));
sb.append(" cost time[").append(costTime).append("]ms");
LOG.warn(sb);
} else if (LOG.isInfoEnabled()) {
StringBuilder sb = new StringBuilder();
sb.append("execute method :").append(joinPoint.getSignature());
sb.append("args: ").append(arrayToString(joinPoint.getArgs()));
sb.append(" cost time[").append(costTime).append("]ms");
LOG.info(sb);
}
return result;
} private static String arrayToString(Object[] a) {
if (a == null)
return "null"; int iMax = a.length - 1;
if (iMax == -1)
return "[]"; StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0;; i++) {
if (a[i] instanceof Object[]) {
b.append(arrayToString((Object[]) a[i]));
} else {
b.append(String.valueOf(a[i]));
}
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
}

Springxml配置例如以下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
">
<beans>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean class="org.enyes.sql.util.SqlExecutionTimeAspect"/>
</beans>

能够使用Log4J将SqlExecutionTimeAspect类的日志打印到专门的日志中。而且warnWhenOverTime提供setter方法。能够通过Spring xml来详细配置。

完成。

Spring AOP监控SQL运行的更多相关文章

  1. SpringMVC4+MyBatis+SQL Server2014+druid 监控SQL运行情况

    前言 在基于SpringMVC+MyBatis的开发过程中,我们希望能看到自己手写SQL的执行情况,在开发阶段我们可以配置log4j在控制台里基于debug模式查看,那么上线后,在生产声我们想查看SQ ...

  2. 监控sql运行时剩余时间

    --监控sql执行时剩余时间 你知道正在执行的sql大概须要多长时间么? 你知道正在执行的sql大概完毕了百分之几么? 你知道正在执行的sql大概还要多长时间完毕么? V$SESSION_LONGOP ...

  3. Spring AOP之多切面运行顺序

    多切面运行顺序 当一个方法的执行被多个切面共同切的时候,环绕通知只影响当前切面的通知顺序,例如创建两个切面logUtil,validateUtil两个切面共同监视计算器类的加法运算,add(int a ...

  4. Spring AOP 的实现 原理

    反射实现 AOP 动态代理模式实例说明(Spring AOP 的实现 原理)   比如说,我们现在要开发的一个应用里面有很多的业务方法,但是,我们现在要对这个方法的执行做全面监控,或部分监控.也许我们 ...

  5. Spring Aop 详解一

    Aop 是一个编程思想,最初是一个理论,最后落地成了很多的技术实现. 我们写一个系统,都希望尽量少写点儿重复的东西.而很多时候呢,又不得不写一些重复的东西.比如访问某些方法的权限,执行某些方法性能的日 ...

  6. Spring5.0源码学习系列之Spring AOP简述

    前言介绍 附录:Spring源码学习专栏 在前面章节的学习中,我们对Spring框架的IOC实现源码有了一定的了解,接着本文继续学习Springframework一个核心的技术点AOP技术. 在学习S ...

  7. Spring AOP 实现原理与 CGLIB 应用

    https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/ AOP(Aspect Orient Programming),也就是面向 ...

  8. 【spring-boot】spring aop 面向切面编程初接触--切点表达式

    众所周知,spring最核心的两个功能是aop和ioc,即面向切面,控制反转.这里我们探讨一下如何使用spring aop. 1.何为aop aop全称Aspect Oriented Programm ...

  9. Spring AOP 实现原理与 CGLIB 应用--转

    AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...

随机推荐

  1. 【转载】Sql语句用left join 解决多表关联问题(关联套关联,例子和源码)

    csdn中高手帮我给解决了,其实就是别名,给自己上了一堂别名的课,所谓别人是高手,其实就是自己是菜鸟吧! 表1:------------------------------ [人事表]     表名: ...

  2. Java之浅拷贝与深拷贝

    ----?浅拷贝 --- 概念 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.简单说,浅拷贝就是只复制所考虑的对象,而不复制它所引用的对象 --- 实现方 ...

  3. 条款4:确定对象被使用前已被初始化(Make sure that objects are initialized before they're used)

    其实 无论学何种语言 ,还是觉得要养成先声明后使用,先初始化再使用. 1.永远在使用对象之前先将其初始化. 内置类型: 必须手工完成. 内置类型以外的:使用构造函数完成.确保每一个构造函数都将对象的一 ...

  4. vue 页面过渡效果

    App.vue 模板 <template> <div id="app"> <transition :name="transition&quo ...

  5. configparser ,subprocess , xlrd ,xlwt 模块

    一,configparser模块 ''' configparser模块: 是什么: 用于解析配置文件的模块 配置文件的定义: 用于编写保存某个软件或某个系统的一系列参数的文件 设置参数 为什么需要配置 ...

  6. Python3--中括号"[]"与冒号":"在列表中的作用

    先来定义两个列表: liststr = ["helloworld","hahahh","123456"] listnum = [1,2,3, ...

  7. C语言学习10

    判断三角形的类型 根据输入的三角形的三条边判断三角形的类型,并输出它的面积. #include <stdio.h> #include <math.h> void judge_1 ...

  8. virtualbox创建虚机后配置网络上网

    一般来说常用的会配置两个网卡:(两个网卡应该在安装虚拟机之前就设置好) 1.NAT网络: 用于上外网: 2.host-only: 用于ssh连接,可以被其他人远程访问. 前提: 如图:在virtual ...

  9. oracle中的权限管理

    connect resource权限 grant connect,resource to user; 执行上面的sql语句后用户包括的权限: CONNECT角色: --是授予最终用户的典型权利,最基本 ...

  10. Fidder详解-抓取HTTPS清求(Web/App)抓包分析(靠谱篇)

    为什么要学Fidder抓包? 学习接口,必须要学http协议,不要求您对协议的掌握有多深.只是希望你能够了解什么是协议.协议的报文.状态码等等!本文通过抓包工具Fidder带你进入接口的大门.我们通过 ...