赞
踩
问题:logback的DBAppender只能写入4个参数,而且参数名字固定,保存数据的表名固定,因此解决以上问题,需要重写DBAppender;
而且还自己从数据库定义各种类型的日志级别
方案:除logback的三张表外,其它再增加2张表,分别为分类表和需要定义的package或class,logback的表名可以进行修改
1、修改表名和列名:logback的表名可以修改成你需要的表名,只需要在AppDBNameResolver里面修改getTableName方法的返回值;
列名也是一样的,只需要修改getColumnName的返回值;
如下:
public class MyDBNameResolver implements DBNameResolver {
private String tableNamePrefix = “s_” ;
private String tableNameSuffix = “” ;
private String columnNamePrefix = “” ;
private String columnNameSuffix = “” ;
//修改表名
public <N extends Enum<?>> String getTableName(N tableName) {
System.out.println( " getTableName " + tableName );
return tableNamePrefix + tableName .name().toLowerCase() + tableNameSuffix;
}
//修改列名
public <N extends Enum<?>> String getColumnName(N columnName) {
System.out.println( " getColumnName " + columnName + " " + columnName.name().toLowerCase() );
if(“arg0”.equals( columnName.name().toLowerCase())){
return “log_type”;
}else
return columnNamePrefix + columnName .name().toLowerCase() + columnNameSuffix;
}
}
logback.xml中增加如下:
< dbNameResolver class=“com.javacodegeeks.examples.logbackmdcexample.MyDBNameResolver”/>增加到< appender>中
2、增加参数
需要重写DBAppender,主要在以下地方:
static final int TIMESTMP_INDEX = 1;
static final int FORMATTED_MESSAGE_INDEX = 2;
static final int LOGGER_NAME_INDEX = 3;
static final int LEVEL_STRING_INDEX = 4;
static final int THREAD_NAME_INDEX = 5;
static final int REFERENCE_FLAG_INDEX = 6;
static final int ARG0_INDEX = 7;
static final int ARG1_INDEX = 8;
static final int ARG2_INDEX = 9;
static final int ARG3_INDEX = 10;
static final int ARG4_INDEX = 11;//增加的一个参数
bindLoggingEventArgumentsWithPreparedStatement方法中修改:对应的数字4改成你增加到的数字
void bindLoggingEventArgumentsWithPreparedStatement (PreparedStatement stmt ,
Object[] argArray) throws SQLException {
int arrayLen = argArray != null ? argArray .length : 0;
for(int i = 0; i < arrayLen && i < 5; i++) {
stmt.setString( ARG0_INDEX+i , asStringTruncatedTo254(argArray[i]));
}
if(arrayLen < 5) {
for(int i = arrayLen; i < 5; i++) {
stmt.setString( ARG0_INDEX+i , null);
}
}
}
如果还增加了其它字段到数据库且,可以修改bindCallerDataWithPreparedStatement方法
void bindCallerDataWithPreparedStatement(PreparedStatement stmt,
StackTraceElement[] callerDataArray) throws SQLException {
StackTraceElement caller = extractFirstCaller( callerDataArray);
stmt.setString( CALLER_FILENAME_INDEX, caller .getFileName());
stmt.setString( CALLER_CLASS_INDEX, caller .getClassName());
stmt.setString( CALLER_METHOD_INDEX, caller .getMethodName());
stmt.setString(CALLER_LINE_INDEX, Integer.toString(caller .getLineNumber()));
//增加的字段
stmt.setString(15, “logger add column”);
}
最后修改SQLBuilder,增加你增加的字段
static String buildInsertSQL(DBNameResolver dbNameResolver ) {
StringBuilder sqlBuilder = new StringBuilder(“INSERT INTO " );
sqlBuilder.append(dbNameResolver .getTableName(TableName.LOGGING_EVENT)).append( " (”);
sqlBuilder.append( dbNameResolver.getColumnName(ColumnName.TIMESTMP)).append(", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.FORMATTED_MESSAGE)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.LOGGER_NAME)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.LEVEL_STRING)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.THREAD_NAME)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.REFERENCE_FLAG)).append( ", “);
sqlBuilder.append( dbNameResolver.getColumnName(ColumnName.ARG0)).append(”, “);
sqlBuilder.append( dbNameResolver.getColumnName(ColumnName.ARG1)).append(”, “);
sqlBuilder.append( dbNameResolver.getColumnName(ColumnName.ARG2)).append(”, “);
sqlBuilder.append( dbNameResolver.getColumnName(ColumnName.ARG3)).append(”, ");
sqlBuilder.append( dbNameResolver .getColumnName(ColumnName. ARG4)).append( ", ");//增加的参数
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.CALLER_FILENAME)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.CALLER_CLASS)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.CALLER_METHOD)).append( ", ");
sqlBuilder.append(dbNameResolver .getColumnName(ColumnName.CALLER_LINE)).append( ", ");
sqlBuilder .append(“logger_type”).append( ") ");//增加自己的列
sqlBuilder.append( “VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?, ?, ?)” );//增加两个占位符
return sqlBuilder.toString();
}
logback.xml中修改如下:
< appender name =“db” class=“com.javacodegeeks.examples.logbackmdcexample.MyDBAppender”>,改成自己的DBAppender
logback基础详解:
log日志级别:TRACE < DEBUG < INFO < WARN < ERROR
Logback默认配置的步骤
(1). 尝试在 classpath 下查找文件 logback-test.xml;
(2). 如果文件不存在,则查找文件 logback.xml;
(3). 如果两个文件都不存在,logback 用 Bas icConfigurator 自动对自己进行配置,这会导致记录输出到控制台。
Logback.xml 文件
[html] view plaincopy
<?xml version="1.0" encoding="UTF-8"?> UTF-8 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 ${LOG_HOME}/myApp.log.%d{yyyy-MM-dd}.log 30 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 10MB com.mysql.jdbc.Driver jdbc:mysql://127.0.0.1:3306/databaseName root root -->一:根节点 包含的属性:
scan:
当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:
设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:
当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
例如:
2.1设置上下文名称:
每个logger都关联到logger上下文,默认上下文名称为default。但可以使用设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
name: 变量的名称
value: 的值时变量定义的值。
通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
例如使用定义上下文名称,然后在设置logger上下文时使用。
${APP_Name} 2.3获取时间戳字符串: 两个属性:key: 标识此 的名字;
datePattern: 设置将当前时间(解析配置文件的时间)转换为字符串的模式,遵循java.txt.SimpleDateFormat的格式。
例如将解析配置文件的时间作为上下文名称:
name:
用来指定受此loger约束的某一个包或者具体的某一个类。
level:
用来设置打印级别,大小写无关:TRACE, DEBUG, INFO,WARN,ERROR,ALL和OFF,还有一个特俗值INHERITED或者同义词NULL`,代表强制执行上级的级别。
如果未设置此属性,那么当前loger将会继承上级的级别。
addtivity:
是否向上级loger传递打印信息。默认是true。
level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。
默认是DEBUG。
和可以包含零个或多个元素,标识这个appender将会添加到这个loger。
例如:
LogbackDemo.java类
package logback;
import org.slf4j.Logger; import org.slf4j.LoggerFactory;
public class LogbackDemo {
private static Logger log = LoggerFactory.getLogger(LogbackDemo.class);
public static void main(String[] args) {
log.trace("======trace");
log.debug("======debug");
log.info("======info");
log.warn("======warn");
log.error("======error");
}
}
三、logback.xml配置文件
第1种:只配置root
当执行logback.LogbackDemo类的main方法时,root将级别为“INFO”及大于“INFO”的日志信息交给已经配置好的名为“STDOUT”的appender处理,“STDOUT”appender将信息打印到控制台;
打印结果如下:
13:30:38.484 [main] INFO logback.LogbackDemo - ======info
13:30:38.500 [main] WARN logback.LogbackDemo - ======warn
13:30:38.500 [main] ERROR logback.LogbackDemo - ======error
第2种:带有loger的配置,不指定级别,不指定appender:
当执行logback.LogbackDemo类的main方法时,因为LogbackDemo 在包logback中,所以首先执行,将级别为“DEBUG”及大于“DEBUG”的日志信息传递给root,本身并不打印;
root接到下级传递的信息,交给已经配置好的名为“STDOUT”的appender处理,“STDOUT”appender将信息打印到控制台;
打印结果如下:
13:19:15.406 [main] DEBUG logback.LogbackDemo - ======debug
13:19:15.406 [main] INFO logback.LogbackDemo - ======info
13:19:15.406 [main] WARN logback.LogbackDemo - ======warn
13:19:15.406 [main] ERROR logback.LogbackDemo - ======error
第3种:带有多个loger的配置,指定级别,指定appender:
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
将控制logback包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级的日志级别“DEBUG”;
没有设置addtivity,默认为true,将此loger的打印信息向上级传递;
没有设置appender,此loger本身不打印任何信息。
控制logback.LogbackDemo类的日志打印,打印级别为“INFO”;
additivity属性为false,表示此loger的打印信息不再向上级传递,
指定了名字为“STDOUT”的appender。
将root的打印级别设置为“ERROR”,指定了名字为“STDOUT”的appender。
当执行logback.LogbackDemo类的main方法时,先执行,将级别为“INFO”及大于“INFO”的日志信息交给此loger指定的名为“STDOUT”的appender处理,在控制台中打出日志,不再向次loger的上级 传递打印信息;
未接到任何打印信息,当然也不会给它的上级root传递任何打印信息;
打印结果如下:
14:09:01.531 [main] INFO logback.LogbackDemo - ======info
14:09:01.531 [main] INFO logback.LogbackDemo - ======info
14:09:01.531 [main] WARN logback.LogbackDemo - ======warn
14:09:01.531 [main] WARN logback.LogbackDemo - ======warn
14:09:01.531 [main] ERROR logback.LogbackDemo - ======error
14:09:01.531 [main] ERROR logback.LogbackDemo - ======error
作者:DannyDaiChn
来源:CSDN
原文:https://blog.csdn.net/qq352345425/article/details/46982683
版权声明:本文为博主原创文章,转载请附上博文链接!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。