最近在做项目时,碰到一个很头疼的问题,需要扩展log4J的入口。在入口处,传递一些系统参数,给log4J处理。例如日志信息入库操作。 查看log4j的源代码后发现,在log4J中,是用LoggingEvent类做为实体,存储日志信息,如果能够扩展LoggingEvent,增加需要的参数信息,就可以在JDBCAppender中获取系统参数信息了。 Log4J的入口类Logger提供了 public static Logger getLogger(String name, LoggerFactory factory) { return LogManager.getLogger(name, factory); } 这样一个方法,通过这个方法中的LoggerFactory参数,可以返回一个Logger实例。这样的话,可以自己写一个LoggerFactory,自定义的log4J入口。 之后定义一个自己的Logger类,并覆写父类中的 protected void forcedLog(String fqcn, Priority level, Object message, Throwable t) { callAppenders(new LoggingEvent(fqcn, this, level, message, t)); } 方法,此方法中的LoggingEvent替换为自己定一个LoggingEvent子类。即可把相应的参数信息,传递到Appender进行处理即可了! 自定义的类如下: 1、生成Logger子类的工厂类
public class SinologFactory implements LoggerFactory {
public Logger makeNewLoggerInstance(String name) {
return (Logger)new SinoLogger(name);
}
}
2、自定义LoggingEvent,增加一个sinoSysname属性
public class SinoLoggingEvent extends LoggingEvent {
public SinoLoggingEvent(String fqnOfCategoryClass, Category logger,
Priority level, Object message, Throwable throwable,String sinoSysname) {
super(fqnOfCategoryClass, logger, level, message, throwable);
// TODO Auto-generated constructor stub
this.sinoSysname=sinoSysname;
}
public SinoLoggingEvent(String fqnOfCategoryClass, Category logger,
long timeStamp, Priority level, Object message, Throwable throwable,String sinoSysname) {
super(fqnOfCategoryClass, logger, timeStamp, level, message, throwable);
// TODO Auto-generated constructor stub
this.sinoSysname=sinoSysname;
}
public SinoLoggingEvent(String fqnOfCategoryClass, Category logger,
long timeStamp, Level level, Object message, String threadName,
ThrowableInformation throwable, String ndc, LocationInfo info,
Map properties,String sinoSysname) {
super(fqnOfCategoryClass, logger, timeStamp, level, message, threadName,
throwable, ndc, info, properties);
// TODO Auto-generated constructor stub
this.sinoSysname=sinoSysname;
}
protected String sinoSysname="";
public String getSinoSysname(){
return sinoSysname;
}
}
3、自定义Logger
public class SinoLogger extends Logger {
static int i=0;
protected String sinoSysname="";
protected SinoLogger(String name) {
super(name);
}
private static final String FQCN = SinoLogger.class.getName();
public
static
Logger getLogger(String name, LoggerFactory factory) {
return LogManager.getLogger(name, factory);
}
protected
void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
callAppenders(new SinoLoggingEvent(fqcn, this, level, message, t,sinoSysname));
}
protected void setSinoSysname(String sinoSysname){
this.sinoSysname=sinoSysname;
}
}
4、自定义JDBCAppender
public class SinoJDBCAppender extends JDBCAppender {
protected String getLogStatement(LoggingEvent event) {
String aaa="";
if (SinoLoggingEvent.class.isInstance(event)) {
SinoLoggingEvent dd = (SinoLoggingEvent) event;
}
return aaa;
}
}