避免使用printStackTrace(); 而是使用日志记录器调用

114

我的应用程序中,我正在通过PMD运行我的代码。它显示了以下消息:

  • 避免使用printStackTrace(); 使用日志记录调用替代。

这是什么意思?


如果您只想避免此消息,而不使用try/catch,请使用throws。 - lamrongol
7个回答

182

这意味着您应该使用类似于或者的日志框架,而不是直接打印异常:

e.printStackTrace();

你应该使用这个框架的API来记录它们:

log.error("Ops!", e);

日志框架提供了很大的灵活性,例如您可以选择是将日志记录到控制台还是文件中 - 或者在某些环境中发现它们不再相关时跳过某些消息。


48
如果你在异常上调用printStackTrace(),则堆栈跟踪将被写入System.err,很难将其路由到其他位置(或过滤它)。建议使用日志框架(或多个日志框架的包装器,如Apache Commons Logging),并使用该框架记录异常(例如,logger.error("一些异常消息",e))。

这样做可以让你:

  • 将日志语句同时写入不同的位置,例如控制台和文件。
  • 通过严重程度(错误、警告、信息、调试等)和来源(通常基于包或类)过滤日志语句。
  • 在不必更改代码的情况下对日志格式产生一定的影响。
  • 等等。

20

一个生产质量的程序应该使用其中一种日志记录工具(例如log4j、logback、java.util.logging)来报告错误和其他诊断信息。这有许多优点:

  • 日志消息会被发送到可配置的位置。
  • 除非你配置了日志,否则最终用户不会看到这些消息。
  • 您可以使用不同的日志记录器和日志记录级别等来控制记录多少或少量日志。
  • 您可以使用不同的追加器格式来控制日志的外观。
  • 您可以轻松地将日志输出插入到更大的监视/日志框架中。
  • 所有这些都可以在不更改代码的情况下完成;即通过编辑已部署应用程序的日志配置文件来完成。

相比之下,如果仅使用printStackTrace,则部署者/最终用户几乎没有任何控制权,而日志消息很可能会在不适当的情况下丢失或显示给最终用户。(对于一条随机的堆栈跟踪,没有什么比这更恐怖的了。)


7

简单来说,e.printStackTrace() 不是一个好的做法,因为它只是将堆栈跟踪输出到标准错误流。由于这个原因,你不能真正控制这个输出去向。


1
几乎每个日志框架都提供了一种方法,可以将throwable对象与消息一起传递。例如:
public trace(Marker marker, String msg, Throwable t);

他们会打印可抛出对象的堆栈跟踪。

这并没有回答问题。 - Stephen C

-1

让我们从公司的概念来谈论。日志记录器提供了灵活的级别(参见logger.info和logger.debug之间的区别)。不同的人想要看到不同的级别,比如QA、开发人员、业务人员。但是e.printStackTrace()会打印出所有内容。此外,如果这个方法将被restful调用,同样的错误可能会打印多次。那么你公司的Devops或Tech-Ops人员可能会疯掉,因为他们会收到相同的错误提醒。 我认为更好的替代方案可能是log.error("XXX中发生了错误", e) 这也将打印出整个信息,比e.printStackTrace()更容易阅读。


-3
主要原因是Proguard会从生产中删除Log调用。因为通过记录或打印StackTrace,可以在Android手机上通过例如Logcat Reader应用程序看到它们(堆栈跟踪或日志内的信息)。因此,这是一个不安全的做法。此外,在生产期间我们也无需访问它们,最好将其从生产中删除。由于ProGuard仅删除所有日志调用而不是StackTrace,因此最好在catch块中使用Log,并让Proguard将它们从生产中删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接