日期:2014-05-16  浏览次数:20524 次

日志框架(二)------log4j 扩展 JdbcAppender输出器

?

?

log4j中提供了将日志记录到数据库中的输出器: org.apache.log4j.jdbc.JDBCAppender。通过以下配置即可生效

?

log4j.logger.dbLog=ERROR,dbLogAppender
log4j.appender.dbLogAppender=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.dbLogAppender.URL=jdbc:mysql://localhost:3306/test
log4j.appender.dbLogAppender.driver=com.mysql.jdbc.Driver
log4j.appender.dbLogAppender.user=root
log4j.appender.dbLogAppender.password=xiaodi
log4j.appender.dbLogAppender.sql=insert into t_log4j_info(priority,message,catalog,time) values('%p','%m','%c','%d{yyyy-MM-dd HH:mm:ss}')
log4j.appender.dbLogAppender.bufferSize=10
log4j.appender.dbLogAppender.layout=org.apache.log4j.PatternLayout

扩展类 PrepareStatementJdbcAppender 和?JndiDataSourceAppender

?

JdbcAppender使用JDBC 的Statement提交sql,本例基于PreparedStatement重新实现数据库输出器(PrepareStatementJdbcAppender),

并以此为父类实现调用JNDI数据源的输出器(JndiDataSourceAppender)。

?

PrepareStatementJdbcAppender类定义

?

/**
 * 支持预编译sql的jdbc输出器<br>
 * 设置参数:<br>
 * URL、driver、user、password、sql、sqlParams 、[bufferSize]<br>
 * 不需要设置layout
 * 
 * @author houfeng-win7
 * 
 */
public class PrepareStatementJdbcAppender extends
		org.apache.log4j.AppenderSkeleton implements org.apache.log4j.Appender {

	protected Connection connection = null;

	protected String driverClass;
	protected String databaseURL = "jdbc:mysql://localhost:3306/test";
	protected String databaseUser = "root";
	protected String databasePassword = "xiaodi";

	/**
	 *  预编译sql //insert into tab values (?,?)
	 */
	protected String sqlStatement = "";
 
	/**
	 * sql参数 有序字符串 <br>
	 * 不要有任何多余字符。
	 * 格式范例:%p%m%c%d{yyyy-MM-dd HH:mm:ss}
	 */
	protected String sqlParams = "";
	/**
	 * 存储当前sql参数值
	 */
	protected ArrayList sqlParamValues ;

	protected int bufferSize = 1;
	protected ArrayList buffer;
	protected ArrayList removes;

	/**
	 * sqlParams模式转换器
	 */
	protected PatternConverter patternConverter;


	public PrepareStatementJdbcAppender() {
		this.buffer = new ArrayList(this.bufferSize);
		this.removes = new ArrayList(this.bufferSize);
	}

	public void append(LoggingEvent event) {

		if (!checkEntryConditions())
			return;

		this.buffer.add(event);

		if (this.buffer.size() >= this.bufferSize)
			flushBuffer();
	}

	/**
	 * 检测必需参数是否设置 
	 * @return
	 */
	protected boolean checkEntryConditions() {
		if(this.driverClass == null){
			this.errorHandler.error("No 'driver' set for the appender named [" + name + "]");
			return false;
		}
		if(this.databaseURL == null){
			this.errorHandler.error("No 'URL' set for the appender named [" + name + "]");
			return false;
		}
		if(this.databaseUser == null){
			this.errorHandler.error("No 'user' set for the appender named [" + name + "]");
			return false;
		}
		if(this.databasePassword == null){
			this.errorHandler.error("No 'password' set for the appender named [" + name + "]");
			return false;
		}
		if(this.sqlStatement == null){
			this.errorHandler.error("No 'sql' set for the appender named [" + name + "]");
			return false;
		}
		if (this.sqlParams == null || this.patternConverter == null) {
			this.errorHandler.error("No 'sqlParams' set for the appender named [" + name + "]");
			return false;
		}

		return true;
	}

	protected void execute()  {
		String sql = this.sqlStatement; 
		ArrayList list = this.sqlParamValues;
		Connection con = null;
		PreparedStatement stmt = null;
		
		try {
			try {
				con = getConnection(); 
				stmt = con.prepareStatement(sql);
				for(int i=0;i<list.size();i++){
					stmt.setString(i+1, list.get(i).toString());
				} 
				stmt.executeUpdate(); 
			} finally{
				stmt.close();
				closeConnection(con); 
			}
		} catch (SQLException e) {
			errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
		} 
	}

	protected void closeConnection(Connection con) {
		// 不