zoukankan      html  css  js  c++  java
  • Spring AOP监控SQL运行

             对数据库连接池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来详细配置。

    完成。






  • 相关阅读:
    轨迹纠偏算法
    OpenStreetMap
    postgres create new super user
    postgis docker
    scala 命令台参数解析
    book
    Microsoft 365:OneDrive新特性,跨部门共享和协作
    2020年6月Microsoft 365 新功能速递
    Microsoft 365 解决方案:未经身份验证的用户上载文档小技巧 (2)
    Microsoft 365 解决方案:外部用户无法打开Microsoft Teams下录制的视频
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7182845.html
Copyright © 2011-2022 走看看