JDBC logging to file

前端 未结 6 553
隐瞒了意图╮
隐瞒了意图╮ 2020-12-06 02:43

I need to log all the queries to an Oracle database in my project to a log file.

What would be a good solution to achieve this? Some sample usage would be a

相关标签:
6条回答
  • 2020-12-06 02:45

    As an update to the answer of @Martin_Schröder, it also now exists log4jdbc-log4j2, which allows to use either slf4j or Log4j2, is available on the Maven repository, and supports JDBC 4.1 (Java 7).

    0 讨论(0)
  • 2020-12-06 02:46

    If you are using Spring, then the datasource-proxy is very convenient. You can basically wrap around any DataSource and just add the logging behavior.

    If you're using Java EE, then P6spy is a good alternative:

    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.

    0 讨论(0)
  • 2020-12-06 02:51

    suggest you look at jdbcdslog's user guide and discussion group.

    A quick look at the user guide suggests that you can wrap (decorate) any JDBC connection with one of jdbcdslog's special logging wrappers, and it will log to whatever place you configure.

    Furthermore it says it uses slf4j which supports logging to several logging engines including java.util.logging, so what you suggest seems very possible.

    (But I'm not familiar with this jdbcdslog so I'm not sure how to get things configured.)

    0 讨论(0)
  • 2020-12-06 02:54

    I'm measuring the performance of my jdbc driver, this is a Tandem Non/Stop DB, and just setting the LogWriter in the DriverManager like this:

            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());
            }
    

    The logging on Queries started working.


    Just as an update, I also found out that for some JDBC drivers the solution can NOT be accomplished programatically (by code changes). For example, I'm using a JDBC driver for Tandem t4 driver, and even though I added all what the manuals said about enabling JDBC tracing, it just worked from time to time and just for Queries..

    Then, I was told to use just the following parameter (as a VM Option):

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

    And it just simple started working..

    0 讨论(0)
  • 2020-12-06 02:58

    You configure where log messages are written by configuring where the underlying logging engine is sending them. Since you're talking about slf4j, that means you've got to configure the thing that it is bridging to (the java.util.logging system in your case; called JUL henceforth).

    Unfortunately, JUL is among the more confusing systems to configure. Here's where I'll just cut to the chase. Create a file in your deployed classpath called logging.properties (I think; this is one of the confusing bits) which contains something like this:

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

    The documentation on the FileHandler class describes things that you can configure.

    0 讨论(0)
  • 2020-12-06 03:11

    After much reading, this is how I got things working :


    NOTE : Fore more information, read the Oracle Diagnosability in JDBC document


    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);
    

    And here's the magic :

    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));
        }
    }
    

    The properties file (from Oracle's documentation) :

    .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
    

    Basically, this is where the handlers are declared

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

    Declares the ConsoleHandler to be used by Oracle's JDBC driver. Any and any number of handlers can be declared here, one per line, with the class' full qualified name :

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

    One can provide their own custom made handlers with the same rule. The following lines are to setup the handler

    java.util.logging.ConsoleHandler.level=INFO
    

    will call the methode setLevel(Level.INFO) of the ConsoleHandler handler instance.

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

    will call the method setFoo("Bar") of the MyHandler handler instance. And that's it.

    Happy logging!

    0 讨论(0)
提交回复
热议问题