2014-11-21 146 views
24

我试图通过连接到eclipse IDE中的Oracle数据库来使用我的JDBC程序启用日志。为JDBC启用日志记录

我已经通过这个SO发布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(); 
     } 
    } 

} 

,我有以下我OracleLog.properties内容文件:

INFO: Test Message 
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,[email protected] 
    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 

.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 

但是,当我放置在ojdbc6-11.2.0.3.jar然后classpath中我得到异常的运行我的程序

如果我在类路径中有ojdbc6_g.jar,那么我也会得到相同的异常。

请让我知道如何为我的JDBC程序启用日志记录?基本上我期待看到由内部JDBC代码生成的日志。

更新: 现在我把ojdbc6dms.jar文件中的classpath,我的计划是给下面的例外:

Nov 28, 2014 9:09:02 PM jdbc.chap2.Logging main 
INFO: Test Message 
javax.management.InstanceNotFoundException: com.oracle.jdbc:type=diagnosability,[email protected] 
    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 
+0

你有没有正确的驱动程序在classpath中? '确保调试JAR文件(例如ojdbc5_g.jar或ojdbc6_g.jar)是CLASSPATH环境变量中唯一的Oracle JDBC JAR文件。'和'为了获得日志输出,你必须使用调试JAR文件,这些文件在文件名' – 2014-11-21 11:51:10

+0

@ KonstantinV.Salikhov'中用'_g'表示,现在我已经尝试在类路径中使用'ojdbc6_g.jar',但是得到了相同的错误消息,我已更新我的问题与错误的详细信息。 – user3181365 2014-11-21 11:59:04

+1

mbean使用不同的名称进行注册,请尝试使用jconsole并查看mbean名称并使用正确的名称。 – 2014-11-21 12:02:57

回答

5

如果你使用Spring框架,那么datasource-proxy是非常方便的。您基本上可以环绕任何DataSource,并添加日志记录行为。

enter image description here

如果您使用的是Java EE,然后P6SPY是一个很好的选择:

enter image description here

在幕后,p6spy提供在Driver水平的声明拦截弹,这是多大对于Java EE应用程序更方便,因为DataSource由应用程序服务器提供。

+0

嗨弗拉德,请你看看我的文章在休眠 - http:// stackoverflow。com/questions/37088759/get-employee-with-highest-salary-in-each-department – user3181365 2016-05-07 13:46:08

10

有很多间谍框架可用于这一目的,请log4jdbc,我爱上这是你在找什么。

特点

  • 为JDBC 3和JDBC 4全支持!
  • 易于配置,在大多数情况下 所有你需要做的是改变驱动程序类名 net.sf.log4jdbc.DriverSpy和前面加上“JDBC:LOG4”您现有的 JDBC URL,建立你的日志类别你准备好了!
  • 在记录的输出中,对于预处理语句,绑定参数是 自动插入到SQL输出中。这在很多情况下大大提高了可读性和调试性。
  • SQL可以生成定时信息,以帮助识别SQL语句花费多长时间运行, 帮助识别太慢了运行报表,这 数据能够后用附带的工具,以产生刨 报告数据快速处理在您的应用程序中识别慢SQL。
  • 生成SQL连接号码信息以帮助识别连接池或线程问题 。适用于任何底层的 JDBC驱动程序,JDK 1.4及更高版本和SLF4J 1.x.
  • 开放源代码软件,以友好商务Apache 2授权。0许可证

使用

  • 放置log4jdbc罐子(基于JDK版本)到应用程序的类路径。
  • 选择使用日志记录系统,log4j,logback,commons logging..etc支持
  • 在您的应用程序配置中将您的JDBC驱动程序类设置为net.sf.log4jdbc.DriverSpy。 在许多情况下被监视的底层驱动程序将自动加载,无需任何额外的配置。
  • 将jdbc:log4预先挂载到您正在使用的正常jdbc url。

    例如,如果你的正常JDBC URL是JDBC :德比://本地主机:1527 // DB-德比10.2.2.0斌/数据库/ MYDATABASE 这样,你会改变为: JDBC:log4jdbc :derby:// localhost:1527 // db-derby-10.2.2.0-bin/databases/MyDatabase

  • 设置您的记录器。

    jdbc.sqlonly:仅记录SQL。在准备好的语句中执行的SQL会自动显示其绑定参数替换为绑定在该位置的数据,从而大大提高可读性。 1.0

    jdbc.sqltiming:记录SQL,执行后,包括SQL执行时间的计时统计信息。 1.0

    jdbc.audit:记录除ResultSets以外的所有JDBC调用。这是一个非常庞大的输出,通常不需要,除非跟踪一个特定的JDBC问题。 1.0

    jdbc.resultset:更大量,因为所有对ResultSet对象的调用都被记录下来。 1.0

    jdbc.connection:记录连接打开和关闭事件以及转储所有打开的连接号。这对于追查连接泄漏问题非常有用。

+0

虽然这个链接可能回答这个问题,但最好在这里包含答案的重要部分,并提供供参考的链接。如果链接页面更改,则仅链接答案可能会失效。 – 2014-12-02 06:59:34

+0

谢谢埃里克,我已经更新了我的文章的详细信息 – Prince 2014-12-02 07:59:44

3

我知道很老的话题,但是还没有提到的是,对于Oracle来说,存在一个解决方案,它不需要对应用程序代码进行任何更改,只需使用所需的启用跟踪的Oracle JDBC驱动程序并启用在启动时通过JVM属性记录日志。

甲骨文自己也描述这here,和一些试验和错误后,我得到它的工作:

  1. 将在类路径中启用跟踪ojdbc jar文件。从链接的Oracle页面引用:“要获取日志输出,您必须使用调试JAR文件,文件名中用”_g“表示,如ojdbc5_g.jar或ojdbc6_g.jar。”我的Oracle 11g安装包含

  2. 按链接的Oracle页面上所述创建logging.properties文件,并根据需要调整日志记录级别。例如:

    .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

  3. 您的JDBC应用程序添加JVM属性 “-Doracle.jdbc.Trace =真-Djava.util.logging.config.file = logging.properties” 到java启动命令。

JDBC应用程序现在应该生成一个名为jdbc.log的文件,该文件应该包含所需的信息。在某些情况下,可能需要指定logging.properties文件的完整路径。

+0

这个答案真的很有趣,因为它允许检查应用程序的JDBC/Oracle行为而不必更改其代码。 – 2017-02-17 22:09:54

+0

这是什么'.level = .SEVERE'?它给我一个错误的价值错误。 – Stephane 2017-03-03 10:27:02

+0

它的错字,应该是'.level = SEVERE' – 2018-02-05 16:53:34