代码之家  ›  专栏  ›  技术社区  ›  Chris Knight

如何保持SysUT和SysRR流的混合?

  •  3
  • Chris Knight  · 技术社区  · 15 年前

    在我的代码库中有(非常简单的)以下内容:

    public static void main (String[] args) {
       System.out.println("Starting application");
       try {
          System.out.println("About to validate");
          validate(args);
       catch (Exception e) {
          e.printStackTrace();
       }
    }
    
    public static void validate(String[] args) {
       System.out.println("Your first arg is " + args[0]);
       if (someProblemWith(args)) {
          System.out.println("Your args are wrong.  It should be: ...");
          throw new BadArgsException(e);
       }
    }
    

    效果很好。注意,上面的示例代码是精心设计的,只是为了在异常和堆栈跟踪打印之前显示多个日志语句。这通常意味着我的最后一条日志记录语句在堆栈跟踪输出的中间丢失。有没有一种优雅的方式问 e.printStackTrace() 语句等待System.out完成其工作?我实际上是在寻找stacktrace,它是发生错误时最后一个打印出来的东西。下面是我的程序的输出示例:

     java.lang.Throwable
     ....
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     Your args are wrong.  It should be: ...
     at java.lang.reflect.Method.invoke(Method.java:597)
     at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   khachik    15 年前

    呼叫 e.printStackTrace(System.out); . 或者,如果只需要调试,可以将进程的输出和错误从命令行中分离出来: .... 1>output.log 2>error.log

        2
  •  8
  •   Nico Huysamen    15 年前

    您看到堆栈跟踪在 System.out.println() 陈述,是因为 System.out 被缓冲,而 System.err (由堆栈跟踪使用)是无缓冲的。

    如果你想让文本按事情发生的确切顺序显示,你需要“解除缓冲” 系统输出 . 最简单的方法就是 系统错误 在那里而不是 系统输出 .

    否则,打电话 System.out.flush() 在你的堆栈痕迹在 catch 条款。

    选项2:使用 Logger 上课。

    选项3:实现自己的“缓冲区”。换句话说,首先将所有内容写入自己的缓冲区,包括堆栈跟踪(使用 .toString() 或者你想怎么做)然后 抓住 刷新你自己的缓冲区。(这有点多余,因为你可以直接刷新 系统输出 无论如何)。

    -==-

    从评论

    当然。这个 记录器 类可用于创建更加健壮和详细的日志记录体验。这通常是在应用程序中所做的。一个例子 记录器 类是从 记录器 类(它是单例的),将要使用的类作为参数。然后使用 .log() 方法。关于 记录器 类是可以在其上设置级别(例如 DEBUG , WARN …)然后你就可以过滤/显示你想要的。然后,“日志”消息以统一的方式显示在控制台中,通常采用以下格式:

    2010-11-23 14:45:32,032 DEBUG [MyClass] Your message

    以上格式来自 log4j ,但您可以使用标准Java 记录器 . 输出应该是相似的,也许少一点。但我相信可以配置。