はじめに
- この記事は ZOZO Advent Calendar 2023 #1 23日目の記事になります
何をしたか
- Java Sentry Legacy SDK(1.7系) - spring を6.x系まで一気にバージョンアップしました
- 使い方が色々変わっていたが、migration guideがあまり参考にならなかったので対応内容を備忘録としてまとめます
なぜしたか
- 2023/11/24のSpring Boot 2.7.x End of Supportに伴い、ZOZOで稼働中のマイクロサービスの一部のSpring Bootのバージョンを3.1.x系に上げました
- 前提条件としてJava11->17の移行も同時に行ったがそこは本記事では割愛します
- ZOZOではエラー検知の仕組みの一つしてSnetryを運用しています。今回Spring BootバージョンアップしたマイクロサービスではSentry Legacy SDK(1.7系)を利用していましたが、Spring Boot 3系のバージョンアップ時にjavax->jakartaのパッケージ変更が必要となった関係で使えなくなりました
- jakartaに対応したsentry-springは
やったこと1
- なにはともあれdependenciesの変更
build.gradle
- implementation 'io.sentry:sentry-spring:1.7.5' + implementation 'io.sentry:sentry-spring-boot-starter-jakarta:6.32.0'
- jakarta対応のライブラリは
sentry-spring-jakarta
もありましたが、最低versionが6.7.x
だったのでこの際と思いsentry-spring-boot-starter-jakarta
を使うことにしました
やったこと2
-
SentryExceptionResolver
が使えなくなったのでCustomEventProcessor
を追加- sentry-spring 1.7系では、SentryExceptionResolverをBean登録することで、Controllerでthrowされる例外がすべてSentryに送信されます
- また、resolveExceptionメソッドをOverrideすることで、requestの情報などを取得でき、Sentryへの通知メッセージを改変することができます
public class CustomSentryExceptionResolver extends SentryExceptionResolver { @Override public ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { EventBuilder eventBuilder = (new EventBuilder()) .withMessage("sample message") .withLevel(Event.Level.ERROR) .withSentryInterface(new ExceptionInterface(ex)); Sentry.capture(eventBuilder); } }
- 6.x系では
SentryExceptionResolver
は使えないので、同様のことを実現する方法としてEventProcessor
を使いました
@Component public class CustomEventProcessor implements EventProcessor { @Override public SentryEvent process(SentryEvent event, Hint hint) { Message sentryMessage = new Message(); sentryMessage.setMessage("sample message"); event.setMessage(sentryMessage); event.setLevel(SentryLevel.ERROR); return event; } }
-
HttpServletRequest
は以下のコードで取得可能です
HttpServletRequest request = hint.getAs(SPRING_RESOLVER_REQUEST, HttpServletRequest.class);
- sentry-spring 1.7系では、SentryExceptionResolverをBean登録することで、Controllerでthrowされる例外がすべてSentryに送信されます
やったこと3
- やったこと2とも関連しますが、event関連のpackageとSentryへのマニュアルメッセージ通知メソッドが変更となっていますので、ドキュメントを参照し修正しました
- import io.sentry.event.Event;
- import io.sentry.event.EventBuilder;
- import io.sentry.event.interfaces.ExceptionInterface;
+ import io.sentry.SentryEvent;
+ import io.sentry.SentryLevel;
+ import io.sentry.protocol.Message;
@Component
public class SentryHelper {
public void capture(String logMessage, Exception e) {
- EventBuilder eventBuilder =
- new EventBuilder()
- .withMessage(logMessage)
- .withLevel(Event.Level.ERROR)
- .withSentryInterface(new ExceptionInterface(e));
- Sentry.capture(eventBuilder);
- }
+ SentryEvent sentryEvent = new SentryEvent();
+ Message sentryMessage = new Message();
+ sentryMessage.setMessage(logMessage);
+ sentryEvent.setMessage(sentryMessage);
+ sentryEvent.setLevel(SentryLevel.ERROR);
+ sentryEvent.setThrowable(e);
+ Sentry.captureEvent(sentryEvent);
}
やったこと4
- 6.x系ではデフォルトでは
unhandled exception
のみがSnetryに通知されます。以下の設定をすることでhandled exception
も通知されますapplication.ymlsentry: exception-resolver-order: -2147483647
まとめ
-
sentry:sentry-spring-boot-starter
に移行したことで、使い方はよりシンプルになり実装しやすくなりました - sentry-springのバージョンが大幅に上がったことでSentryに通知される情報もより詳細になり、エラー要因の調査もしやすくなりました
- これからsentry-spring Legacy SDKをバージョンアップしようとしている方の参考になれば幸いです