Mastodonのエラー情報をErrbitで収集してみる


この記事はMastodon Advent Calendar 2017の10日目の記事です。昨日はcrakaCさんの1コア512MBのVPSでMastodonする - Dive into Ofutonです。

最近自分でもMastodonのインスタンスを立てて、エラーを収集し始めたのでその話を書こうと思います。

エラー収集をしようと思ったきっかけ

Mastodonは日々開発が進んでいて、どんどん新しい機能が追加されています。しかし、それと同時にバグが混入してしまうこともあります。

Mastodonはsidekiqによる非同期の処理が多いため、「ブラウザでアクセスしてもエラーは表示されないけど裏側ではうまくうごいていない」みたいなことが起こりやすいです。そこで、そういったエラーに気づけるようにエラーを収集してしてみることにしました。

Errbitのセットアップ

Errbitはエラーを収集するWebアプリで、オープンソースで公開されています。DockerImageが公開されているのでさくっと立てれてます。

Mastodon側にはAirbrakeのgemをインストールします。AirbrakeはErrbitと同じようにエラーを収集するWebサービスで、こちらは有料のサービスです。ErrbitはAirbrakeのAPIに準拠しているので、エラー情報を送信するときはairbrakeのgemを使用します。

Gemfile
gem 'airbrake', '~> 5.0'

設定ファイルはこんな感じです。送信先のErrbitの情報や、収集するエラーのフィルタリングの設定をしています。

config/initializers/errbit.rb
Airbrake.configure do |config|
  config.host = ENV.fetch('AIRBRAKE_HOST')
  config.project_id = ENV.fetch('AIRBRAKE_PROJECT_ID') # required, but any positive integer works
  config.project_key = ENV.fetch('AIRBRAKE_PROJECT_KEY')

  # Uncomment for Rails apps
  config.environment = Rails.env
  config.ignore_environments = %w(development test)
end

Airbrake.add_filter do |notice|
  if notice[:errors].any? { |error|
    error[:type].constantize.ancestors.include?(HTTP::Error) ||
    ['Mastodon::UnexpectedResponseError', 'OpenSSL::SSL::SSLError', 'Excon::Error::ServiceUnavailable', 'Excon::Error::Timeout', 'ActiveRecord::ConnectionTimeoutError'].include?(error[:type])
  }
    notice.ignore!
  end
end

Mastodonでは、sidekiqでネットワーク系のエラーが発生した場合はリトライするように実装されているので、無視するエラーには主にネットワーク系のエラーを指定しています。

収集したエラーを見てみる

エラーが発生するとこのようにどんどんエラー情報が溜まっていきます。
左側のカウントを見るとわかるように、ある程度同じエラーはまとめられます。ただ、コードに変更があると別として扱われたりするみたいです。

詳細画面はこんな感じです。発生したエラーや、発生した場所などの情報が概要に表示されています。発生した場所(WHERE)は、sidekiqの場合はsidekiqと表示されますが、通常のHTTPリクエストの場合はコントローラーのメソッド(例: statuses#show)が表示されます。

他にもバックトレース(Backtrace)やHTTPのリクエストヘッダ(Environment)、パラメータ(Parameters)などを見ることができます。
さらに、下の方にはコメント入力欄があるので、メモを残すこともできます。(URLを載せてもリンクにならないのが気になりますが)

バックトレースはこんな感じに表示されます。app以下のファイルでは緑色になっているので見やすいですね。

パラメータはこんな感じです。sidekiqの場合はsidekiqに渡された引数が表示され、HTTPリクエストの場合はGETパラメータやPOSTパラメータの内容が表示されます。

sidekiqの場合:

HTTPリクエストの場合:

おわりに

Errbitを使うことで手軽にエラー情報を収集したり見たりできるので非常に便利です。
ただ、アカウント周りはいまいちな部分が多いです。アカウントは手動じゃないと作れず、アカウントごとに見れるプロジェクトを制限できないので、そのあたりが改善されると複数人でもErrbitが使いやすくなるかなと思いました。

何回かは収集されたエラーを修正してプルリクエストを送ることはできました。しかし、思っていたほどエラーが集まりませんでした(もちろんそのほうがいいですが)。
エラーを収集するために立てたインスタンスはほぼ自分しか使っておらず、一部の機能しか使えていないので、エラーが集まりにくいのではないかと思いました。

そのため、多くの人がいろんな機能を使う大きいインスタンスのほうが多くのエラー情報を収集できるような気がします。
とりあえずもうしばらくはこのまま動かして、一日に一回ぐらいエラーが収集されているか確認しようと思います。

明日はzundanさんです!