这个包主要是处理数据库的,logback日志输出的目的地有三个控制台、文件、数据库。这个包提供了ch.qos.logback.core.db.dialect.SQLDialect、ch.qos.logback.core.db.ConnectionSource、ch.qos.logback.core.db.DBAppenderBase<E>三个接口把日志输入到数据库表中的。和日志相关的表有三个logging_event、logging_event_property、logging_event_exception。三个表的脚本文件在logback-classic.jar的ch.qos.logback.classic.db.script包下可自行获取。下面具体分析每一个接口的具体作用
1、ch.qos.logback.core.db.dialect.SQLDialect接口:该接口是一个数据库方言接口,一想到数据库的方言我们应该明白是为适配各种数据库差异性的。就像每种数据库的分页以及获取自增主键的sql都是不同。logback的方言主要实现各种数据库logging_event表自增主键EVENT_ID字段的值。logback目前支持的数据库类型:postgresql、mysql、oracle、microsoft、hsql、h2、sql anywhere、sqlite。具体接口图如下

2、ch.qos.logback.core.db.ConnectionSource接口:该接口主要提供四种能力,第一个getConnection()获取connection连接、第二个getSQLDialectCode()通过DatabaseMetaDatagetDatabaseProductName()方法计算出SQLDialectCode枚举值,第三个supportsGetGeneratedKeys()判断驱动是否有现成的api获取自增主键值,如果不没有就通过sql去获取,也就是上面的方言实现类的getSelectInertId()方法获取,第四个supportsBatchUpdates()判断驱动是否支持批量操作如果不支持就追条追条插入。第二、三、四在基类ch.qos.logback.core.db.ConnectionSourceBase都已经实现。第一个在基类ConnectionSourceBase的子类中实现,这里强调下一般获取connection有三种方式第一种通过最原始的方式jdbc驱动可以获取connction,第二种通过dataSource对象的getConnection()方法获取,目的是为了能够对接第三方连接池框架。第三种就是jndi的方式。具体看图

3、ch.qos.logback.core.db.DBAppenderBase<E>接口:该接口的目的是要把日志对象插入数据库的表中,一个模板方法append(),三个抽象方法:getInsertSQL()方法获取插入logging_event表的sql,subAppend()方法执行插入logging_event表的sql,secondarySubAppend()方法执行插入表logging_event_property和logging_event_exception两个表的sql。 append()是抽象类ch.qos.logback.core.db.DBAppenderBase的核心方法,但是在执行append()之前需要调用start()初始化SQLDialect对象以及cnxSupportsGetGeneratedKeys和cnxSupportsBatchUpdates属性。
该方法分为几步:
第一步:通过ch.qos.logback.core.db.ConnectionSource接口获取connection对象。
第二步:执行插入logging_event表的sql并获取自增主键值。
第三步:执行插入logging_event_property和logging_event_exception表的sql。
模板方法append()见图

类图如下

4、最后给一个例子
创建LoggingEvent对象
package com.logback.db; public class LoggingEvent { private Long eventId; private int timestmp; private String formattedMessage; private String loggerName; private String levelString; private String threadName; private int referenceFlag; private String arg0; private String arg1; private String arg2; private String arg3; private String callerFilename; private String callerClass; private String callerMethod; private String callerLine; public Long getEventId() { return eventId; } public void setEventId(Long eventId) { this.eventId = eventId; } public int getTimestmp() { return timestmp; } public void setTimestmp(int timestmp) { this.timestmp = timestmp; } public String getFormattedMessage() { return formattedMessage; } public void setFormattedMessage(String formattedMessage) { this.formattedMessage = formattedMessage; } public String getLoggerName() { return loggerName; } public void setLoggerName(String loggerName) { this.loggerName = loggerName; } public String getLevelString() { return levelString; } public void setLevelString(String levelString) { this.levelString = levelString; } public String getThreadName() { return threadName; } public void setThreadName(String threadName) { this.threadName = threadName; } public int getReferenceFlag() { return referenceFlag; } public void setReferenceFlag(int referenceFlag) { this.referenceFlag = referenceFlag; } public String getArg0() { return arg0; } public void setArg0(String arg0) { this.arg0 = arg0; } public String getArg1() { return arg1; } public void setArg1(String arg1) { this.arg1 = arg1; } public String getArg2() { return arg2; } public void setArg2(String arg2) { this.arg2 = arg2; } public String getArg3() { return arg3; } public void setArg3(String arg3) { this.arg3 = arg3; } public String getCallerFilename() { return callerFilename; } public void setCallerFilename(String callerFilename) { this.callerFilename = callerFilename; } public String getCallerClass() { return callerClass; } public void setCallerClass(String callerClass) { this.callerClass = callerClass; } public String getCallerMethod() { return callerMethod; } public void setCallerMethod(String callerMethod) { this.callerMethod = callerMethod; } public String getCallerLine() { return callerLine; } public void setCallerLine(String callerLine) { this.callerLine = callerLine; } }
实现DBAppenderBase类
package com.logback.db; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.PreparedStatement; import ch.qos.logback.core.db.DBAppenderBase; public class InsertDbAppend extends DBAppenderBase<LoggingEvent> { protected static final Method GET_GENERATED_KEYS_METHOD; static { Method getGeneratedKeysMethod; try { // the getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", (Class[]) null); } catch (Exception ex) { getGeneratedKeysMethod = null; } GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod; } @Override protected Method getGeneratedKeysMethod() { // TODO Auto-generated method stub return GET_GENERATED_KEYS_METHOD; } @Override protected String getInsertSQL() { return "insert into logging_event(TIMESTMP,\r\n" + " FORMATTED_MESSAGE,\r\n" + " LOGGER_NAME,\r\n" + " LEVEL_STRING,\r\n" + " CALLER_FILENAME,\r\n" + " CALLER_CLASS,\r\n" + " CALLER_METHOD,\r\n" + " CALLER_LINE) values(?,?,?,?,?,?,?,?)"; } @Override protected void subAppend(LoggingEvent eventObject, Connection connection, PreparedStatement statement) throws Throwable { try { statement.setInt(1,eventObject.getTimestmp()); statement.setString(2,eventObject.getLoggerName()); statement.setString(3,eventObject.getLevelString()); statement.setString(4,eventObject.getCallerFilename()); statement.setString(5,eventObject.getCallerClass()); statement.setString(6,eventObject.getCallerMethod()); statement.setString(7,eventObject.getCallerLine()); statement.setInt(8,eventObject.getReferenceFlag()); statement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { statement.close(); } } @Override protected void secondarySubAppend(LoggingEvent eventObject, Connection connection, long eventId) throws Throwable { // 略 } }
main方法
package com.logback.db; import ch.qos.logback.core.db.DriverManagerConnectionSource; public class DbMain { public static void main(String[] args) { //1、创建connectionDatasource对象 DriverManagerConnectionSource driverManagerConnectionSource=new DriverManagerConnectionSource(); driverManagerConnectionSource.setPassword("dcp"); driverManagerConnectionSource.setUser("dcp"); driverManagerConnectionSource.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:orcl"); driverManagerConnectionSource.setDriverClass("oracle.jdbc.OracleDriver"); driverManagerConnectionSource.start(); //2、创建DBAppenderBase实现类InsertDbAppend InsertDbAppend insertDbAppend=new InsertDbAppend(); insertDbAppend.setConnectionSource(driverManagerConnectionSource); insertDbAppend.start(); LoggingEvent loggingEvent=new LoggingEvent(); loggingEvent.setCallerClass("callerClass"); loggingEvent.setCallerFilename("callerFilename"); loggingEvent.setCallerLine("callerLine"); loggingEvent.setCallerMethod("callerMethod"); loggingEvent.setFormattedMessage("formattedMessage"); loggingEvent.setLevelString("levelString"); loggingEvent.setLoggerName("loggerName"); loggingEvent.setReferenceFlag(3); loggingEvent.setTimestmp(4); //3、调用核心方法 insertDbAppend.append(loggingEvent); } }
浙公网安备 33010602011771号