如何在log4j中创建自己的Appender?

时间:2011-05-20 13:10:42

标签: java log4j appender

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

4 个答案:

答案 0 :(得分:71)

你应该扩展AppenderSkeleton类,(引用javadoc)“提供常用功能的代码,例如支持阈值过滤和对一般过滤器的支持。”

如果您阅读了AppenderSkeleton的代码,您会发现它几乎可以处理所有代码,只留给您:

  1. protected void append(LoggingEvent event)
  2. public void close()
  3. public boolean requiresLayout()
  4. 核心方法是追加。请记住,您不需要在其中实现过滤逻辑,因为它已经在doAppend中实现,而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;
        }
    
    }
    

    好的,我们来测试一下:

    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());
        }
    } 
    

    你应该打印“第一”,“第二”,“第三”;不应打印第四条消息,因为根记录器的日志级别是调试,而事件级别是跟踪。这证明AbstractSkeleton正确地为我们实现了“级别管理”。所以这肯定是要走的路......现在的问题是:为什么你需要一个自定义的appender,而有许多内置的日志到几乎任何目的地? (顺便说一下从log4j开始的好地方:http://logging.apache.org/log4j/1.2/manual.html

答案 1 :(得分:6)

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

@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;
        }
}

答案 2 :(得分:2)

要创建自己的Appender,您只需实现Appender接口并覆盖它。 并研究此链接开始log

答案 3 :(得分:2)

我想花费@AgostinoX答案来支持专业文件配置以及启动和停止日志记录捕获的能力:

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();