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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です