关于异常日志打印的问题

问题

  • 在开发中看到系统大量使用try catch(Exception e)包裹业务代码,然后打印信息。让我不禁想到这样包裹真的好么??又因为代码中我发现一些问题就算是因为这样的包裹没有及时处理异常导致报错却没有打印信息,很难发现问题!

查阅

  • 《Think in java》:1.不应把java的异常处理机制当成是单一用途的工具。是的,他是被设计用来处理一些烦人的运行时错误,这些错误往往是由代码控制能力之外的因素导致的,然而,他对于发现某些编译器无法检测到的编程错误,也是非常重要的。
  • 《Think in java》:2.处理异常的一个重要原则是"只有在你知道如何处理的情况下才捕获异常"。实际上,异常处理的一个重要目标就是把错误处理的代码同错误发生的地点相分离。这使你能在一段代码中专注于要完成的事情,至于如何处理错误,则放在另一段代码中完成。这样一来,主干代码就不会与错误处理逻辑混在一起,也更容易理解和维护。通过允许一个处理程序去处理多个出错点,异常处理还使得错误处理代码的数量趋向于减少。
  • 《Think in java》:3."被检查的异常"使这个问题变得有些复杂,因为他们强制你在可能还没准备好处理错误的时候被迫加上catch子句,这就到导致了吞食则有害的问题。
  • 极客时间专栏介绍:第一,尽量不要捕获类似 Exception 这样的通用异常,而是应该捕获特定异常。这是因为在日常的开发和合作中,我们读代码的机会往往超过写代码,软件工程是门协作的艺术,所以我们有义务让自己的代码能够直观地体现出尽量多的信息,而泛泛的 Exception 之类,恰恰隐藏了我们的目的。另外,我们也要保证程序不会捕获到我们不希望捕获的异常。比如,你可能更希望 RuntimeException 被扩散出来,而不是被捕获。进一步讲,除非深思熟虑了,否则不要捕获 Throwable 或者 Error,这样很难保证我们能够正确程序处理 OutOfMemoryError。
  • 极客时间专栏介绍:第二,不要生吞(swallow)异常。这是异常处理中要特别注意的事情,因为很可能会导致非常难以诊断的诡异情况。生吞异常,往往是基于假设这段代码可能不会发生,或者感觉忽略异常是无所谓的,但是千万不要在产品代码做这种假设!如果我们不把异常抛出来,或者也没有输出到日志(Logger)之类,程序可能在后续代码以不可控的方式结束。没人能够轻易判断究竟是哪里抛出了异常,以及是什么原因产生了异常。
  • 极客时间专栏介绍:我们先来看看printStackTrace()的文档,开头就是“Prints this throwable and its backtrace to the standard error stream”。问题就在这里,在稍微复杂一点的生产系统中,标准出错(STERR)不是个合适的输出选项,因为你很难判断出到底输出到哪里去了。尤其是对于分布式系统,如果发生异常,但是无法找到堆栈轨迹(stacktrace),这纯属是为诊断设置障碍。所以,最好使用产品日志,详细地输出到日志系统里。
  • 极客时间专栏介绍:有的时候,我们会根据需要自定义异常,这个时候除了保证提供足够的信息,还有两点需要考虑:1.是否需要定义成 Checked Exception,因为这种类型设计的初衷更是为了从异常情况恢复,作为异常设计者,我们往往有充足信息进行分类。2.在保证诊断信息足够的同时,也要考虑避免包含敏感信息,因为那样可能导致潜在的安全问题。如果我们看 Java 的标准类库,你可能注意到类似 java.net.ConnectException,出错信息是类似“ Connection refused (Connection refused)”,而不包含具体的机器名、IP、端口等,一个重要考量就是信息安全。类似的情况在日志中也有,比如,用户数据一般是不可以输出到日志里面的。
  • 极客时间专栏介绍:try-catch 代码段会产生额外的性能开销,或者换个角度说,它往往会影响 JVM 对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的 try 包住整段的代码;与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句(if/else、switch)要低效。
  • 极客时间专栏介绍:Java 每实例化一个 Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了。

总结(吐槽:copy半天的资料)

  • java编程思想和极客专栏都说到有一点,不要生吞异常。生吞异常可能会导致问题很难发现。
  • java编程思想中有说道,异常捕获重要原则是"只有在你知道如何处理的情况下才捕获异常",那么在撸代码时不能随意捕获异常,特别是一些运行时自己不知道可能出现的异常,所以捕获Exception异常也算是一种偏激的做法。
  • 书中说:“他是被设计用来处理一些烦人的运行时错误”,那么可预知的错误我们应当提前避免或者提前抛出或者处理,比如空指针。
  • 异常捕获中日志变得非常重要,做好日志的异常处理及信息打印。
  • try catch尽可能包含能预知的小范围,有一定性能消耗。

你可能感兴趣的:(java)