Spring Boot - Sl4j ロガーが例外をキャッチするために ResponseEntityExceptionHandler と組み合わせて使用​​されるとログが記録されない

okwaves2024-01-25  8

@ControllerAdvice を使用して、すべての例外をキャッチし、それに応じてログに記録するキャッチオール例外ハンドラーを作成しました。ただし、何らかの理由で、sl4j ロガーはコンソールにログを記録できません。同じロガーがアプリケーション内の他の場所で動作しますが、キャッチオール例外ハンドラでは動作しません。

@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 が使用されていますが、これがロンボク島と関係があるかどうかはわかりません。スーパークラス (ResponseEntityExceptionHandler) には独自のロガーがあることがわかります。そのため、奇妙な変数の隠蔽が起こっているとは思えませんが、確信はありません。

ロギング プロファイルと設定は、このキャッチオール例外ハンドラー内を除く他の場所で動作しているため、正しいと確信しています。単にログに何も出力しないだけです。

更新:

スーパークラスからロガーを使用でき、機能します。ただし、Apache commons-logging を使用しているため、ここで必要ないくつかの特定のメソッドが欠落しています。



------------------------

Spring Boot のデフォルトのログ レベルは info であるため、デバッグ ログは抑制されます。問題を再現するためにコードを少し変更しました。

@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.info、log.warn、または log.error に変更します。これはあなたの場合により適しています。

解決策 2: application.properties で CatchAllExceptionHandler のデバッグ ログを有効にするプロパティを追加します。

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

abを追加した後の出力オーバープロパティ:

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   : ******

3

ログ レベルはすでに ALL に設定されているため、ログ レベルに関連する問題はなく、同じプロジェクトの他のクラスでも同じアプローチが問題なく機能します。そのため、問題はないと思います。ログ レベルまたはログ プロファイルについて。

– アリ

2020 年 9 月 3 日 23:45

例外ハンドラー コードを try catch に追加できますか。制御が log.debug 行まで到達していない可能性があります

– ヘマント・パテル

2020 年 9 月 5 日 0:13

質問内ですでに共有されています。その行に到達し、その行が正常に実行されます (デバッグ モードで確認しました)。ここでは Sl4j の代わりに使用できる ResponseEntityExceptionHandler のロガー変数があり、問題なく動作します。 Sl4j は、ここを除くアプリケーション内のどこでも動作します。 sl4j ロガーと Apache 共通ログの間に何らかの競合があるのではないかと思われますこの問題の原因となっている ging ロガー (スーパークラスによる)。

– アリ

2020 年 9 月 9 日 1:11

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。