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;
}
}
ここで問題は、ログエントリだけでなくカスタム例外のスタックトレースも表示されることですで、これを防ぐ方法を見つけることができません。問題は、もう一度投げることが原因だと思います。考えられる解決策は、代わりに返す例外のカスタムクラスを作成することですが、例外のマーシャリングは正常に機能しているようなので、このアイデアは嫌いです。
ヒントはありますか?ありがとう。
解決策は例外処理をスプリングブートに任せるでした。これにより、カスタム例外はログに記録されず、その他のログはデフォルトでログに記録されます。 @ControllerAdviceとログステートメントを残りのコントローラーから削除し、カスタム例外コンストラクターにログステートメントを追加を追加しました。
public DuplicateFoundException(String message) {
super(message);
LOGGER.warn(message);
}
これが最善の方法かどうかはわかりませんが、今では1か所にのみカスタムの例外ログがあり、すべての例外に対してログステートメントを繰り返す必要がなく、ログのスタックトレースやその他のエラーメッセージを確認する必要もありません。
私はSpring Boot 2+を使用していますが、この行をapplication.propertiesに追加してください:
server.error.include-stacktrace = never
スタックトレースが必要ない場合は、例外クラスでfillInStackTrace
をオーバーライドしてスタックトレースを抑制できます。
_public class DuplicateFoundException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
_
e.printStackTrace()
を呼び出すと、スタックトレースは出力されません。
このブログ投稿 も参照してください。