静岡市でWeb開発しているフリーランスのkazuomatzです。
表題の通りで、Exception Notificationなるものの存在も知りつつ、もう少し、自分達の運用に合うような形で、Slack500というGemを作ってみました。
きっかけは、Railsの重大な脆弱性対応や、AWS S3の署名バージョン2(SigV2)の廃止*1などに対応するために、Railsとその仲間達(=Gem)をアップデートする際に、その影響範囲が網羅できないためでした。
まぁ、RSpecやっとけよってことなんですが、やはり、これらのアップデートによってもたらされることは予測できないこともあるので、アップデート後の運用の中で、いち早くエラーを検知して対応するといった対症療法的アプローチも考えようと思いました。
*1) 2020年6月24日移行も継続して延命されました
概要
Slack500の機能としてはシンプルでControllerでrescue_fromで例外をキャッチした先でSlack500の関数を呼ぶ作りです。
エラーの内容を把握するために最低限必要な内容を通知します。
使い方
Gemfileに追加して、
gem 'slack_500'
bundle.
$ bundle
または、
$ gem install slack_500
次に、設定ファイルを作成するために、rakeタスクを実行。
$ rake slack_500:config
/config/initializers/slack_500.rb ファイルができるので、ファイルを編集。
require 'slack_500'
Slack500.setup do |config|
# pretext
config.pretext = 'Slack Report Title'
# タイトル
config.title = 'Rendering 500 with exception.'
# メッセージの左に表示されるバーのカラー
config.color = '#FF0000'
# フッターに表示する文字列
config.footer = 'via Slack 500 Report.'
# WebHook URL
# see https://slack.com/services/new/incoming-webhook
config.webhook_url = "https://hooks.slack.com/services/xxxxxxxxx/xxxx"
end
実装の仕方
class ApplicationController < ActionController::Base
if Rails.env.production?
# Exceptionを補足
rescue_from Exception, with: :rescue_500
end
:
:
def rescue_500(exception)
# Slackに通知
Slack500.post(request,exception)
render 'error/500', status: :internal_server_error, layout: 'application'
end
:
:
end
使ってみて気づいた点
思いの外飛んでくる
テストしとけよって話なのですが、飛んできます。パラメータによる例外、nil例外など。エラーを踏んでくれたユーザー様に感謝しながら修正します。
Slack鳴り止まない状況であったら、夜も眠れない状況になるし、Slack様にもトラフィック負担をおかけしてしまうので、ご利用は計画的にお願いします。
何気にクローラーからのアクセスで通知が飛んでくる
予期しないクエリーパラメーターによる例外や文字コードのencode例外(incompatible character encodings: UTF-8 and ASCII-8BIT)、ResponseをJSONしか用意してないのに、クローラーがtext/htmlを要求して例外などが見つかりました。テストしとけよって話なのですが。
SEO的に影響がある場合もあるので、エラーを潰した方がよいでしょう。ほっといてもよい場合もあるので、User Agentを通知することにして判断できるようにしました。
まとめ
前提として通常のテストで網羅できない場合を想定した導入と考えた方がよいでしょう。一昔前は、GemがいっぱいあってRailsすげぇって話だったのですが、最近は、Gemの作者もメンテナンスを放棄してしまうケースも多くなってきたような気もします。Gemの依存関係が複雑になってきて不用意にbunlde updateしたら動かなくなるケースも結構増えてきたような・・・。
そのようなことを含めてSlack500で運用をしていきたいと思います。