java收集sql监控_java笔记:自己动手写javaEE框架(三)--引入SQL监控技术P6spy

2023-12-29 04:30

本文主要是介绍java收集sql监控_java笔记:自己动手写javaEE框架(三)--引入SQL监控技术P6spy,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件151 黄旭 1531610120

任何系统里,日志和一定的监控是相当重要的,在一个软件整个生命周期里维护永远是大头同时是痛苦的,而日志和监控就是为后期维护提供了良好的基础和手段,在java工程里面大多使用log4j来记录系统日志,这个技术几乎所有的java工程师都很熟悉,不太明白了,大家可以查查百度。这里我打算引入一个能监控JDBC执行语句的框架到我写的java框架里面,这个框架非常的好用,他就是p6spy。

“如果优化SQL语句,如何进行系统调优”,这样的问题我想很多程序员都听到过,优化和调优是一个高难度的技术技能,只有具有扎实的技术功底和多年的项目经验才把他做好。我以前遇到这样的提问,思路很机械,都是从SQL语法,索引,分区,算法来考虑,其实优化和调优程序环境的搭配也是很重要的,例如,现在做java企业级项目,大多使用了orm技术,很少会直接去用jdbc操作数据库,而orm技术对jdbc的封装让最终执行的sql语句的原型离程序员越来越远,因此对jbdc执行的原生态的sql语句的掌控是相当重要的。

在这里我可以分享一下我的经验。我现在比较推崇ibatis,它既实现了orm思想,又保留了sql语句的使用而不是像hibernate那样对数据库做完全面向对象的映射,而产生了很多新的东西,比如hql。这是一个简便的设计,我觉得系统设计最佳的方案就是新老兼容。其实不同的程序员擅长的技术也不同,做java的程序员当然对java更熟悉,开发数据库的程序员对数据库很在行,假如你现在开发一个后台数据库数据量很大,业务操作很复杂的系统,我这里会首推ibatis技术做orm层,因为这样的大系统到了数据库层面和dba打交道很多,对sql语句以及数据库优化很多,而ibatis直接写sql语句的优点就很明显了,java程序员和dba的沟通和程序的交互也就方便多了。我最近做了几个这样的系统,系统做完后我都会把重要的sql语句从系统里抽取出来给dba优化,而dba优化后我基本只要拷贝到程序里就可以,为整个工作带来了便利。此外系统上线,如果操作数据库报错,在日志里提取sql语句,进行检查,检查后维护程序也是有很大的便利,最后用sql嵌入orm,程序架构的变迁所带来的问题也会少很多,因此我以后开发系统orm技术的首选就是ibatis了。

但是ibatis执行jdbc是使用prepareStatement,所以最终打印出来的sql语句是下面的格式:

48304ba5e6f9fe08f3fa1abda7d326ab.png

2011-10-13 11:17:36 Connection - {conn-100000} Connection

2011-10-13 11:17:36 Connection - {conn-100000} Preparing Statement: select t.username,t.password,t.enabled from users t where t.username = ?

2011-10-13 11:17:36 PreparedStatement - {pstm-100001} Executing Statement: select t.username,t.password,t.enabled from users t where t.username = ?

2011-10-13 11:17:36 PreparedStatement - {pstm-100001} Parameters: [sharpxiajun]

2011-10-13 11:17:36 PreparedStatement - {pstm-100001} Types: [java.lang.String]

48304ba5e6f9fe08f3fa1abda7d326ab.png

我们拷贝出sql语句还要改写,真是烦死人了,那么p6spy就能解决这个问题,它会把?替换成参数,看看我加入了p6spy后执行的效果吧。

|statement| select t.username,t.password,t.enabled from users t where t.username = 'sharpxiajun'

P6spy使用很简单,只要完成下面步骤就行:

1.将p6spy.jar包放到应用的classpath所在的路径中;

2.修改连接池或者连接配置的jdbc的驱动为p6spy所提供的保证后的驱动,com.p6spy.engine.spy.P6SpyDriver

3.修改spy.properties并将其放到类搜索目录.

下面我们开始开发了。

1.新的工程结构图如下:

1cd537ff973334959beca94b9fe985e4.png

新添两个jar包:log4j-1.2.12.jar和p6spy.jar

2.将log4j.properties和spy.properties拷贝到src下面(暂时拷贝到src下面,其实应该放到conf下面,因为现在都是在本地测试,没有发布到tomcat下面,就把两个文件拷贝到默认的路径下)

log4j.properties内容如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

log4j.debug=true

log4j.rootLogger=INFO,CONSOLE,STDOUT

#-----CONSOLE-----

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender

log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout

log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %c{1} - %m%n

#-----SQL LOG-----

log4j.logger.java.sql.Connection=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG

log4j.logger.com.ibatis=debug

log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug

log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug

log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug

48304ba5e6f9fe08f3fa1abda7d326ab.png

日志打印到控制台里,SQL LOG下的配置表示打印出jbdc以及ibatis的日志。

spy.properties内容如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

module.log=com.p6spy.engine.logging.P6LogFactory

realdriver=oracle.jdbc.driver.OracleDriver

deregisterdrivers=true

executionthreshold=

outagedetection=false

outagedetectioninterval=

filter=false

include =

exclude =

sqlexpression =

autoflush = true

dateformat=

includecategories=

excludecategories=info,debug,result,batch

stringmatcher=

stacktrace=false

stacktraceclass=

reloadproperties=false

reloadpropertiesinterval=60

useprefix=false

appender=com.p6spy.engine.logging.appender.StdoutLogger

append=true

log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender

log4j.appender.STDOUT.layout=org.apache.log4j.SimpleLayout

log4j.appender.STDOUT.layout.ConversionPattern=p6spy

log4j.logger.p6spy=DEBUG,STDOUT

48304ba5e6f9fe08f3fa1abda7d326ab.png

这里只要修改下realdriver=oracle.jdbc.driver.OracleDriver就行。

3.接下来我们只要更改下数据库的驱动就行了,修改下constants.properties,内容如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

#db.driverClass = oracle.jdbc.driver.OracleDriver

db.driverClass = com.p6spy.engine.spy.P6SpyDriver

db.user = sharpxiajun

db.password = sharpxiajun

db.jdbcUrl = jdbc:oracle:thin:@127.0.0.1:1521:orcl

#db.driverClass = com.mysql.jdbc.Driver

#db.user = root

#db.password = root

#db.jdbcUrl = jdbc\:mysql\://localhost\:3306/sq_xidi?useUnicode\=true&characterEncoding\=utf-8

48304ba5e6f9fe08f3fa1abda7d326ab.png

4.最后修改下USERS.xml配置文件,让查询方法接收到参数,如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

select t.username,t.password,t.enabled from users t

t.username = #username#

48304ba5e6f9fe08f3fa1abda7d326ab.png

执行结果如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

log4j: Parsing for [root] with value=[INFO,CONSOLE,STDOUT].

log4j: Level token is [INFO].

log4j: Category root set to INFO

log4j: Parsing appender named "CONSOLE".

log4j: Parsing layout options for "CONSOLE".

log4j: Setting property [conversionPattern] to [%d{yyyy-MM-dd HH:mm:ss} %c{1} - %m%n].

log4j: End of parsing for "CONSOLE".

log4j: Parsed "CONSOLE" options.

log4j: Parsing appender named "STDOUT".

log4j:ERROR Could not find value for key log4j.appender.STDOUT

log4j:ERROR Could not instantiate appender named "STDOUT".

log4j: Parsing for [com.ibatis.common.jdbc.SimpleDataSource] with value=[debug].

log4j: Level token is [debug].

log4j: Category com.ibatis.common.jdbc.SimpleDataSource set to DEBUG

log4j: Handling log4j.additivity.com.ibatis.common.jdbc.SimpleDataSource=[null]

log4j: Parsing for [java.sql.Connection] with value=[DEBUG].

log4j: Level token is [DEBUG].

log4j: Category java.sql.Connection set to DEBUG

log4j: Handling log4j.additivity.java.sql.Connection=[null]

log4j: Parsing for [com.ibatis] with value=[debug].

log4j: Level token is [debug].

log4j: Category com.ibatis set to DEBUG

log4j: Handling log4j.additivity.com.ibatis=[null]

log4j: Parsing for [java.sql.Statement] with value=[DEBUG].

log4j: Level token is [DEBUG].

log4j: Category java.sql.Statement set to DEBUG

log4j: Handling log4j.additivity.java.sql.Statement=[null]

log4j: Parsing for [com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate] with value=[debug].

log4j: Level token is [debug].

log4j: Category com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate set to DEBUG

log4j: Handling log4j.additivity.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=[null]

log4j: Parsing for [com.ibatis.common.jdbc.ScriptRunner] with value=[debug].

log4j: Level token is [debug].

log4j: Category com.ibatis.common.jdbc.ScriptRunner set to DEBUG

log4j: Handling log4j.additivity.com.ibatis.common.jdbc.ScriptRunner=[null]

log4j: Parsing for [java.sql.PreparedStatement] with value=[DEBUG].

log4j: Level token is [DEBUG].

log4j: Category java.sql.PreparedStatement set to DEBUG

log4j: Handling log4j.additivity.java.sql.PreparedStatement=[null]

log4j: Finished configuring.

初始化测试类....

2011-10-13 11:17:35 XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [conf/applicationContext.xml]

2011-10-13 11:17:35 GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@2808b3: startup date [Thu Oct 13 11:17:35 CST 2011]; root of context hierarchy

2011-10-13 11:17:35 PropertyPlaceholderConfigurer - Loading properties file from class path resource [conf/constants.properties]

2011-10-13 11:17:35 DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1de17f4: defining beans [usersDao,userService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,myDataSource,sqlMapClient,sqlMapClientTemplate,transactionManager,methodServiceAdvisor,org.springframework.aop.config.internalAutoProxyCreator,baseServiceMethods,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0]; root of factory hierarchy

2011-10-13 11:17:35 MLog - MLog clients using log4j logging.

2011-10-13 11:17:35 C3P0Registry - Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]

2011-10-13 11:17:36 AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 2wyjv28i1xq0ktewu9ral|131303f, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.p6spy.engine.spy.P6SpyDriver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 2wyjv28i1xq0ktewu9ral|131303f, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:oracle:thin:@127.0.0.1:1521:orcl, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]

2011-10-13 11:17:36 TransactionalTestExecutionListener - Began transaction (1): transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@6db33c]; rollback [false]

测试开始....

进入到了方法拦截器。。。。

调用的service:

cn.com.sharpxiajun.service.impl.UsersServiceImpl@23bdd1

调用的方法:

public abstract java.util.List cn.com.sharpxiajun.service.UsersService.queryUsersList(java.util.Map) throws java.lang.Exception

参数是:

{username=sharpxiajun}

2011-10-13 11:17:36 Connection - {conn-100000} Connection

2011-10-13 11:17:36 Connection - {conn-100000} Preparing Statement: select t.username,t.password,t.enabled from users t where t.username = ?

2011-10-13 11:17:36 PreparedStatement - {pstm-100001} Executing Statement: select t.username,t.password,t.enabled from users t where t.username = ?

2011-10-13 11:17:36 PreparedStatement - {pstm-100001} Parameters: [sharpxiajun]

2011-10-13 11:17:36 PreparedStatement - {pstm-100001} Types: [java.lang.String]

|statement| select t.username,t.password,t.enabled from users t where t.username = 'sharpxiajun'

返回结果是:

[]

拦截器执行结束!!

[]

测试结束!!

|commit|

2011-10-13 11:17:36 TransactionalTestExecutionListener - Committed transaction after test execution for test context [[TestContext@1fac852 testClass = UsersServiceImplTest, locations = array['classpath:conf/applicationContext.xml'], testInstance = cn.com.sharpxiajun.junittest.service.UsersServiceImplTest@1758cd1, testMethod = testQueryUserList@UsersServiceImplTest, testException = [null]]]

2011-10-13 11:17:36 GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@2808b3: startup date [Thu Oct 13 11:17:35 CST 2011]; root of context hierarchy

2011-10-13 11:17:36 DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1de17f4: defining beans [usersDao,userService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,myDataSource,sqlMapClient,sqlMapClientTemplate,transactionManager,methodServiceAdvisor,org.springframework.aop.config.internalAutoProxyCreator,baseServiceMethods,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0]; root of factory hierarchy

这篇关于java收集sql监控_java笔记:自己动手写javaEE框架(三)--引入SQL监控技术P6spy的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/548321

相关文章

SpringBoot集成P6Spy的实现示例

《SpringBoot集成P6Spy的实现示例》本文主要介绍了SpringBoot集成P6Spy的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录本节目标P6Spy简介抛出问题集成P6Spy1. SpringBoot三板斧之加入依赖2. 修改

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

Spring Integration Redis 使用示例详解

《SpringIntegrationRedis使用示例详解》本文给大家介绍SpringIntegrationRedis的配置与使用,涵盖依赖添加、Redis连接设置、分布式锁实现、消息通道配置及... 目录一、依赖配置1.1 Maven 依赖1.2 Gradle 依赖二、Redis 连接配置2.1 配置 R

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

MySQL磁盘空间不足问题解决

《MySQL磁盘空间不足问题解决》本文介绍查看空间使用情况的方式,以及各种空间问题的原因和解决方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录查看空间使用情况Binlog日志文件占用过多表上的索引太多导致空间不足大字段导致空间不足表空间碎片太多导致空间不足临时表空间

MySQL进行分片合并的实现步骤

《MySQL进行分片合并的实现步骤》分片合并是指在分布式数据库系统中,将不同分片上的查询结果进行整合,以获得完整的查询结果,下面就来具体介绍一下,感兴趣的可以了解一下... 目录环境准备项目依赖数据源配置分片上下文分片查询和合并代码实现1. 查询单条记录2. 跨分片查询和合并测试结论分片合并(Shardin

Spring Security重写AuthenticationManager实现账号密码登录或者手机号码登录

《SpringSecurity重写AuthenticationManager实现账号密码登录或者手机号码登录》本文主要介绍了SpringSecurity重写AuthenticationManage... 目录一、创建自定义认证提供者CustomAuthenticationProvider二、创建认证业务Us

Java Stream流以及常用方法操作实例

《JavaStream流以及常用方法操作实例》Stream是对Java中集合的一种增强方式,使用它可以将集合的处理过程变得更加简洁、高效和易读,:本文主要介绍JavaStream流以及常用方法... 目录一、Stream流是什么?二、stream的操作2.1、stream流创建2.2、stream的使用2.

MySQL配置多主复制的实现步骤

《MySQL配置多主复制的实现步骤》多主复制是一种允许多个MySQL服务器同时接受写操作的复制方式,本文就来介绍一下MySQL配置多主复制的实现步骤,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 环境准备2. 配置每台服务器2.1 修改每台服务器的配置文件3. 安装和配置插件4. 启动组复制4.

MySQL数据脱敏的实现方法

《MySQL数据脱敏的实现方法》本文主要介绍了MySQL数据脱敏的实现方法,包括字符替换、加密等方法,通过工具类和数据库服务整合,确保敏感信息在查询结果中被掩码处理,感兴趣的可以了解一下... 目录一. 数据脱敏的方法二. 字符替换脱敏1. 创建数据脱敏工具类三. 整合到数据库操作1. 创建服务类进行数据库