log4jdbc是用来记录数据库sql的jar包。需要与log类.jar一起使用。之前我们公司使用的是log4j。但是据说log4j有性能问题。最后我们换用了现在比较流行的logback日志框架。但是,中间需要用适配的jar包,所以组合为log4jdbc+log4j-over-slfj+logback。
一、如何配置
数据库连接配置修改如下:
#driver需要配置为适配的log4jdbc的驱动类 dataSource.driverClass=net.sf.log4jdbc.sql.jdbcapi.DriverSpy #jdbcUrl需要增加前面的head:jdbc\:log4 dataSource.jdbcUrl=jdbc\:log4jdbc\:jtds\:sybase\://ip\:port/db;charset\=UTF-8;appname\=appname;
log4jdbc特有的配置-log4jdbc.log4j2.properties:
#配置真实的数据库驱动 log4jdbc.drivers=net.sourceforge.jtds.jdbc.Driver # log4jdbc.dump.fulldebugstacktrace=false #配置为需要记录的包或类匹配路径 log4jdbc.debug.stack.prefix= #sql的最大占行长度 log4jdbc.dump.sql.maxlinelength=150 #spy日志处理类 log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator #warn级别的日志,时间耗时超过配置值的会打印出来 log4jdbc.sqltiming.warn.threshold=100logback配置:
二、源码跟踪${baseHome}/${appname}_jdbc_${ip}_${port}.log %d{yyyy-MM-dd HH:mm:ss} [%-5level] [%-5thread] %logger{20} - %msg%n warn true ${baseHome}/${appname}_jdbc_${ip}_${port}.%d{yyyy-MM-dd}(%i).log 200MB
首先,我们先看看代理的驱动类--net.sf.log4jdbc.sql.jdbcapi.DriverSpy
1.为什么jdbcUrl需要增加前面的head:jdbc\:log4?
/** * A2.log4jdbc.log4j.properties只有这几个属性吗?String
representing the prefix of URL * to use log4jdbc. */ static final private String log4jdbcUrlPrefix = "jdbc:log4"; /** * Get the actual URL that the real driver expects * (strip off#log4jdbcUrlPrefix
fromurl
). * * @param url AString
corresponding to a JDBC url for log4jdbc. * @return AString
representing url * with#log4jdbcUrlPrefix
stripped off. */ private String getRealUrl(String url) { return url.substring(log4jdbcUrlPrefix.length()); }
不止呢@~@
//你可以知道的远不止这些 public final class Properties { private static volatile SpyLogDelegator log; /** * A3.是哪调用的log4jdbc的connect方法呢?String
representing the name of the class implementing *SpyLogDelegator
to use. It is used by {@link SpyLogFactory} * to determine which class to load. * Default isnet.sf.log4jdbc.log4j2.Log4j2SpyLogDelegator
* * @see SpyLogFactory */ static final String SpyLogDelegatorName; //这里就先列一个想看的自己看看properties /** * Static initializer. */ static { //first we init the logger log = null; //then we need the properties to define which logger to use java.util.Properties props = getProperties(); SpyLogDelegatorName = props.getProperty("log4jdbc.spylogdelegator.name");//。。。。。 } private static java.util.Properties getProperties() { java.util.Properties props = new java.util.Properties(System.getProperties()); //try to get the properties file. //default name is log4jdbc.log4j2.properties //check first if an alternative name has been provided in the System properties String propertyFile = props.getProperty("log4jdbc.log4j2.properties.file", "/log4jdbc.log4j2.properties"); if (log != null) { log.debug("Trying to use properties file " + propertyFile); } InputStream propStream = Properties.class.getResourceAsStream(propertyFile); if (propStream != null) { try { props.load(propStream); } catch (IOException e) { if (log != null) { log.debug("Error when loading log4jdbc.log4j2.properties from classpath: " + e.getMessage()); } } finally { try { propStream.close(); } catch (IOException e) { if (log != null) { log.debug("Error when closing log4jdbc.log4j2.properties file" + e.getMessage()); } } } if (log != null) { log.debug("log4jdbc.logj2.properties loaded from classpath"); } } else { if (log != null) { log.debug("log4jdbc.logj2.properties not found in classpath. Using System properties."); } } return props; } }
java.sql.DriverManager的getConnection方法
try { println(" trying " + aDriver.driver.getClass().getName()); Connection con = aDriver.driver.connect(url, info); if (con != null) { // Success! println("getConnection returning " + aDriver.driver.getClass().getName()); return (con); } } catch (SQLException ex) { if (reason == null) { reason = ex; } }4.什么时候记录的日志的?
public boolean execute(String sql, String[] columnNames) throws SQLException { String methodCall = "execute(" + sql + ", " + columnNames + ")"; this.sql = sql; reportStatementSql(sql, methodCall); //这个地方开始调用Slf4jSpyLogDelegator long tstart = System.currentTimeMillis(); try { boolean result = realStatement.execute(sql, columnNames); reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);//2 return reportReturn(methodCall, result);//3 } catch (SQLException s) { reportException(methodCall, s, sql, System.currentTimeMillis() - tstart); throw s; } }以下是打印sql的处理类,如果你想按照你的标准或是日志级别分配的话,你可以实现接口SpyLogDelegator:
以上是我的全部内容。我是游走在IT届的小女子,有人问你想在IT走多远?我想说,别人能走多远,我同样能!没有终点!