web-dev-qa-db-ja.com

Spring Bootアプリケーションでカスタム例外のスタックトレースロギングを防止する

Spring Boot(mvc)でカスタム例外をログに記録し、スタックトレースがログに表示されないようにスローするファイルはありますか?ただし、他の例外については、スタックトレースが表示されます。

長い説明:

私は春のブーツを使用して、簡単な休憩サービスを作成しています。 カスタム例外の場合、デフォルトではログにスタックトレースがありませんで、json応答は基本的な例外の詳細(ステータス、エラー、メッセージ)で作成されます。

問題はログも作成しないエントリであるため、手動でこれを実行する必要があります。

カスタム例外

@ResponseStatus(value = HttpStatus.CONFLICT)
public class DuplicateFoundException extends RuntimeException {
    public DuplicateFoundException(String message) {
        super(message);
    }
}

サービスメソッドで例外がスローされています(@RestController内)

if (!voteDao.findByItemAndUser(item, voteDto.getUserId()).isEmpty()) {
    log.warn("... already voted ...");   //TODO: don't do this for every throw
    throw new DuplicateFoundException("... already voted ...");
}

より多くの例外があると、各スローの前にログステートメントが配置されることになり、これは悪いアプローチだと思います。サービスメソッドからすべてのログステートメントを削除して、作成しました@ ControlledAdviceすべてのカスタム例外をログに記録しますを再スローして、以前と同じようにNice jsonを取得します。

@ControllerAdvice
public class RestExceptionHandler {
    private static final Logger log = Logger.getLogger(RestExceptionHandler.class);

    @ExceptionHandler
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            log.warn(e.getMessage());
        } else {
            log.error("...");
        }
        throw e;
    }
}

ここで問題は、ログエントリだけでなくカスタム例外のスタックトレースも表示されることですで、これを防ぐ方法を見つけることができません。問題は、もう一度投げることが原因だと思います。考えられる解決策は、代わりに返す例外のカスタムクラスを作成することですが、例外のマーシャリングは正常に機能しているようなので、このアイデアは嫌いです。

ヒントはありますか?ありがとう。

19
rhorvath

解決策は例外処理をスプリングブートに任せるでした。これにより、カスタム例外はログに記録されず、その他のログはデフォルトでログに記録されます。 @ControllerAdviceとログステートメントを残りのコントローラーから削除し、カスタム例外コンストラクターにログステートメントを追加を追加しました。

public DuplicateFoundException(String message) {
    super(message);
    LOGGER.warn(message);
}

これが最善の方法かどうかはわかりませんが、今では1か所にのみカスタムの例外ログがあり、すべての例外に対してログステートメントを繰り返す必要がなく、ログのスタックトレースやその他のエラーメッセージを確認する必要もありません。

1
rhorvath

私はSpring Boot 2+を使用していますが、この行をapplication.propertiesに追加してください:

server.error.include-stacktrace = never

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/web/ErrorProperties.IncludeStacktrace.html

13
Carlos Negron

スタックトレースが必要ない場合は、例外クラスでfillInStackTraceをオーバーライドしてスタックトレースを抑制できます。

_public class DuplicateFoundException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}
_

e.printStackTrace()を呼び出すと、スタックトレースは出力されません。

このブログ投稿 も参照してください。

9