`
johnson.lee
  • 浏览: 51598 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Log4j记录日志到数据库

阅读更多
[list]
  • 1.自定义输出消息
  • /**
     * 参数化消息
     * @author Johnson.Lee
     *
     */
    public interface ParameterizedMessage extends Serializable {
    
    	/**
    	 * 获取参数列表
    	 * @return 返回参数列表
    	 */
    	public Object[] getParameters();
    	
    	/**
    	 * 获取指定索引位置的参数
    	 * @param index 索引位置
    	 * @return 返回参数列表中指定索引位置的参数值
    	 * @throws IndexOutOfBoundsException 当index >= 参数列表个数时,抛出此异常
    	 * @see #getParameterCount()
    	 */
    	public Object getParameter(int index) throws IndexOutOfBoundsException;
    	
    	/**
    	 * 获取参数个数
    	 * @return 返回参数个数
    	 */
    	public int getParameterCount();
    	
    }
    

    /**
     * JDBC日志消息
     * @author Johnson.Lee
     *
     */
    public class JDBCLogMessage implements ParameterizedMessage {
    	private static final long serialVersionUID = 1709063421963292637L;
    	private Object[] params;
    	
    	public JDBCLogMessage(Object... params) {
    		this.params = params;
    	}
    
    	public Object[] getParameters() {
    		return this.params;
    	}
    
    	public Object getParameter(int index) throws IndexOutOfBoundsException {
    		return this.params[index];
    	}
    
    	public int getParameterCount() {
    		return this.params.length;
    	}
    
    	@Override
    	public String toString() {
    		return Arrays.toString(this.params);
    	}
    }
    
  • 2.继承Log4j的AppenderSkeleton
  • /**
     * 使用纯JDBC连接将日志记录到数据库中
     * @author Johnson.Lee
     *
     */
    public class JDBCAppender extends AppenderSkeleton {
    	private String driver;
    	private String url;
    	private String userName;
    	private String password;
    	private String sql;
    
    	@Override
    	protected void append(LoggingEvent e) {
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		try {
    			Class.forName(this.driver);
    			conn = DriverManager.getConnection(this.url, this.userName, this.password);
    			if (e.getMessage() instanceof ParameterizedMessage) {
    				try {
    					pstmt = conn.prepareStatement(sql);
    					Object[] params = ((ParameterizedMessage) e.getMessage()).getParameters();
    					for (int i = 0; i < params.length; i++) {
    						pstmt.setObject(i + 1, params[i]);
    					}
    					pstmt.executeUpdate();
    				} catch (SQLException ex) {
    					this.errorHandler.error("log into database failed!", ex, 0);
    				} finally {
    					AbstractJDBCDao.close(pstmt);
    					AbstractJDBCDao.close(conn);
    				}
    			}
    		} catch (ClassNotFoundException ex) {
    			this.errorHandler.error("load jdbc driver [" + this.driver + "] failed!", ex, 0);
    		} catch (SQLException ex) {
    			this.errorHandler.error("establish connect failed!", ex, 0);
    		}
    	}
    	
    	@Override
    	public void close() {
    	}
    
    	@Override
    	public boolean requiresLayout() {
    		return false;
    	}
    
    	/**
    	 * 设置JDBC驱动
    	 * @param driver JDBC驱动类名
    	 */
    	public void setDriver(String driver) {
    		this.driver = driver;
    	}
    
    	/**
    	 * 设置连接字符串
    	 * @param url 数据库连接字符串
    	 */
    	public void setUrl(String url) {
    		this.url = url;
    	}
    
    	/**
    	 * 设置数据库用户名
    	 * @param userName 用户名
    	 */
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    
    	/**
    	 * 设置数据库密码
    	 * @param password 密码
    	 */
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	/**
    	 * 设置插入日志的SQL语句
    	 * @param sql
    	 */
    	public void setSql(String sql) {
    		this.sql = sql;
    	}
    	
    }
    
  • 3.配置log4j.properties
  • log4j.rootLogger=INFO, stdout, jdbc
    
    #std appender
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
    
    #file appender
    #log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
    #log4j.appender.file.File=${application.context}
    #log4j.appender.file.DatePattern='_'yyyyMMdd'.log'
    #log4j.appender.file.layout=org.apache.log4j.PatternLayout
    #log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n
    
    #jdbc appender
    log4j.appender.jdbc=net.kinginfo.framework.log.JDBCAppender
    log4j.appender.jdbc.driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
    log4j.appender.jdbc.url=jdbc:microsoft:sqlserver://192.172.10.106:1433;databaseName=tempdb
    log4j.appender.jdbc.userName=sa
    log4j.appender.jdbc.password=sa
    log4j.appender.jdbc.sql=insert into LogInfo(time, type, info) values(getDate(),?,?)
    
  • 4.创建日志表
  • use tempdb;
    
    create table LogInfo (
    	id int identity(1,1) primary key not null,
    	time datetime,
    	type int,
    	info varchar(255)
    );
    
    select * from LogInfo;
    
  • 5.编写测试类
  • public class TestJDBCAppender {
    	
    	public static void main(String[] args) {
    		Logger logger = Logger.getRootLogger();
    		ParameterizedMessage msg = new JDBCLogMessage(1, "日志测试");
    		logger.info(msg);
    	}
    }
    

    [/list]
    0
    1
    分享到:
    评论
    2 楼 johnson.lee 2009-12-05  
    sunrie 写道
    能不能做到异步的记录到数据库呢?

    1楼所指的异步是指多线程并发的记录日志到数据库中吧?异步记录应该是没问题的,像对HTTP请求做处理时,就有并发的情况,用log4j记录日志是没问题的。
    1 楼 sunrie 2009-12-01  
    能不能做到异步的记录到数据库呢?

    相关推荐

    Global site tag (gtag.js) - Google Analytics