Sentryの無料枠でも問題なさそうですが、例外が発生した時に通知したいだけなので、
昔からよく使われているException Notifierを導入してみました。
昔はメールでキャッチしていましたが、今はSlackにも対応しています。
導入だけで通知されるケースとされないケースがあります。
smartinez87/exception_notification: Exception Notifier Plugin for Rails
Notifiers
・Datadog notifier
・Email notifier ← 今回はこれと、
・HipChat notifier
・IRC notifier
・Slack notifier ← これを使えるようにします。
・Mattermost notifier
・Teams notifier
・Amazon SNS
・Google Chat notifier
・WebHook notifier
Gem追加
Gemfile
# Use Exception Notification gem 'exception_notification' gem 'slack-notifier'
% bundle install
設定変更
Config(gem)で環境毎に設定を変えられるようにします。
Webhookの作成方法はこちら → エラーをSNS経由でSlackに通知する
% rails g exception_notification:install
config/initializers/exception_notification.rb
config.add_notifier :email, Settings.exception_notifier.email_config.to_hash if Settings.exception_notifier.email_enabled config.add_notifier :slack, Settings.exception_notifier.slack_config.to_hash if Settings.exception_notifier.slack_enabled
config/settings/development.yml
exception_notifier: email_enabled: true email_config: email_prefix: '[WARNING]【開発環境】' sender_address: 'noreply@localhost' exception_recipients: ['warning'] slack_enabled: false slack_config: webhook_url: 'https://hooks.slack.com/services/xxxxxxxx' additional_parameters: color: 'good'
letter_opener_webを導入している場合、ブラウザからメールの確認ができる。
Slackは開発環境では不要なので、falseにしています。
config/settings/production.yml
exception_notifier: email_enabled: <%= ENV['EXCEPTION_NOTIFIER_EMAIL'] == '1' || false %> # 1 email_config: email_prefix: <%= ENV['EXCEPTION_NOTIFIER_EMAIL_PREFIX'] || "[WARNING]#{ENV['ENV_NAME']}" %> sender_address: <%= ENV['EXCEPTION_NOTIFIER_EMAIL_SENDER'] || "noreply@#{ENV['BASE_DOMAIN']}" %> # noreply@example.com exception_recipients: <%= eval(ENV['EXCEPTION_NOTIFIER_EMAIL_RECIPIENTS'] || '[]') %> # ['warning@example.com'] slack_enabled: <%= ENV['EXCEPTION_NOTIFIER_SLACK'] == '1' || false %> # 1 slack_config: webhook_url: <%= ENV['EXCEPTION_NOTIFIER_SLACK_WEBHOOK_URL'] %> # https://hooks.slack.com/services/xxxxxxxx additional_parameters: color: <%= ENV['EXCEPTION_NOTIFIER_SLACK_COLOR'] || 'warning' %>
envを使って、環境毎に使用有無、メールアドレスやチャンネル変更できるようにしています。
config/settings/test.yml
exception_notifier: email_enabled: false slack_enabled: false
RSpecでは使わないので、falseに設定しています。
通知に情報を追加
設定するだけで、リクエスト(controller経由)の例外は通知されるようになりますが、
誰がとURLを記載するようにしました。
但し、メールアドレス等、個人情報は極力入れたくないので、
current_userのidのみ記載するようにしました。
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base before_action :prepare_exception_notifier private # 例外通知に情報を追加 def prepare_exception_notifier return if Rails.env.test? request.env['exception_notifier.exception_data'] = { current_user: { id: current_user&.id }, url: request.url } end
Slack通知
メール通知
ActiveJobはデフォルトでは通知されない
例外をキャッチして、通知するように実装する必要があります。
それぞれのjobでStandardErrorを捕捉している場合は、それぞれに記載する必要があるので注意。
app/jobs/application_job.rb
# 例外通知 rescue_from StandardError do |error| ExceptionNotifier.notify_exception(error) end
Slack通知
開発環境なので、colorは'good'(緑)に設定
メール通知
開発環境なので、letter_opener_webで確認
Taskは通知されない
全体をbegin〜rescue~endして、notify_exceptionを呼び出せば行けますが、
例外は標準出力が出るので、
ECSタスク(Docker) → Cloudwatch Logs → サブスクリプションフィルター
Cron → 対象ユーザーにメール → aliases等で転送
にするのが良さそう。
今回のコミット内容
https://dev.azure.com/nightonly/rails-app-origin/_git/rails-app-origin/commit/a5a0065338f7de6a8d76ad0a5f92cd923e64adb8
https://dev.azure.com/nightonly/rails-app-origin/_git/rails-app-origin/commit/8b8a62f1b5d96a74856395fdb2947f31eb56b776