JDBC记录到文件
我需要将我项目中的Oracle数据库的所有查询记录到日志文件中。
实现这一目标的好方法是什么? 一些样品用法将不胜感激。
我用jdbcdslog查看了SLF4J ,但我不知道如何用它来登录文件。 此外,我需要“过滤”一些日志(因为我不需要知道什么时候调用一些getxxxx
方法)
最好,我更喜欢使用java.util.logging
但这不是必需的。
谢谢。
** 更新 **
我发现了这篇Oracle文章 ,但它并没有真正告诉我如何以编程方式执行相同的操作。
经过多次阅读,这就是我的工作方式:
注意:有关更多信息,请阅读JDBC文档中的Oracle Diagnosability
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
声明ConsoleHandler
将由Oracle的JDBC驱动程序使用。 可以在此声明任意数量和任意数量的处理程序,每行一个,具有类的完全限定名称:
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")
。 就是这样。
快乐的伐木!
建议你看一下jdbcdslog的用户指南和讨论组 。
快速查看用户指南建议您可以使用jdbcdslog的特殊日志包装器之一来包装(装饰)任何JDBC连接,并且它将记录到您配置的任何位置。
此外它说它使用slf4j支持记录到几个日志引擎,包括java.util.logging,所以你的建议似乎很有可能。
(但是我不熟悉这个jdbcdslog,所以我不确定如何配置它。)
您可以通过配置基础日志引擎发送日志消息的位置来配置日志消息的写入位置。 既然你在谈论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
类的文档描述了您可以配置的内容。
作为@Martin_Schröder答案的更新,它现在也存在log4jdbc-log4j2 ,允许使用slf4j或Log4j2,可在Maven存储库中使用,并支持JDBC 4.1(Java 7)。
我正在测量我的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
它只是简单的开始工作..
如果您使用的是Spring,那么datasource-proxy非常方便。 您基本上可以包装任何DataSource
,只需添加日志记录行为即可。
如果你正在使用Java EE,那么P6spy是一个很好的选择:
在幕后, P6spy在Driver
级别提供了语句拦截器,这对Java EE应用程序来说更方便,因为DataSource
是由应用程序服务器提供的。