最近在做项目时,碰到一个很头疼的问题,需要扩展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;
}
}