【问题标题】:How to log error in java exception handling.? [closed]如何在java异常处理中记录错误。? [关闭]
【发布时间】:2015-10-07 11:31:19
【问题描述】:

哪种方法更适合生产(根据良好的编程)以轻松调试错误。

LOG.error("Error message ",e);

或

LOG.error("Error message "+e);

或

LOG.error("Error message "+e.getMessage());

【问题讨论】:

  • 你至少知道它们的区别吗?
  • @Tom 为什么这基于意见而被搁置?第一种情况为日志框架提供了所有需要的信息,然后日志框架可以决定实际记录哪些信息。后面的方法只向日志框架提供消息,并且无法通过日志配置集中管理记录的内容。
  • 您想知道哪种方法最好,所以每个人都用他或她认为最好的方法来回答。因此它是基于意见的。
  • @Pawan 说明您正在使用的日志框架可能会有所帮助。

标签: java exception-handling


【解决方案1】:

你为什么不试试呢?您是唯一知道您在日志记录中需要哪些信息的人。根据抛出的异常,您可能需要堆栈跟踪。

看下面一个小例子来展示不同的输出

private void logTest() {
    try {
        Files.readAllBytes(Paths.get("foobar"));
    } catch (IOException e) {
        logger.error("Error message ", e);
        logger.error("Error message " + e);
        logger.error("Error message " + e.getMessage());
    }
}

logger.error("错误信息", e);

2015-10-07 13:42:11,239 [main] ERROR sub.optimal.Main  - Error message 
java.nio.file.NoSuchFileException: foobar
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
    at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
    at java.nio.file.Files.newByteChannel(Files.java:361)
    at java.nio.file.Files.newByteChannel(Files.java:407)
    at java.nio.file.Files.readAllBytes(Files.java:3152)
    at sub.optimal.Main.logTest(Main.java:43)
    at sub.optimal.Main.main(Main.java:53)

logger.error("错误信息" + e);

2015-10-07 13:42:11,243 [main] ERROR sub.optimal.Main  - Error message java.nio.file.NoSuchFileException: foobar

logger.error("错误信息" + e.getMessage());

2015-10-07 13:42:11,243 [main] ERROR sub.optimal.Main  - Error message foobar

【讨论】:

  • 谢谢@SubOptimal 我试过了,但我很困惑哪一个是生产和有效开发的好习惯。
  • 正如我所说,这取决于。如果您知道异常本身包含您需要了解的所有信息,例如java.nio.file.NoSuchFileException: foobar,那么您可能不想在堆栈跟踪中弄乱日志。如果您发现异常,但您不知道可能是什么原因,或者您可能需要哪些信息来发现源头,请尽可能多地记录(意味着包括堆栈跟踪)。
  • @SubOptimal 为什么不决定在 apender 的布局上登录什么?如果你使用 error(String, Throwable),你可以在布局中决定你是否希望日志中出现消息、异常消息和堆栈跟踪(通常即使不重新编译也可以更改)。如果您使用任何其他建议的形式,则无法配置记录器以打印堆栈跟踪。
  • @JiriTousek 取决于记录器实现,这可能是一个选项,并非所有实现都可能提供此功能(我不知道版本 2 之前的 log4j 中的此功能)。如果一个类中的不同异常处理程序应该记录不同级别的异常信息,则可能会出现问题。
【解决方案2】:

使用LOG.error("Error message ",e); - 这样您就不会丢失异常的堆栈跟踪(请注意,您还需要确保设置日志框架的输出布局,以便打印堆栈跟踪)。

堆栈跟踪是异常报告的重要组成部分,因为它们会告诉您有问题的代码是如何被调用的,因此可以帮助您了解错误发生时程序处于什么状态。

如果您出于某种原因只想记录消息而不是堆栈跟踪,我仍然建议使用上述表单,然后将日志框架配置为不打印堆栈跟踪(在 Log4j 中,这是通过配置附加器)。这样,如果您以后改变主意,只需更改配置即可将堆栈跟踪添加到日志中,而无需更改实际的日志记录代码。应该将哪些信息放入日志中的选择应该是 appender 配置的责任,而不是记录条目的代码。

【讨论】:

  • @Raedwald 不过,我想指出两件重要的事情:1)“显示给用户”和“打印到日志”是两个非常不同的事情。虽然用户需要清晰易懂的信息,但在日志中您需要尽可能多的细节。即使是链接问题的公认答案也这么说。 2) 即使是可能表示值得记录的错误的异常,而不仅仅是那些明显的错误。
【解决方案3】:

你也可以使用:

logger.log(Level.INFO, "an exception was thrown", e);

【讨论】:

    【解决方案4】:

    在 Java 中

    LOG.error("Error message ",e);
    
    LOG.error("Error message "+e);
    

    您正在传递将调用 to String 实现的异常对象

    LOG.error("Error message "+e.getMessage());
    

    这会给你getMessage的内容

    【讨论】:

    • 我同意 Sagar .. 但是在出现异常时有堆栈跟踪总是好的。我建议 LOG.error(""错误信息 " + e.printStackTrace());
    • “您正在传递将调用 to String 实现的异常对象” 这对于第一行代码是错误的。
    • @PriyambadaMadala 如果您想要 stracktrace,请使用 LOG.error("Error message ", e);。无需致电printStackTrace。
    猜你喜欢
    • 2020-01-04
    • 1970-01-01
    • 2013-08-15
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多