如何将sysout和syserr重定向到java中的自定义Logger?

时间:2013-10-02 17:25:36

标签: java logging

我有一个自定义Logger,我想将所有sysout和syserr从控制台重定向到该自定义记录器。所以我想以下列方式重定向sysout和syserr:

  • 通过扩展ByteArrayOutputStream
  • 然后设置System.setErr和System.setOut

    public class ServerLoggingPrintStream extends ByteArrayOutputStream  {
        public ServerLoggingPrintStream() {
            super();
        }
    
    public void write(byte[] originalBytes, int originalOffset, int originalLength) {
        synchronized(this) {
            String str = new String(originalBytes);
            if (str.length() == 0 || str.equals(System.getProperty("line.separator")) ) {
                        return;
            } 
    
            //using my custom logger named TRACE_LOGGER
            TRACE_LOGGER.log(LogLevel.INFO, this, "write", str);            
        }
      }
    }
    
    
    ServerLoggingPrintStream  serverLoggingPrintStreamStdOut_ = null;
    ServerLoggingPrintStream  serverLoggingPrintStreamStdErr_ = null;
    
    serverLoggingPrintStreamStdErr_ = new ServerLoggingPrintStream();
    System.setErr(new PrintStream(serverLoggingPrintStreamStdErr_));
    
    serverLoggingPrintStreamStdOut_ = new ServerLoggingPrintStream();
    System.setOut(new PrintStream(serverLoggingPrintStreamStdOut_));
    

你认为有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

要做到这一点,要比这更复杂。话虽如此,有些开源项目已经做到了,所以你可以从中借用一些代码。这方面有一个例子:

http://docs.jboss.org/jbossas/javadoc/4.0.2/org/jboss/logging/util/LoggerStream.java.html

答案 1 :(得分:0)

我会使用OutputStream重定向到您使用的日志记录框架。它很容易实现(我假设字符集是ISO,所以编码没有花哨的处理):

final class RedirectionOutputStream extends OutputStream {

    StringBuilder buffer = new StringBuilder();

    @Override
    public synchronized void write(final int b) throws IOException {
        final char c = (char) (b & 0xFF);
        buffer.append(c);
        if (c == '\n') {
             // send buffered data to logging framework (its a complete line now)
             // reset buffer
             buffer.setLength(0);
        }
    }
}

这就是它的要点,但您的日志框架的细节可能会有所不同。主要问题是记录器通常期望字符串记录,并且您从重定向流中获得原始的编码字节,因此您必须反转编码(在此示例中通过原始强制转换,技术上应该使用Reader完成)。 p>