如何在log4j中创build我自己的Appender?

我在log4j是新的。 任何人都可以解释如何创build我自己的Appender? 即如何实现类和接口以及如何覆盖它?

你应该扩展AppenderSkeleton类,(引用javadoc)“提供了通用function的代码,例如支持阈值过滤和支持通用filter。

如果你读了AppenderSkeleton的代码,你会发现它几乎处理了所有的事情,只留给你:

  1. 保护无效附加(LoggingEvent事件)
  2. public void close()
  3. public boolean requireLayout()

核心方法是追加。 请记住,您不需要在其中实现过滤逻辑,因为它已经在doAppend中实现,而后者又调用append。 在这里,我做了一个(非常无用的)类,它将日志条目存储在一个ArrayList中,就像一个演示。

public /*static*/ class MyAppender extends AppenderSkeleton { ArrayList<LoggingEvent> eventsList = new ArrayList(); @Override protected void append(LoggingEvent event) { eventsList.add(event); } public void close() { } public boolean requiresLayout() { return false; } } 

好的,我们来testing一下:

 public static void main (String [] args) { Logger l = Logger.getLogger("test"); MyAppender app = new MyAppender(); l.addAppender(app); l.warn("first"); l.warn("second"); l.warn("third"); l.trace("fourth shouldn't be printed"); for (LoggingEvent le: app.eventsList) { System.out.println("***" + le.getMessage()); } } 

你应该有“第一”,“第二”,“第三”印; 由于根logging器的日志级别为debug,而事件级别为trace,因此不应打印第四条消息。 这certificate了AbstractSkeleton为我们正确实现了“层次pipe理”。 所以这绝对是一种好的方式…现在的问题是:为什么你需要一个自定义的appender,而有许多内置的日志到几乎任何目的地? (顺便说一句,从log4j开始: http : //logging.apache.org/log4j/1.2/manual.html )

如果你想做一些操纵或决定,你可以这样做:

 @Override protected void append(LoggingEvent event) { String message = null; if(event.locationInformationExists()){ StringBuilder formatedMessage = new StringBuilder(); formatedMessage.append(event.getLocationInformation().getClassName()); formatedMessage.append("."); formatedMessage.append(event.getLocationInformation().getMethodName()); formatedMessage.append(":"); formatedMessage.append(event.getLocationInformation().getLineNumber()); formatedMessage.append(" - "); formatedMessage.append(event.getMessage().toString()); message = formatedMessage.toString(); }else{ message = event.getMessage().toString(); } switch(event.getLevel().toInt()){ case Level.INFO_INT: //your decision break; case Level.DEBUG_INT: //your decision break; case Level.ERROR_INT: //your decision break; case Level.WARN_INT: //your decision break; case Level.TRACE_INT: //your decision break; default: //your decision break; } } 

要创build一个自己的Appender,你只需要实现Appender接口并覆盖它。 也研究这个链接的开始日志

我想花费@AgostinoX答案来支持pro文件configuration和启动和停止日志logging捕获的能力:

 public class StringBufferAppender extends org.apache.log4j.AppenderSkeleton { StringBuffer logs = new StringBuffer(); AtomicBoolean captureMode = new AtomicBoolean(false); public void close() { // TODO Auto-generated method stub } public boolean requiresLayout() { // TODO Auto-generated method stub return false; } @Override protected void append(LoggingEvent event) { if(captureMode.get()) logs.append(event.getMessage()); } public void start() { //System.out.println("[StringBufferAppender|start] - Start capturing logs"); StringBuffer logs = new StringBuffer(); captureMode.set(true); } public StringBuffer stop() { //System.out.println("[StringBufferAppender|start] - Stop capturing logs"); captureMode.set(false); StringBuffer data = new StringBuffer(logs); logs = null; return data; } } 

现在你所要做的就是在log4j.property文件中定义

 log4j.rootLogger=...., myAppender # here you adding your appendr name log4j.appender.myAppender=com.roi.log.StringBufferAppender # pointing it to the implementation 

比以往任何时候你想在runtume中启用它:

 Logger logger = Logger.getRootLogger(); StringBufferAppender appender = (StringBufferAppender)logger.getAppender("myAppender"); appender.start(); 

而想要阻止它:

 StringBuffer sb = appender.stop();