log4jdbc源码解析(1)

阅读更多

        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=100 
    logback配置:

		${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?

 

	/**
	 * A 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 from url).
	 * 
	 * @param url 	A String corresponding to a JDBC url for log4jdbc. 
	 * @return 		A String representing url 
	 * 				with #log4jdbcUrlPrefix stripped off. 
	 */
	private String getRealUrl(String url)
	{
		return url.substring(log4jdbcUrlPrefix.length());
	}
 2.log4jdbc.log4j.properties只有这几个属性吗?

 不止呢@~@

//你可以知道的远不止这些
public final class Properties 
{
	private static volatile SpyLogDelegator log;

	/**
	 * A String representing the name of the class implementing 
	 * SpyLogDelegator to use. It is used by {@link SpyLogFactory} 
	 * to determine which class to load. 
	 * Default is net.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;
	}
 }
 3.是哪调用的log4jdbc的connect方法呢?

 

    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.什么时候记录的日志的?

 
log4jdbc源码解析(1)_第1张图片
 这些都是检测的sql_spy类:

 

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:
log4jdbc源码解析(1)_第2张图片
 

 

 以上是我的全部内容。我是游走在IT届的小女子,有人问你想在IT走多远?我想说,别人能走多远,我同样能!没有终点!

   

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       

 

  • log4jdbc源码解析(1)_第3张图片
  • 大小: 35.7 KB
  • log4jdbc源码解析(1)_第4张图片
  • 大小: 133.2 KB
  • 查看图片附件

你可能感兴趣的:(log4jdbc)