Java 有没有理由不总是记录堆栈跟踪?

Java 有没有理由不总是记录堆栈跟踪?,java,logging,stack-trace,Java,Logging,Stack Trace,今天在我们的应用程序中遇到了一个令人沮丧的问题,最终导致抛出ArrayIndexOutOfBounds异常。异常的类型几乎是所有记录的类型,这是相当无用的(但是,哦,亲爱的遗留应用程序,我们仍然爱你,大部分)。我重新部署了这个应用程序,并对异常处理记录了堆栈跟踪(并立即找到了问题的根本原因),我想知道为什么以前没有人这样做。您通常会记录堆栈跟踪吗?是否有任何理由不这样做 如果您能够解释(为什么,而不是如何)在java中必须跳转才能获得堆栈跟踪的字符串表示形式背后的基本原理,那么您将获得额外的积分

今天在我们的应用程序中遇到了一个令人沮丧的问题,最终导致抛出
ArrayIndexOutOfBounds
异常。异常的类型几乎是所有记录的类型,这是相当无用的(但是,哦,亲爱的遗留应用程序,我们仍然爱你,大部分)。我重新部署了这个应用程序,并对异常处理记录了堆栈跟踪(并立即找到了问题的根本原因),我想知道为什么以前没有人这样做。您通常会记录堆栈跟踪吗?是否有任何理由不这样做


如果您能够解释(为什么,而不是如何)在java中必须跳转才能获得堆栈跟踪的字符串表示形式背后的基本原理,那么您将获得额外的积分

当开发人员过于自由地登录,系统管理员发现应用程序一旦投入生产负载,就会用大量的日志文件冲击并填充HD时,日志记录的限制常常会被推开。然后,很难让他们相信您已经看到了自己的错误,并且已经充分减少了日志记录(或调整了日志级别),但确实需要那些剩余的日志条目。

  • 有些日志可能包含敏感数据,但日志设施不一定足够安全,无法在生产中跟踪该数据

  • 登录到多会导致信息过多,即系统管理员完全没有信息。如果他们的日志中充满了调试消息,他们将无法识别可疑模式。(几年前,出于安全原因,我看到一个系统记录所有系统调用。日志太多了,以至于当一些非特权用户开始成为root用户时,没有人看到它。)


最好的做法是使用适当的日志级别记录所有内容,并能够在生产中设置日志级别(至少在Java中不是什么大问题)。

我通常会记录堆栈跟踪,因为它包含有关故障排除/调试问题的信息。这是小型转储旁边最好的想法,通常只需通过代码检查和识别问题就可以找到解决方案

顺便说一句,我同意sibidiba关于完整堆栈暴露的应用程序内部潜在信息披露的观点:函数名以及堆栈调用序列可以告诉受过教育的读者很多。这就是为什么有些产品只在堆栈上记录符号地址,并依赖开发人员将地址解析为来自内部PDB的名称的原因


但在我看来,将文本记录到包含1行错误和14行堆栈的文件中会使浏览错误日志变得非常困难。它还导致高并发性应用程序出现问题,因为日志文件上的锁被保留的时间更长(或者更糟,日志文件被交错)。我自己也曾多次遇到这些问题,以及在支持和排除部署我自己的应用程序时遇到的其他问题,导致我实际创建了一项服务,用于记录错误。在设计错误收集策略时,我选择每次收集堆栈转储,并将堆栈用作bucket键的一部分(将同一堆栈上发生的错误分组到同一个bucket中)。

对于我们来说,这非常简单:如果引发意外异常,我们将堆栈跟踪与尽可能多的消息一起记录

我的猜测是,编写问题中的原始代码的开发人员没有足够的经验来知道仅仅使用消息是不够的。我也这么想过一次


将堆栈跟踪作为字符串获取是非常复杂的,因为JRE中没有StringPrintWriter—我相信他们的思路是,它们提供了许多正交的构建块,然后根据需要进行组合。您必须自己组装所需的PrintWriter。

请同时查看这些问题

这里要考虑的重要事情

  • 处理敏感数据
  • 压缩异常消息并将其邮寄到适当的修复程序
  • 记录所需的内容。因为它在空间上很昂贵 时间呢
  • 如果你能解释(为什么, 而不是如何)拥有 在java中跳环以获取字符串 堆栈跟踪的表示


    难道你不应该只记录丢弃的东西,而不是通过环来打印堆栈跟踪吗?如下所示:log.error(“部署失败!”,例如)。如果是一次性的,Log4J将打印通过getMessage()获得的错误消息和堆栈跟踪。

    我经常看到的是代码记录这样的异常:

    日志错误(ex)

    因为log4j接受一个对象作为第一个参数,所以它将记录异常的字符串表示,异常通常只是类的名称。这通常只是开发人员的疏忽。最好像这样记录和记录错误:

    LOG.error(“foo已发生”,ex)


    …因此,如果配置正确,日志框架将记录堆栈跟踪。

    这是使用
    Log4J
    的遗留版本吗?如果是这样,它是否使用了
    org.apache.log4j.RollingFileAppender
    ?我在银行应用程序中使用它(是的,系统非常庞大),我没有任何问题;相反,他似乎在问为什么在他之前的开发人员没有这样做。@danben-正确,问题是关于堆栈跟踪记录的一般实践,而不是如何这样做。对于我不知道如何处理的异常,我总是尝试{…}捕获(异常e){Logger.Error(e);}。生成stacktrace相当慢,但这并不重要,因为此类错误无论如何都不会经常发生。有些人使用
    logger.info()
    logger.debug()
    将“有用”信息传递给日志。因此,记录必要/不必要的数据(取决于您的POV)是有争议的。我这么问是因为似乎有太多的信息传递给了