【问题标题】:JDBC logging to fileJDBC 记录到文件
【发布时间】:2011-08-09 22:32:11
【问题描述】:

我需要将项目中对 Oracle 数据库的所有查询记录到日志文件中。

实现此目标的解决方案是什么?一些示例用法将不胜感激。

我查看了SLF4Jjdbcdslog,但我不确定如何使用它登录文件。此外,我需要“过滤”一些日志(因为我不需要知道何时调用了某些 getxxxx 方法)

我更喜欢使用java.util.logging,但这不是必需的。

谢谢。

** 更新 **

我找到了this Oracle article,但它并没有真正说明如何以编程方式做同样的事情。

【问题讨论】:

    标签: java logging jdbc


    【解决方案1】:

    经过大量阅读,这就是我的工作方式:


    注意:有关更多信息,请阅读 Oracle Diagnosability in JDBC 文档


    Properties prop = new Properties();
    prop.put ("user", USER);
    prop.put ("password", PASS);
    // prop.put(propname, propValue);
    
    Class.forName("oracle.jdbc.driver.OracleDriver");
    
    enableLogging(false);
    
    conn = DriverManager.getConnection("jdbc:oracle:thin:@"+HOST+":"+PORT+":"+SID, prop);
    

    这就是魔法:

    static private void enableLogging(boolean logDriver) 
    throws MalformedObjectNameException, NullPointerException, 
           AttributeNotFoundException, InstanceNotFoundException, 
           MBeanException, ReflectionException, InvalidAttributeValueException, 
           SecurityException, FileNotFoundException, IOException 
    {
        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));
        }
    }
    

    属性文件(来自 Oracle 的文档):

    .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
    

    基本上,这是声明处理程序的地方

    oracle.jdbc.handlers=java.util.logging.ConsoleHandler
    

    声明供 Oracle 的 JDBC 驱动程序使用的 ConsoleHandler。可以在这里声明任意数量的处理程序,每行一个,使用类的完整限定名:

    oracle.jdbc.handlers=java.util.logging.ConsoleHandler
    oracle.jdbc.handlers=java.util.logging.FileHandler
    ...
    

    可以为他们自己的定制处理程序提供相同的规则。以下几行用于设置处理程序

    java.util.logging.ConsoleHandler.level=INFO
    

    将调用ConsoleHandler处理程序实例的setLevel(Level.INFO)方法。

    com.my.own.project.logging.handler.MyHandler.foo=Bar
    

    将调用MyHandler 处理程序实例的方法setFoo("Bar")。就是这样。

    记录愉快!

    【讨论】:

    • 嗨,Yanick,我按照您解决方案中的所有步骤操作,但在启用日志时遇到了问题,请您看看我的帖子并纠正我的错误。 --> stackoverflow.com/questions/27060563/enable-logging-for-jdbc
    • 感谢您的信息。依靠 Oracle 将原本应该简单的事情变成 20 步的过程。
    【解决方案2】:

    建议你看看jdbcdslog's user guidediscussion group

    快速浏览一下用户指南建议您可以使用 jdbcdslog 的特殊日志包装器之一包装(装饰)任何 JDBC 连接,它会记录到您配置的任何位置。

    此外,它说它使用 slf4j,它支持记录到包括 java.util.logging 在内的多个日志引擎,所以你的建议似乎很有可能。

    (但我不熟悉这个 jdbcdslog,所以我不确定如何配置。)

    【讨论】:

    • 是的,我读了很多东西,但我读到的内容足以理解基础知识;目前,它正在记录到控制台,但我需要过滤日志,我不知道如何:)
    • 哦!这是一个日志框架问题,而不是 jdbcdslog 问题。 (根据我从 jdbcdslog 用户指南中收集到的信息,它只查找 slf4j 并且一切都自动启动。此时配置由日志框架处理。)您可能最好使用 log4j,它很容易配置,还有很多很好的例子。
    【解决方案3】:

    您可以通过配置底层日志引擎发送日志消息的位置来配置日志消息的写入位置。由于您在谈论 slf4j,这意味着您必须配置它所桥接的东西(在您的情况下为 java.util.logging 系统;此后称为 JUL)。

    不幸的是,JUL 是更容易配置的系统之一。这就是我要切入正题的地方。在您部署的类路径中创建一个名为 logging.properties 的文件(我认为;这是令人困惑的部分之一),其中包含以下内容:

    handlers=java.util.logging.FileHandler
    .level=ALL
    java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
    

    FileHandler 类的文档描述了您可以配置的内容。

    【讨论】:

    • 我更喜欢自己通过log4j登录;我可以使它产生比使用 ​​JUL(没有自定义代码)更紧凑和有用的输出。文档也更清晰。
    • 我同意。我不知道如何让 JUL 工作,所以我只是通过 slf4j+log4j。
    【解决方案4】:

    作为对@Martin_Schröder 答案的更新,它现在还存在log4jdbc-log4j2,它允许使用 slf4j 或 Log4j2,在 Maven 存储库中可用,并支持 JDBC 4.1 (Java 7)。

    【讨论】:

      【解决方案5】:

      我正在测量我的 jdbc 驱动程序的性能,这是一个 Tandem Non/Stop DB,只需像这样在 DriverManager 中设置 LogWriter:

              try {
                  // This will load the JDBC Driver
                  Class.forName("com.tandem.t4jdbc.SQLMXDriver");
                  // Here you will enable the Logging to a file.
                  DriverManager.setLogWriter(new PrintWriter(new File("log/dbcLog.log")));
              } catch (ClassNotFoundException e) {
                  _logger.error(e.toString());
              }
      

      查询日志开始工作。


      作为更新,我还发现对于某些 JDBC 驱动程序,该解决方案无法以编程方式完成(通过代码更改)。 例如,我为 Tandem t4 驱动程序使用了 JDBC 驱动程序,即使我添加了手册中关于启用 JDBC 跟踪的所有内容,它只是不时地工作,而且只适用于查询..

      然后,我被告知只使用以下参数(作为 VM 选项):

      -Dt4sqlmx.T4LogFile=t4sqlmx.log -Dt4sqlmx.T4LogLevel=FINE
      

      它只是简单地开始工作..

      【讨论】:

      • 我还发现,对于某些 JDBC 驱动程序,解决方案无法以编程方式完成(通过代码更改)。例如,我正在为 Tandem t4 驱动程序使用 JDBC 驱动程序,即使我添加了手册中关于启用 JDBC 跟踪的所有内容,但它只是不时地工作,而且只适用于查询。然后,我被告知使用只需以下参数:-Dt4sqlmx.T4LogFile=t4sqlmx.log -Dt4sqlmx.T4LogLevel=FINE 它只是简单地开始工作......
      【解决方案6】:

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

      如果您使用的是 Java EE,那么 P6spy 是一个不错的选择:

      在幕后,P6spy 提供了Driver 级别的语句拦截器,这对于 Java EE 应用程序来说更加方便,因为DataSource 是由应用程序服务器提供的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-27
        • 2017-09-25
        • 1970-01-01
        • 1970-01-01
        • 2012-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多