[英]How to enable logging for SQL statements when using JDBC
I am trying to enable logs using my JDBC program by connecting to Oracle database in eclipse IDE.我正在尝试通过连接到 Eclipse IDE 中的 Oracle 数据库来使用我的 JDBC 程序启用日志。
I have gone through this SO post JDBC logging to file then I have created below java program and running it from my eclipse IDE, but I was not able to see any logs generated by the JDBC driver classes.我已经完成了这个 SO post JDBC logging to file然后我在 java 程序下面创建并从我的 eclipse IDE 运行它,但是我看不到 JDBC 驱动程序类生成的任何日志。
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class Logging {
static Logger log = Logger.getLogger(Logging.class.toString());
static Connection con = null;
public static void main(String[] args) throws SQLException,
ClassNotFoundException {
System.setProperty("oracle.jdbc.Trace", Boolean.TRUE.toString());
System.setProperty("java.util.logging.config.file",
"OracleLog.properties");
log.info("Test Message");
enableLogging(false);
getConnection();
closeConnection();
}
static private void enableLogging(boolean logDriver) {
try {
oracle.jdbc.driver.OracleLog.setTrace(true);
// compute the ObjectName
String loader = Thread.currentThread().getContextClassLoader()
.toString().replaceAll("[,=:\"]+", "");
javax.management.ObjectName name = new javax.management.ObjectName(
"com.oracle.jdbc:type=diagnosability,name=" + loader);
// get the MBean server
javax.management.MBeanServer mbs = java.lang.management.ManagementFactory
.getPlatformMBeanServer();
// find out if logging is enabled or not
System.out.println("LoggingEnabled = "
+ mbs.getAttribute(name, "LoggingEnabled"));
// enable logging
mbs.setAttribute(name, new javax.management.Attribute(
"LoggingEnabled", true));
File propFile = new File("path/to/properties");
LogManager logManager = LogManager.getLogManager();
logManager.readConfiguration(new FileInputStream(propFile));
if (logDriver) {
DriverManager.setLogWriter(new PrintWriter(System.err));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException,
ClassNotFoundException {
Properties connectionProps = new Properties();
connectionProps.put("user", "test_app");
connectionProps.put("password", "test");
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(
"jdbc:oracle:thin:@"+HOST_IP+":1521:"+SID,
connectionProps);
System.out.println("Connected to database");
return con;
}
public static void closeConnection() throws SQLException {
if (con != null) {
con.close();
}
}
}
and I have below content in my OracleLog.properties file:我的 OracleLog.properties 文件中有以下内容:
.level=SEVERE
oracle.jdbc.level=INFO
oracle.jdbc.handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
But when I run my program by placing ojdbc6-11.2.0.3.jar
in classpath then I am getting exception as:但是当我通过在类路径中放置
ojdbc6-11.2.0.3.jar
来运行我的程序时,我得到了异常:
INFO: Test Message
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,name=sun.misc.Launcher$AppClassLoader@73d16e93
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:643)
at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
at myjdbc.Logging.enableLogging(Logging.java:45)
at myjdbc.Logging.main(Logging.java:24)
Connected to database
If I have ojdbc6_g.jar
in classpath then also I am getting same exception.如果我在类路径中有
ojdbc6_g.jar
,那么我也会遇到同样的异常。
Please let me know how can I enable logging for my JDBC program?请让我知道如何为我的 JDBC 程序启用日志记录? basically I am expecting to see the logs generated by the internal JDBC code.
基本上我希望看到内部JDBC代码生成的日志。
Update: Now I placed ojdbc6dms.jar
file in classpath, my program is giving below exception:更新:现在我将
ojdbc6dms.jar
文件放在类路径中,我的程序给出了以下异常:
Nov 28, 2014 9:09:02 PM jdbc.chap2.Logging main
INFO: Test Message
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,name=sun.misc.Launcher$AppClassLoader@73d16e93
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:643)
at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
at jdbc.chap2.Logging.enableLogging(Logging.java:45)
at jdbc.chap2.Logging.main(Logging.java:24)
Exception in thread "main" java.lang.NoClassDefFoundError: oracle/dms/console/DMSConsole
at oracle.jdbc.driver.DMSFactory.<clinit>(DMSFactory.java:48)
at oracle.jdbc.driver.PhysicalConnection.createDMSSensors(PhysicalConnection.java:2121)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:730)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:433)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:608)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:208)
at jdbc.chap2.Logging.getConnection(Logging.java:70)
at jdbc.chap2.Logging.main(Logging.java:25)
Caused by: java.lang.ClassNotFoundException: oracle.dms.console.DMSConsole
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 10 more
2019 update: log4jdbc has not been maintained since 2015. p6spy still seems to be actively maintained. 2019年更新:log4jdbc从2015年开始就没有维护了, p6spy好像还在积极维护。
There are lot of Spy frameworks available for this purpose , please check log4jdbc , I fell this is what you are looking for.有很多间谍框架可用于此目的,请检查log4jdbc ,我认为这就是您正在寻找的。
Features特征
Usage用法
Prepend jdbc:log4 to the normal jdbc url that you are using.将 jdbc:log4 前置到您正在使用的普通 jdbc url。
For example, if your normal jdbc url is jdbc:derby://localhost:1527//db-derby-10.2.2.0-bin/databases/MyDatabase then You would change it to: jdbc:log4jdbc:derby://localhost:1527//db-derby-10.2.2.0-bin/databases/MyDatabase例如,如果您的普通 jdbc url 是 jdbc:derby://localhost:1527//db-derby-10.2.2.0-bin/databases/MyDatabase 那么您将其更改为:jdbc:log4jdbc:derby://localhost: 1527//db-derby-10.2.2.0-bin/databases/MyDatabase
Set up your loggers.设置你的记录器。
jdbc.sqlonly : Logs only SQL. jdbc.sqlonly :仅记录 SQL。 SQL executed within a prepared statement is automatically shown with it's bind arguments replaced with the data bound at that position, for greatly increased readability.
在准备好的语句中执行的 SQL 会自动显示,其绑定参数替换为在该位置绑定的数据,以大大提高可读性。 1.0
1.0
jdbc.sqltiming : Logs the SQL, post-execution, including timing statistics on how long the SQL took to execute. jdbc.sqltiming :记录执行后的 SQL,包括 SQL 执行时间的计时统计信息。 1.0
1.0
jdbc.audit : Logs ALL JDBC calls except for ResultSets. jdbc.audit :记录除 ResultSet 之外的所有 JDBC 调用。 This is a very voluminous output, and is not normally needed unless tracking down a specific JDBC problem.
这是一个非常庞大的输出,通常不需要,除非跟踪特定的 JDBC 问题。 1.0
1.0
jdbc.resultset : Even more voluminous, because all calls to ResultSet objects are logged. jdbc.resultset :更加庞大,因为所有对 ResultSet 对象的调用都被记录下来。 1.0
1.0
jdbc.connection : Logs connection open and close events as well as dumping all open connection numbers. jdbc.connection :记录连接打开和关闭事件以及转储所有打开的连接号。 This is very useful for hunting down connection leak problems.
这对于查找连接泄漏问题非常有用。
Very old topic, I know, but what has not been mentioned yet is that for Oracle a solution exists which does not require any change in the application code, just by using the required trace-enabled Oracle JDBC driver and enabling the logging through JVM properties at startup.很老的话题,我知道,但还没有提到的是,对于 Oracle,存在一个不需要更改应用程序代码的解决方案,只需使用所需的启用跟踪的 Oracle JDBC 驱动程序并通过 JVM 属性启用日志记录在启动时。
Oracle themselves have described this here , and after some trial and error I got it to work: Oracle 自己在此处对此进行了描述,经过一些试验和错误后,我让它工作了:
Place the trace-enabled ojdbc jar file in your classpath.将启用跟踪的 ojdbc jar 文件放在您的类路径中。 Quote from the linked Oracle page: "To get log output, you must use the debug JAR files, which are indicated with a "_g" in the file name, like ojdbc5_g.jar or ojdbc6_g.jar."
引用来自链接的 Oracle 页面:“要获取日志输出,您必须使用调试 JAR 文件,这些文件在文件名中以“_g”表示,例如 ojdbc5_g.jar 或 ojdbc6_g.jar。” My Oracle 11g installation contained
我的 Oracle 11g 安装包含
Create a logging.properties file as described on the linked Oracle page, and adjust the logging levels to your needs.按照链接的 Oracle 页面中的说明创建 logging.properties 文件,并根据需要调整日志记录级别。 Example:
例子:
.level=SEVERE oracle.jdbc.level=FINEST oracle.jdbc.handlers=java.util.logging.FileHandler java.util.logging.FileHandler.level=FINEST java.util.logging.FileHandler.pattern=jdbc.log java.util.logging.FileHandler.count=1 java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
Add the JVM properties "-Doracle.jdbc.Trace=true -Djava.util.logging.config.file=logging.properties" to the java startup command for your JDBC application.将 JVM 属性“-Doracle.jdbc.Trace=true -Djava.util.logging.config.file=logging.properties”添加到 JDBC 应用程序的 java 启动命令。
The JDBC application should now produce a file named jdbc.log which should contain the desired information. JDBC 应用程序现在应该生成一个名为 jdbc.log 的文件,其中应该包含所需的信息。 In some cases it can be necessary to specify the full path to the logging.properties file.
在某些情况下,可能需要指定 logging.properties 文件的完整路径。
If you are using Spring framework, then the datasource-proxy framework is very convenient.如果你使用的是Spring框架,那么datasource-proxy框架就非常方便了。 You can basically wrap around any
DataSource
and just add the logging behavior.您基本上可以环绕任何
DataSource
并添加日志记录行为。
If you're using Java EE, then P6spy is a good alternative:如果您使用的是 Java EE,那么 P6spy 是一个不错的选择:
Behind the scenes, p6spy provides the statement interceptor at the Driver
level, which is much more convenient for Java EE applications because the DataSource
is provided by the application server.在幕后, p6spy提供了
Driver
级别的语句拦截器,这对于Java EE 应用程序来说更加方便,因为DataSource
是由应用程序服务器提供的。
Assuming you're using Log4j , just do this:假设您使用的是Log4j ,请执行以下操作:
Use ojdbc_g as mentioned in Oracle JDBC Developer's Guide: Diagnosability in JDBC使用 ojdbc_g,如Oracle JDBC Developer's Guide: Diagnosability in JDBC 中所述
Note, the 19.3 drivers are in Maven now, or just download manually.请注意,19.3 驱动程序现在在 Maven 中,或者只需手动下载。
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8_g</artifactId>
<version>19.3.0.0</version>
</dependency>
You will also need Log4j JDK Logging Adapter您还需要Log4j JDK Logging Adapter
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>2.13.0</version>
</dependency>
Set these System properties:设置这些系统属性:
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
-Doracle.jdbc.Trace=true
Configure your Loggers in log4j2.xml在log4j2.xml 中配置您的记录器
<Logger name="oracle.jdbc" level="TRACE">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="oracle.sql" level="TRACE">
<AppenderRef ref="Console"/>
</Logger>
Note that level="ALL"
will give the finest level of logging请注意,
level="ALL"
将提供最好的日志记录级别
Have you tried setting the corresponding system property?您是否尝试过设置相应的系统属性? eg.
例如。 for TRACE:
对于跟踪:
System.setProperty( "oracle.jdbc.Trace", Boolean.TRUE.toString() );
(from https://docs.oracle.com/cd/B28359_01/java.111/b31224/diagnose.htm ) (来自https://docs.oracle.com/cd/B28359_01/java.111/b31224/diagnose.htm )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.