如何将java日志控制台输出从std err更改为std out?

Obe*_*ane 31 java logging

我使用的标准ConsoleHandler,从java.util.logging和由默认控制台输出被引导到错误流(即System.err).

如何将控制台输出更改为输出流(即System.out)?

小智 14

我到了

 SimpleFormatter fmt = new SimpleFormatter();
 StreamHandler sh = new StreamHandler(System.out, fmt);
 logger.addHandler(sh);
Run Code Online (Sandbox Code Playgroud)


Obe*_*ane 9

我想出了一个方法.首先删除默认控制台处理程序:

setUseParentHandlers(假);

然后继承ConsoleHandler并在构造函数中:

setOutputStream(System.out的);

  • 你最好用自己实现的`OutputStream`包装`System.out`,以避免在下一次调用`setOutputStream(...)`或`LogManager.reset()`时关闭它. (3认同)

小智 9

Handler consoleHandler = new Handler(){
         @Override
            public void publish(LogRecord record)
            {
                if (getFormatter() == null)
                {
                    setFormatter(new SimpleFormatter());
                }

                try {
                    String message = getFormatter().format(record);
                    if (record.getLevel().intValue() >= Level.WARNING.intValue())
                    {
                        System.err.write(message.getBytes());                       
                    }
                    else
                    {
                        System.out.write(message.getBytes());
                    }
                } catch (Exception exception) {
                    reportError(null, exception, ErrorManager.FORMAT_FAILURE);
                }

            }

            @Override
            public void close() throws SecurityException {}
            @Override
            public void flush(){}
        };
Run Code Online (Sandbox Code Playgroud)

  • 但是,在现代......有没有办法在不实现自定义处理程序的情况下执行此操作? (6认同)

vol*_*ley 9

嗯,我只是踩了几下脚,试图完成这个壮举.在谷歌搜索之前,我设法让人想到以下黑客.丑陋,但它似乎完成了工作.

public class StdoutConsoleHandler extends ConsoleHandler {
  protected void setOutputStream(OutputStream out) throws SecurityException {
    super.setOutputStream(System.out); // kitten killed here :-(
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:从构造函数调用setOutputStream()很有吸引力,但它确实(正如Jon Skeet已经指出的那样)关闭了System.err.疯狂的技能!


oca*_*sen 5

我有一个类似的问题。我想将INFO及以下版本登录到System.out,并将WARNING及以上版本登录到System.err。这是我实现的解决方案:

public class DualConsoleHandler extends StreamHandler {

    private final ConsoleHandler stderrHandler = new ConsoleHandler();

    public DualConsoleHandler() {
        super(System.out, new SimpleFormatter());
    }

    @Override
    public void publish(LogRecord record) {
        if (record.getLevel().intValue() <= Level.INFO.intValue()) {
            super.publish(record);
            super.flush();
        } else {
            stderrHandler.publish(record);
            stderrHandler.flush();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以通过剔除对的硬编码引用来使其更加灵活Level.INFO。但这对于我获得一些基本的双流日志记录很有效。(顺便说一句,关于不对ConsoleHandler进行子类化以避免关闭的提示System.err非常有用。)


Har*_*hna 5

步骤 1:将父处理程序设置为 false。

log.setUseParentHandlers(false);
Run Code Online (Sandbox Code Playgroud)

第 2 步:添加写入 System.out 的处理程序

log.addHandler(new StreamHandler(System.out, new SimpleFormatter()));
Run Code Online (Sandbox Code Playgroud)

就是这样..

import java.io.IOException;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;

public class App {

     static final Logger log = Logger.getLogger("com.sample.app.App");

     static void processData() {
          log.info("Started Processing Data");
          log.info("Finished processing data");
     }

     public static void main(String args[]) throws IOException {
          log.setUseParentHandlers(false);

          log.addHandler(new StreamHandler(System.out, new SimpleFormatter()));

          processData();
     }
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 4

查看ConsoleHandler的文档和源代码- 我相信您可以轻松编写一个仅使用 System.err 而不是 System.out 的版本。(老实说,ConsoleHandler 不允许进行配置,这很遗憾。)

然后,只需配置日志系统以正常方式使用新的 StdoutHandler (或任何您所说的)即可。

  • 是的,但我怀疑您想要子类化 StreamHandler 以避免尝试关闭 System.err。 (3认同)