用 p6spy 来观察 Java 程序中执行的所有 SQL 语句(二. Tomcat 下的配置)

在前篇 用 p6spy 来观察 Java 程序中执行的所有 SQL 语句(一. 引子) 大略介绍了 p6spy,并且在 http://www.p6spy.com/documentation/install.htm#install 也有 p6spy 在不同服务器下的安装方法。本文不打算依照官方的说明来做,我们让 Tomcat 的 Common 类加载器来加载 p6spy.jar 包,包含了 Tomcat 5/6 下的 p6spy 配置,数据库连接池实现用 C3P0,数据库为 Oracle,配置在一个与应用同名的单独的 xml 文件中,Tomcat 中是在应用的 META-INF/context.xml 文件中。步骤如下:

1. 软件准备

下载 Tomcat 5 或者 6 进行安装,不必多说。假设置 Tomcat 的目录为 $TOMCAT_HOME。
下载 p6spy-install.zip,解压缩 p6spy-install.zip,其中有 p6spy.jar 和 spy.properties
准备好数据库的驱动包,比如 Oracle 的 classes12.jar,和 C3P0 实现包,如 c3p0-0.9.0.2.jar。

2. 拷贝文件

在 Tomcat 5 下:
    拷贝 p6spy.jar、classes12.jar、c3p0-0.9.0.2.jar 到 $TOMCAT_HOME/common/lib 目录下
    拷贝 spy.properties 到 $TOMCAT_HOME/common/classes 目录下

在 Tomcat 6 下:
    把 p6spy.jar、classes12.jar、c3p0-0.9.0.2.jar 和 spy.properties 都拷到 $TOMCAT_HOME/lib 目录下。

----注:这里我们让 Tomcat 的 Common 类加载器来加载相关类,Common 加载的类对应 WebApp 是可见的。有关 Tomcat 类加载器层次可参考 Tomcat5 类装载器分析 和 Tomcat6 类装载器分析

Tomcat5 的 Common 类加载器从 $TOMCAT_HOME/common/lib 目录下加载 jar/zip 文件,从 $TOMCAT_HOME/common/classes 下加载类文件。而 spy.properties 是通过 classloader 来加载的,所以应放在 classpath 下。而 Tomcat 6 的 Common 类加载器对 jar/zip,和 class 文件都是从 $TOMCAT_HOME/lib 中加载。

细心点还能注意到 Tomcat 5.5.20 是 Tomcat 5 到 Tomcat 6 的过度版本,实则是一个混乱的版本。同时有 $TOMCAT_HOME/lib 和 $TOMCAT_HOME/common 目录,可是又新奇的发现在 Tomcat 5.5.25 中没有 $TOMCAT_HOME/lib 目录了。Tomcat 6 中不再有 $TOMCAT_HOME/common 目录了。

3. 修改 p6spy 配置文件

打开 $TOMCAT_HOME/lib 或者 $TOMCAT_HOME/common/classes 下的 spy.properties 文件,此文件中本身有很详细的注释,很容易理解其中的配置。我们在这里修改几个主要的地方,让它能工作起来。

1) 找到 # realdriver=oracle.jdbc.driver.OracleDriver 把前面的 # 注释符去掉,因为我们用的是 Oracle 数据库,即改为

realdriver=oracle.jdbc.driver.OracleDriver

同时把 realdriver=org.gjt.mm.mysql.Driver 用 # 注释掉,即改为

# realdriver=org.gjt.mm.mysql.Driver

2) 打开输出过滤,因为我们希望对有些表(如用户表) 的查询不输出相应的 SQL,找到 filter=false,把它改为 filter=true。

    再看它后面有几个配置 include = 、 exclude =  和 sqlexpression = 用来设置过虑规则。例如我们不想输出对 users、constants 表操作的 SQL,就配置

exclude = users,constants

3) 输出目的地的选择,在 spy.properties 中可以找到

#specifies the appender to use for logging
#appender=com.p6spy.engine.logging.appender.Log4jLogger
#appender=com.p6spy.engine.logging.appender.StdoutLogger
appender=com.p6spy.engine.logging.appender.FileLogger

分别是输出到 Log4j、控制台和文件中,如果是输出到控制台的话,就让 appender=com.p6spy.engine.logging.appender.StdoutLogger 有效,其他两个注释掉。

如果你配置的是默认的 appender=com.p6spy.engine.logging.appender.FileLogger,那么它下面的 logfile = spy.log 就是指定要输出的日志文件,这个文件会生成在 System.getProperty("user.dir") 目录中,即 $TOMCAT_HOME/bin 目录中,你可以让它生成到 $TOMCAT_HOME/logs 目录中,就写成

logfile = ../logs/spy.log

如果是让 SQL 语句输出到日志文件的话,append=true,会较重要,为 true 时为附加,spy.log 会变得很大,否则为每次 Tomcat 重启后生成新的文件。

需留意一下最后的有关使用 Log4j 输出的配置

4. 配置数据库连接池

其实连接池的配置与使用 p6spy 无多大关系,无论你是在 Tomcat 中、还是 Spring、Hibernate 中配置连接池,甚至是直接用 JDBC 连接数据库都无所谓,关键是,要使 p6spy 在其中发生效用,所用的数据库驱动就必须是 com.p6spy.engine.spy.P6SpyDriver。

假定应用的 Context 是 MyWeb,且直接是部署在 $TOMCAT_HOME/webapps 目录下,那么我们配置这个应用的数据源就可以在 $TOMCAT_HOME/conf/Catalina/localhost 建立一个 MyWeb.xml 文件,文件内容如下:

----注:这一步不是必须的,主要通常我们都会使用连接池来访问数据库,其实只要在应用里使用 com.p6spy.engine.spy.P6SpyDriver 驱动,p6spy 就会在中间获取到它要的信息,并输出 SQL 语句。

关于不同版本的 Tomcat 连接池的配置又是个不小的议题。

如果是在 Tomcat 5.5 中,$TOMCAT_HOME/conf/Catalina/localhost/MyWeb.xml 的内容应如下:

而到了 Tomcat 6 中时,$TOMCAT_HOME/conf/Catalina 目录都不存在了。Tomcat 6 中给应用配置连接池就要在应用的 META-INF 目录(例如 $TOMCAT_HOME/MyWeb/META-INF) 下建立文件 context.xml,内容如下:

5. 测试应用

前面说过,只要是用 com.p6spy.engine.spy.P6SpyDriver 的话,不管你是用连接池还是每次建立 JDBC 连接,p6spy 都能给你输出所执行的 SQL 语句。默认时输出样子如下:

参考:1. Tomcat5 类装载器分析
        2. Tomcat6 类装载器分析
        3. Tomcat 6 连接池设置
        4. tomcat中的几种连接池配置代码(tomcat5.0,tomcat5.5x,tomcat6.0)

 

本文链接 https://yanbin.blog/p6spy-view-java-executing-sql-tomcat/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

2 Comments
Inline Feedbacks
View all comments
xwx
xwx
11 years ago

感觉您的博客太好了!谢谢!之前就看过您的博客,然后搜索其他的东西又回到您的博客了!呵呵!