假设一个可操作的 Java 应用程序使用 DataNucleus 的 JDO 实现来访问数据库,是否可以拦截对数据库进行的所有 SQL 查询?目的是对它们进行统计并保留日志/跟踪。
2 回答
您可以通过打开 DataNucleus.Datastore.Native 类别轻松地从 DataNucleus 获取所有 SQL 语句的日志(参见http://www.datanucleus.org/products/datanucleus/logging.html)
JDO2 InstanceLifecycleListeners 将允许您拦截事件,但我认为 SQL 语句在那里不可用......
您还可以查看您的应用服务器以获取 SQL 分析工具。例如,GlassFish 允许您将 SQLTraceListener 实现附加到连接池。请参阅http://docs.oracle.com/cd/E18930_01/html/821-2418/giyck.html#giygg
日志4j
您可以将java.util.logging或Log4j与 DataNucleus 一起使用。我将讲述 Log4j 的配置。
log4j.properties
# Define the destination and format of our logging
log4j.rootCategory=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{1}:%M:%L - %m%n
# DataNucleus Categories
log4j.category.DataNucleus=ALL
最后一行为 INFO 或 ALL 分配了一个级别阈值,以便查看所有 DataNucleus 日志。DataNucleus 使用一系列类别,并将所有消息记录到这些类别中。有关更多详细信息,请参见此处。你可能需要
log4j.category.DataNucleus.Query
- 所有与查询有关的消息log4j.category.DataNucleus.Datastore
- 所有常规数据存储消息
或log4j.category.DataNucleus.JDO
- JDO 通用的所有消息
log4j.category.DataNucleus
是所有 DataNucleus 日志类别的根。
将log4j添加到您的 CLASSPATH。我使用Gradle进行依赖管理,所以这是我的构建脚本:
构建.gradle
configurations {
all*.exclude group: "commons-logging", module: "commons-logging"
}
dependencies {
// Logging
compile 'org.slf4j:slf4j-api:1.7.+'
runtime 'org.slf4j:slf4j-jdk14:1.7.+'
runtime ('log4j:log4j:1.2.17') {
exclude group: "com.sun.jdmk", module: "jmxtools"
exclude group: "com.sun.jmx", module: "jmxri"
exclude group: "javax.mail", module: "mail"
exclude group: "javax.jms", module: "jms"
}
}
要在启动应用程序时提供 Log4J 配置文件,请将 JVM 参数设置为
-Dlog4j.configuration=file:log4j.properties
如果您在 JavaEE 应用程序服务器中运行,这可能会为您完成。或者,如果您使用 Spring WebMVC,请将 log4j.properties 放在 WEB-INF 中,并将以下侦听器添加到您的部署描述符中。
web.xml
<!-- The definition of the Log4j Configuration -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>