エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

Play2向けSentryライブラリを作成しました

エンジニアリンググループ 中村です。
Play Framework 2.x (以降: Play2)向けのSentryライブラリを公開したので紹介します。

github.com

Sentryとは

エムスリーでは、Sentryというエラートラッキングツールを利用しています。

アプリケーションのエラー発生時に、単にログファイルに出力するだけではエラーに気づくことができません。 代わりにアプリケーション自身からメールを送るなどすることがありますが、普段のメールが埋もれてしまったり、大量に起きたときにメールが詰まることもおきかねません。

そこで、メールの代わりにSentryにエラーの情報を送ります。 Sentryでは同じ種類のログをひとまとめに束ねてくれたり、その種類ごとでの通知頻度を調整してくれたりと便利です。 記録する情報はログテキストだけでなく、例外発生時のスタックトレースやHTTPリクエストの詳細などを含めることもできるため、単に「エラーが起きた」ということ以上の原因追求ための情報もわかるので非常に助かります。

例: Sentryのサンプル画面
f:id:taknakamura:20180927135920p:plain:w300

Javaでの組み込み方法

Sentryを利用するには、アプリケーションにSentryクライアントを組み込むことになります。
各種の言語向けにクライアントライブラリがあり、Java系であればロガーライブラリごとにクライアントモジュールが用意されています。 例えば、logbackに対応したsentry-logbackがあります。 導入ガイドに従っていけば、Sentry用ログアダプタとして利用することができるため、通常のログ出力をそのままSentryへ送信することができるようになります。 またwebアプリであれば、Sentry用のServletRequestListenerが用意されているおかげで、自動でHTTPリクエストの内容もSentryの記録につけてくれるようになります。 Sentry用のServletRequestListenerによって、リクエスト受けた時にHTTPリクエスト情報をスレッドローカルに保持しておき、Sentryへのログ出力時にそれを使うようになっています。

Play2への対応

Play2でSentryを使うには前述のJavaのライブラリを使えばよいのですが、以下の問題があります。

  1. sentry-logbackはServlet APIのみをサポートしているため、Play2のHTTPリクエスト情報は取得できない
  2. Futureを使ったマルチスレッド処理を多用すると、スレッド間でHTTPリクエスト情報の受け渡す必要がある

そこで、これらに対処するためのライブラリを作成しました。

https://github.com/m3dev/play2-sentry

このライブラリでは、主に以下のことをしています。

  1. Play2のplay.api.mvc.RequestHeaderの内容をSentry向けのデータに変換し、スレッドローカルに保持する
  2. 独自のAkka Dispatcherによって新スレッド起動時に、HTTPリクエスト情報を親スレッドから新規スレッドに渡す

ライブラリを組み込む時にはSentryクライアントそのもの手順に追加して、拡張したSentryを使うようにすることと、独自のAkka Dispatcherを使うようにするための設定変更が必要です。 詳細な手順は、リポジトリのREADMEを参照してください。

未対応なこと

社内での必要性に沿って作ったものなので、Play2の最新版ではなく2.4が対象になっています。追って最新版への対応もしていきたいと思っています。

また、Sentryのログへ付与するメタ情報の一部がまだマルチスレッド間の対応ができていない部分もあるので、随時機能追加したいと思います。

エンジニア募集

エムスリーでは技術で医療の課題を解決するエンジニアを募集しています。 Sentryを利用するような開発環境の改善、利用を促進する共有モジュールの開発など、この記事を読んで興味を持った方はぜひ下記リンクよりご応募ください!