即使在设置System.setErr()之后,也无法使用自定义PrintStream打印错误



基本上,我想让控制台做两件事:

  1. 我希望控制台将错误代码和一般信息消息(错误为红色,其他为绿色(着色
  2. 我想将所有控制台消息保存到日志文件中

所以,我创建了一个打印流,看起来像这样:

public static class GeneralStream extends PrintStream {
public GeneralStream(OutputStream out) {
super(out);
}
@Override
public void println(String string) {
String time = DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now());
String output = "["+time+"] ["+type.n()+"] "+string;
Logs.logToFile(output);

String coloredOutput = ANSI_RESET+ANSI_WHITE+"["+ANSI_CYAN+time+ANSI_WHITE+"] "+
ANSI_WHITE+"["+ANSI_RESET+type.c()+type.n()+ANSI_WHITE+"] "+type.c()+string+ANSI_RESET;
super.println(coloredOutput);
}
}

太好了。然后,我在程序开始时将此打印流设置为默认的PrintStream,使用:

// Set console output settings
System.setOut(new Console.GeneralStream(System.out));
System.setErr(new Console.GeneraStream(System.err));

太棒了。最后,在完成System.out.println("Hello World"(之后,我得到了我期望的结果。我的信息是彩色的。它们被记录到一个文件中。太棒了事实上,即使我执行System.err.println("错误!"(,我仍然会得到预期的结果然而;"自动";异常不会通过我设置的System.err打印

这里有一个例子:

// Set console output settings
System.setOut(new Console.GeneralStream(System.out));
System.setErr(new Console.ErrorStream(System.err));
System.out.println("Hello world!");
System.err.println("Printing an error!");
// Real exception (NPE)
Integer nullInteger = null;
System.out.println(nullInteger.toString()); // won't print and will produce a NullPointException

结果如下:正如您所看到的,我的System.out和System.err打印得很好,但一旦出现真正的异常,它就会定期打印。

所以我的问题是,我如何为这样的错误设置一个自定义的PrintStream,以便将它们记录到一个文件中(最好遵循我的自定义消息格式(。

如果深入研究Throwable类如何打印堆栈跟踪,您会发现它使用了println(Object)方法,因此您需要将此方法添加到自定义ErrorStream类:

@Override
public void println(Object object) {
println(String.valueOf(object));
}

即便如此,您也可能想要更改";未捕获异常处理程序";以更改其记录异常的方式。默认处理程序似乎首先调用System.err.print以输出Exception in thread "{ThreadName}",然后再调用Throwable.printStackTrace,因此您最终会在消息中间使用时间戳和其他内容。例如:

Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("Uncaught exception in thread " + thread.getName());
throwable.printStackTrace(System.err);
});

最新更新