【问题标题】:How to log only part of an exception?如何仅记录部分异常?
【发布时间】:2021-04-24 08:48:59
【问题描述】:
private static InputStream getFileFromClassPathOrFileSystem(String path) {
    try {
        //try to get from something like file:///some/path, and if missing Scheme exception, go to catch clause
        return Files.newInputStream(Paths.get(URI.create(path)));
    } catch (IllegalArgumentException | IOException e) {
        LOGGER.info("Could not retrieve from file system, trying classpath. If the exception is 'Missing scheme' this can be ignored");
        return Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
    }
}

SonarQube 使用 Either log or rethrow this exception 标记此问题。这对我们来说很有意义,所以我们将e 添加到记录器行:

LOGGER.info("Could not retrieve from file system, trying classpath. If the exception is 'Missing scheme' this can be ignored", e);

虽然这解决了声纳问题,并且确实为我们提供了更多有用的信息,但我们现在充斥着 40 行的堆栈跟踪。 (并且该方法被称为 LOT ??????)

有没有可能两全其美?就像记录了错误,但只有部分错误(实际上,只有前两行很好),并且没有被 SonarQube 标记?

【问题讨论】:

    标签: java exception logging sonarqube


    【解决方案1】:

    您可以只使用原因消息而不使用完整堆栈:

    e.getMessage()
    

    返回此 throwable 的详细消息字符串。

    【讨论】:

    • LOGGER.info(无法从文件系统中检索,正在尝试类路径。如果异常是“缺少方案”,则可以忽略“{}”,e.getMessage());
    • 这仍将被标记为“记录或重新抛出此异常”。 :'(
    【解决方案2】:

    堆栈跟踪/日志总是在生产系统中拯救,这些是系统运行时的记录。

    PS:请检查为什么此特定方法会发生这么多异常。

    如果您不想记录,可以将记录器级别更改为调试/跟踪,这样可以避免减少堆栈跟踪。

    LOGGER.debug("Could not retrieve from file system, trying classpath. If the exception is 'Missing scheme' this can be ignored", e);
    LOGGER.trace("Could not retrieve from file system, trying classpath. If the exception is 'Missing scheme' this can be ignored", e);
    

    提出问题,下面是一段代码(从 e.printStackTrace() 复制的),它将打印消息和前 5 行。

    免责声明:请不要在生产中使用它。

    StackTraceElement[] ele = e.getStackTrace();
    System.out.println(e.getMessage());
    for(int i=0; i<ele.length && i<=5; i++){
    System.out.println("at " + ele[i]);
    }
    

    【讨论】:

      【解决方案3】:

      也许最好的解决方案是标记 SonarQube 警告。

      为了说服记录器仅打印堆栈跟踪的“有趣位”,您很可能需要编写自定义日志消息格式化程序或附加程序。可靠地找出有趣的部分是什么(跨越您的应用程序可能抛出的所有异常等)可能是一个挑战。

      请注意,记录异常消息(如建议的那样)不会关闭 SonarQube。至少,如果要相信这个测试用例,则不会:

      另一方面,它看起来像:

      } catch (Exception e) { // Compliant
        String message = "Some context for exception" + e.getMessage();
        JAVA_LOGGER.info(message);
      }
      

      SonarQube 可以接受,但它不记录任何堆栈帧。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 2014-02-28
        • 2017-11-01
        • 1970-01-01
        • 2015-04-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多