【问题标题】:Sl4j logger does not log when it used in conjunction with ResponseEntityExceptionHandler for catching exceptionsSl4j 记录器在与 ResponseEntityExceptionHandler 结合使用以捕获异常时不记录
【发布时间】:2020-12-22 15:28:02
【问题描述】:

我使用@ControllerAdvice 创建了一个包罗万象的异常处理程序来捕获所有异常并相应地记录。但是,由于某种原因,sl4j 记录器无法登录到控制台。同一个记录器在我的应用程序中的所有其他地方都可以工作,但它在 catch-all 异常处理程序中不起作用。

@ControllerAdvice
@Slf4j
public class CatchAllExceptionHandler extends ResponseEntityExceptionHandler {

  private ResponseEntity<Object> buildResponseEntity(ApiError apiError) {
    return new ResponseEntity<>(apiError, apiError.getStatus());
  }

  @ExceptionHandler(Exception.class)
  public ResponseEntity<Object> catchAllExceptionHandler(Exception ex) {
    ApiError apiError =
        ApiError.builder()
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .message("An internal service issue")
            .debugMessage(ex.getMessage())
            .build();
    log.debug("An issue has occurred, {}, {}", kv("message", ex.getMessage()),
        kv("trace", ex.getStackTrace()));
    return buildResponseEntity(apiError);
  }
}

Sl4j 来自 Lombok 已被使用,但我不确定这是否与 Lombok 有关。我可以看到超类(ResponseEntityExceptionHandler)有自己的logger,所以我认为没有发生任何奇怪的变量隐藏,但我不确定。

我很确定我的日志记录配置文件和配置是正确的,因为它可以在除了这个包罗万象的异常处理程序之外的任何其他地方工作。它只是不会在日志中打印任何内容。

更新:

我可以使用超类中的记录器并且它可以工作。但是,它使用了 apache commons-logging,但这里缺少一些我需要的特定方法。

【问题讨论】:

    标签: spring-boot logging slf4j lombok


    【解决方案1】:

    Spring boot 默认日志级别是info,因此debug 日志被抑制。我稍微修改了您的代码以重现该问题。

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> catchAllExceptionHandler(Exception ex) {
      log.info("******");
      log.debug("An issue has occurred, {}", ex.getMessage());
      log.info("An issue has occurred, {}", ex.getMessage());
      log.info("******");
      return ResponseEntity.status(500).build();
    }
    

    上述代码的输出:
    仅查看已打印的信息日志。

    2020-09-03 22:25:45.065  INFO c.e.demo.main.CatchAllExceptionHandler   : ******
    2020-09-03 22:25:45.065  INFO c.e.demo.main.CatchAllExceptionHandler   : An issue has occurred, test exception
    2020-09-03 22:25:45.065  INFO c.e.demo.main.CatchAllExceptionHandler   : ******
    

    解决方案 1:
    log.debug 更改为log.infolog.warnlog.error。这更适合您的情况。

    解决方案 2:
    application.properties 中添加一个属性以启用CatchAllExceptionHandler 的调试日志。

    logging.level.com.example.demo.main.CatchAllExceptionHandler=debug
    

    添加以上属性后的输出:

    2020-09-03 22:36:05.389  INFO c.e.demo.main.CatchAllExceptionHandler   : ******
    2020-09-03 22:36:05.389 DEBUG c.e.demo.main.CatchAllExceptionHandler   : An issue has occurred, test exception
    2020-09-03 22:36:05.389  INFO c.e.demo.main.CatchAllExceptionHandler   : An issue has occurred, test exception
    2020-09-03 22:36:05.389  INFO c.e.demo.main.CatchAllExceptionHandler   : ******
    

    【讨论】:

    • 已经为 ALL 设置了日志级别,因此没有与日志级别相关的问题,并且相同的方法在同一项目的其他类中没有任何问题,所以我认为不是关于日志级别或日志配置文件。
    • 您能否在 try catch 中添加您的异常处理程序代码。可能是控制没有到达 log.debug 行
    • 已在问题中分享。它到达该行并成功运行该行(我已经在调试模式下检查过它)。有一个来自 ResponseEntityExceptionHandler 的记录器变量,我可以在这里使用它来代替 Sl4j,它可以正常工作。 Sl4j 在我的应用程序中的其他任何地方都可以使用,除了这里。我怀疑 sl4j 记录器和 Apache 通用日志记录器(根据超类)之间存在某种冲突,导致了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 2010-11-08
    • 2013-05-02
    • 2014-05-31
    • 2011-11-25
    • 2011-09-08
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多