以下の内容はhttps://vividcode.hatenablog.com/entry/ktor-sentryより取得しました。


Ktor で例外発生時に Sentry にクラッシュレポートを送る

最近、個人で web アプリケーションを書くのに Ktor (Kotlin の web アプリケーションフレームワーク) を使っています。

Ktor では、1 つ以上の 「インターセプタ (interceptor)」 から成る 「パイプライン (pipeline)」 にリクエストを通すことで、HTTP リクエストに対する処理が実行されます。 各インターセプタがリクエストに対して処理を行う、という形です。 パイプラインについての詳細なドキュメントはまだ未整備な状態 *1 ですが、Application の説明の方にパイプラインについても簡単に書かれています。

Sentry にクラッシュレポートを送る

今回は、後段のインターセプタで例外が発生した際に Sentry にクラッシュレポートを送るためのインターセプタを書いてみました。

Application クラスの intercept メソッド *2 を呼び、インターセプタを追加します。

fun Application.main() {
    // ... (略) ...
    Sentry.init(sentryDsn)
    // Application#intercept メソッドでインターセプタを追加する。
    intercept(ApplicationCallPipeline.Call) {
        try {
            proceed()
        } catch (e: Exception) {
            // 追加情報としてリクエストのエンドポイントの情報を与える。
            Sentry.getContext().addExtra(
                "Request endpoint",
                "${call.request.httpMethod.value} ${call.request.uri}")
            Sentry.capture(e)
            throw e
        } finally {
            Sentry.clearContext()
        }
    }
    // ... (略) ...

Sentry クラスなどは Sentry 公式の sentry ライブラリのものです。

悩み事

Ktor ではコルーチンが使われているため、各リクエストに対して 1 スレッドが割り当てられる、というわけではありません。 一方で、sentry ライブラリのコンテキストマネージャはデフォルトだとスレッドローカル変数を使用してコンテキストが分かれるような作りになっていて、Ktor の処理の中の様々な場所で Sentry のコンテキストを触ろうとするとスレッド違いなどを意識しないといけなくて難しそう、だと思ってます。

上の例では同じスレッド上でコンテキストを触っているので問題ないのですが、もうちょっと込み入ったことをしたくなると不便そうです。 コンテキスト管理をスレッドローカル変数でやるのは悪い文化。

Ktor でクラッシュレポートを Sentry に送るライブラリ

ライブラリもあります。 が、まだスナップショットでしかリリースしてなさそう? なので私は避けました。

本記事でのバージョン

  • Kotlin 1.2.10
  • Ktor 0.9.0
  • sentry 1.6.4

*1:ページとしては存在するが、まだ記載されていない

*2:Application クラスが継承している Pipeline クラスが実装している




以上の内容はhttps://vividcode.hatenablog.com/entry/ktor-sentryより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14