自定义日志记录以在运行时收集消息

发布于 2024-07-24 06:54:58 字数 860 浏览 1 评论 0原文

有没有办法在运行时创建一个 log4j Logger 将日志消息收集到缓冲区中?

我目前有一个记录许多事件的类。 对于需要监视记录事件的远程应用程序,我想只交换一个记录到缓冲区的记录器,然后检索缓冲区,而不是重构该类。 例如,给出类似的内容:

Class Foo{
   Logger log = ....;

   public void doSomething(){ 
      log.debug(...
      .. actual code
      log.debug(...
   }
}

//我想从一些外部代码中做什么:

String showFooLog(){
   Foo f = new Foo();
   f.log=new Logger(... 
   f.doSomething();
   return f.log.contents();
}

这可能吗?

编辑:找到了一个更短的解决方案,从 Jared 的帖子中指出(尽管它仍然不是线程安全的)。 谢谢您的帮助。

 Logger l = Logger.getLogger( ...  );
 StringWriter writer = new StringWriter();
 WriterAppender appender = new WriterAppender( new HTMLLayout(), writer );
 l.addAppender( appender );
    ... run code here
  writer.flush();
 l.removeAppender( appender );
 return writer.toString()

Is there a way to create a log4j Logger at runtime that will gather logging messages into a buffer?

I currently have a class that logs a number of events. For a remote application that needs to monitor the logged events, I'd like to just swap in a logger that logs to a buffer and then retrieve the buffer, rather than refactor the class. E.g. given something like:

Class Foo{
   Logger log = ....;

   public void doSomething(){ 
      log.debug(...
      .. actual code
      log.debug(...
   }
}

//what I'd like to do from some outside code:

String showFooLog(){
   Foo f = new Foo();
   f.log=new Logger(... 
   f.doSomething();
   return f.log.contents();
}

Is this possible?

Edit: Found a shorter solution, pointed to from Jared's posting( although it's still not threadsafe). Thanks for the help.

 Logger l = Logger.getLogger( ...  );
 StringWriter writer = new StringWriter();
 WriterAppender appender = new WriterAppender( new HTMLLayout(), writer );
 l.addAppender( appender );
    ... run code here
  writer.flush();
 l.removeAppender( appender );
 return writer.toString()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄居人 2024-07-31 06:54:58

这绝对是可能的 - 尽管您可能需要创建自己的 Appender。 不过,这确实很容易做到。 这是一个示例的粗略版本(需要考虑线程安全...这不是线程安全的...并且我不确定我喜欢静态...但这应该足以推动您朝正确的方向):

public class BufferAppender extends org.apache.log4j.AppenderSkeleton {
    private static Map<String, StringBuffer> buffers = new HashMap<String, StringBuffer>();

    @Override
    protected void append(LoggingEvent evt) {
        String toAppend = this.layout.format(evt);
        StringBuffer sb = getBuffer(evt.getLoggerName());
        buffer.append(toAppend);
    }

    public static String getBufferContents(String loggerName) {
            StringBuffer sb = buffers.get(sb);
            if(sb == null) {
               return null;
            } else {
               return sb.toString();
            }
    }

    public static void clearBuffer(String loggerName) {
            createBuffer(loggerName);
    }

    private static StringBuffer getBuffer(String loggerName) {
       StringBuffer sb = buffers.get(loggerName);
       if(sb == null) {
            sb = createBuffer(loggerName);
       }
       return sb;
    }

    private static StringBuffer createBuffer(String loggerName) {
       StringBuffer sb = new StringBuffer();
       buffers.put(loggerName, sb);
       return sb;
    }
}

It's absolutely possible - although you're probably going to need to create your own Appender. This is really easy to do, though. Here's a rough-out of an example (need to think out thread-safety...this isn't threadsafe....and I'm not sure I like the statics...but this should be good enough to push you in the right direction):

public class BufferAppender extends org.apache.log4j.AppenderSkeleton {
    private static Map<String, StringBuffer> buffers = new HashMap<String, StringBuffer>();

    @Override
    protected void append(LoggingEvent evt) {
        String toAppend = this.layout.format(evt);
        StringBuffer sb = getBuffer(evt.getLoggerName());
        buffer.append(toAppend);
    }

    public static String getBufferContents(String loggerName) {
            StringBuffer sb = buffers.get(sb);
            if(sb == null) {
               return null;
            } else {
               return sb.toString();
            }
    }

    public static void clearBuffer(String loggerName) {
            createBuffer(loggerName);
    }

    private static StringBuffer getBuffer(String loggerName) {
       StringBuffer sb = buffers.get(loggerName);
       if(sb == null) {
            sb = createBuffer(loggerName);
       }
       return sb;
    }

    private static StringBuffer createBuffer(String loggerName) {
       StringBuffer sb = new StringBuffer();
       buffers.put(loggerName, sb);
       return sb;
    }
}
思念满溢 2024-07-31 06:54:58

您可以继承 org.apache.log4j.WriterAppender 并为其提供 ByteArrayOutputStream 来存储任何消息。 请参阅 WriterAppender 的其他子类以获取灵感。 然后,您可以向记录器提供该对象的实例,以便通过 addAppender 进行追加。

You could subclass org.apache.log4j.WriterAppender and provide it a ByteArrayOutputStream to store any messages. See the other subclasses of WriterAppender for inspriation. Then you can provide an instance of that object to your logger for appending via addAppender.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文