6

是否可以拦截对 System.out.print* 和 System.err.print* (在 Java 中)的调用并为其添加时间戳?不用担心,我们使用通常的日志记录框架,但偶尔会有一些 sys.out 泄漏,如果知道它何时发生会很高兴,这样我们就可以将其绑定到正确的日志文件。

4

3 回答 3

10

你能行的。

查看文档

重新分配“标准”输出流。首先,如果有安全管理器,则使用 RuntimePermission("setIO") 权限调用其 checkPermission 方法,以查看是否可以重新分配“标准”输出流。

public class  CustomPrintStream extends PrinterStream{

 //override  print  methods here 
}

System.setOut(new CustomPrintStream());
于 2013-06-22T05:44:14.697 回答
2

这应该是可能的。

System.out 是一个printStream

您可以扩展流以将日期和时间附加到打印方法并使用System.setOut()适当地设置流。

作为事后的想法,如果您想确定打印语句的来源,您可以使用: Thread.currentThread().getStackTrace()[1].getClassName();

于 2013-06-22T05:44:42.853 回答
2

您可以使用Aspect Oriented Programming来实现这一点 - 特别是AspectJ工具。

这个想法是您定义在代码中的点匹配的切入点,然后编写在这些点执行的建议。然后,AspectJ 编译器将在这些点编入您的建议

因此,对于您的问题,您将首先定义一个切入点,每次您printPrintStream

pointcut callPrint(PrintStream ps, String s) : 
              call(* java.io.PrintStream.print*(..)) && target(ps) && args(s);

然后,您将编写建议来绕过此调用以替换参数(如果PrintStream是)System.out(您可以对System.err.

void around(PrintStream ps, String s) : callPrint(ps,s) {
  if(ps.equals(System.out)){
    String new_string = ...
    proceed(new_string);
  }
  else proceed(s);
}

然后,您需要将所有这些都放在一个方面并将其编织到您的代码中 - 网上有很多关于如何做到这一点的教程。

于 2013-06-22T07:23:52.647 回答