この記事では、Railsアプリのエラーを自動でSlackに通知する方法について解説します。
今回は、簡単なTODOアプリに通知機能を追加し、実践していきます。
目次
1. Slack側の設定
2. Railsアプリに記述を加えていく
3. エラーを通知する
4. 通知フォーマットのカスタマイズ
5. まとめ
6. 参考資料
今回の完成イメージ
1. Slack側の設定
まずはSlackチャンネルに通知を送信するためのSlack Appを作成します。
この記事で手順がとても丁寧にまとめられていますので、参考にしながらSlackの通知アプリを作成してください。
これでslackの通知アプリが作成できます。
最後の動作確認が少し難しいですが、
その場合は下の画像にある curl -X
から始まるコマンドをコピーしてターミナルで実行してください。正しく設定できていれば、Slackに「Hello, World!」と通知が届くはずです。
例:
% curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/~~~~~~
ターミナルで実行すると、、、 通知が来た!
Slackへの通知が確認できたら、次に進みます。
2. Railsアプリに記述を加えていく
この簡単なTODOアプリを使って実践していきます。
エラーが発生した際にSlackに通知が届くように設定してみましょう。
以下が、プロジェクトのディレクトリ構造です。
todo_app/
├── app/
│ ├── controllers/
│ │ ├── application_controller.rb # カスタム通知の設定
│ │ └── todos_controller.rb # タスクの作成機能を実装
├── config/
│ ├── initializers/
│ │ └── exception_notification.rb # エラー通知の設定を担当
├── .env # SlackのWebhook URLを設定
└── Gemfile # 使用するGemのリスト
必要なGemをインストール
まず、slack-notifier
とdotenv-rails
をGemfile
に追加します。
gem 'slack-notifier'
gem 'dotenv-rails'
追加後、以下のコマンドでGemをインストールします。
bundle install
-
slack-notifier
はSlackに通知を送る際に使います -
dotenv-rails
は環境変数を.env
ファイルで管理するためのGemです
今回はSlackのWebHooksURLを環境変数で管理する際に利用します。
環境変数にWebhook URLを設定
先ほど取得したWebhook URLを .env
ファイルに保存します。
プロジェクトのルートディレクトリに .env
ファイルを作成し、次のようにWebhook URLを設定します。
SLACK_WEBHOOK_URL=https://hooks.slack.com~~~~~ # 取得したWebHooksURL
.env
ファイルはGitに含めないように、.gitignore
ファイルに追加しておきましょう。
/.env
Slack通知の設定
次に、slack-notifier
を使ってSlackにメッセージを送信するコードを追加します。
今回はcreateアクションに追記して、新規投稿の際にslack通知が発生するようにします。
def create
@todo = Todo.new(todo_params)
if @todo.save
redirect_to todos_path
else
render :index
end
+ notifier = Slack::Notifier.new(
+ ENV['SLACK_WEBHOOK_URL']
+ )
+ notifier.ping '新しいタスクを作成しました。'
end
コードの解説
notifier = Slack::Notifier.new(
ENV['SLACK_WEBHOOK_URL']
)
この部分では、slack-notifier
Gemを使ってSlackに通知を送るための notifier
オブジェクトを作成しています。
-
Slack::Notifier.new
: 新しいNotifier
オブジェクトを作成します。 -
ENV['SLACK_WEBHOOK_URL']
: Webhook URL.env
ファイルで環境変数として管理されており、ここで呼び出しています。このURLを使って、どのSlackチャンネルに通知を送るかを指定しています。
notifier.ping '新しいタスクを作成しました。'
-
notifier.ping
: 実際にSlackにメッセージを送るためのメソッドです。 -
新しいタスクを作成しました。
: Slackに送信されるメッセージの内容です。この部分は自由にカスタマイズ可能で、タスクの内容や他の情報を含めることもできます。
これで、タスク作成時にSlackに通知が届くようになります。
ちなみに新規投稿が成功しようが失敗しようが通知はされますが、
今回は練習なので特に気にせず行きましょう。
実際にタスクを作成してみると、
Slackへの通知が無事に届きました!
3. エラーを通知する
ここまでで、任意のアクションが動作した際にSlackに通知されるようになりました。
次にRailsアプリでエラーが発生した際に自動で通知を送信する方法を紹介します。
必要なGemをインストール
exception_notification
をGemfile
に追加します。
gem 'exception_notification'
-
exception_notification
は、Railsアプリで発生した例外を自動的に通知するためのGemです。このGemを使うと、例外が発生した際にSlack以外にもメール、Webhooks、Campfireなどでエラーの詳細を送信することができます。
忘れずにGemをインストールします。
bundle install
次に、以下のコマンドで設定ファイルを作成します。
$ rails g exception_notification:install
作成された config/initializers/exception_notification.rb
に、Slack通知用の設定を追加します。
exception_notification
Gemを使用して、例外発生時に自動で通知が行われるようにします。以下がその設定コードです。
require 'exception_notification/rails'
ExceptionNotification.configure do |config|
config.add_notifier :slack, {
:webhook_url => ENV['SLACK_WEBHOOK_URL']
}
end
コードの解説
require 'exception_notification/rails'
まず、この行で exception_notification
のライブラリがRails環境に読み込まれます。このライブラリには、Railsの例外処理をフックして、例外が発生したときに通知を行う仕組みが組み込まれています。
Railsのミドルウェアが例外をキャッチ
Railsには例外処理を行うためのミドルウェアが組み込まれており、このミドルウェアがリクエストのライフサイクルで発生した例外をキャッチします。通常、このミドルウェアは未処理の例外をキャッチすると、500エラーとしてレスポンスを返しますが、exception_notification がインストールされると、この例外キャッチのフックに exception_notification の通知処理が追加されます。
ExceptionNotification.configure do |config|
この部分では、exception_notification
Gemの設定を行います。configure
メソッドを使って、通知の設定を定義します。
config.add_notifier :slack, {
:webhook_url => ENV['SLACK_WEBHOOK_URL'],
}
-
config.add_notifier :slack
: ここでは、Slackに通知を送るための設定を追加しています。:slack というキーを使ってSlack通知の設定を行います。 -
webhook_url
、Slack通知を送信するために必要な情報です。
この設定を追加することで、Railsアプリケーション内でエラー(例外)が発生した際に、Slackにそのエラー内容が自動で通知されます。
実際にエラーが発生した際の通知
検証!
意図的にエラーを発生させて、通知が送信されるか確認します。
todos_controller.rb
の create
アクション内で、@todo
を @todos
に変更し、NoMethodエラーを発生させます。
def create
@todo = Todo.new(todo_params)
- if @todo.save
+ if @todos.save
redirect_to todos_path
else
render :index
end
# ここはもう必要ない!
# notifier = Slack::Notifier.new(
# ENV['SACK_WEBHOOK_URL']
# )
# notifier.ping '新しいタスクを作成しました。'
end
エラーが発生すると、次のようにSlackに通知が届きます。
これで、エラーが発生した際に自動でSlackに通知される仕組みが完成しました!
4. 通知フォーマットのカスタマイズ
ただし、このファイルだけでは通知内容(例外のメッセージ、リクエストのパラメータなど)をカスタマイズすることはできません。
カスタム通知の設定を追加
通知にエラーメッセージやリクエストパラメータを含めたい場合には、
ApplicationController
に次のようなコードを追加することでSlack通知の内容を自由にカスタマイズできます。
class ApplicationController < ActionController::Base
# すべての例外をキャッチして、カスタム通知を送信する
rescue_from Exception, with: :server_error
def server_error(e) # このeは、rescue_fromでキャッチされた例外が自動的に渡される
# ExceptionNotifierを使ってカスタム通知を送信
ExceptionNotifier.notify_exception(
e,
env: request.env, # リクエストの環境情報を渡す
data: {
message: "500エラーが発生しました", # 自由なメッセージ
exception_class: e.class.to_s, # エラーのクラス名
exception_message: e.message, # エラーのメッセージ
request_path: request.path, # リクエストのパス
params: request.params # リクエストのパラメータ
}
)
# 必要に応じて500エラー画面を表示
render file: "#{Rails.root}/public/500.html", status: 500
end
end
-
ApplicationController
等でrescue_from
を使って例外をキャッチし、ExceptionNotifier.notify_exception
を呼び出して通知します。 -
rescue_from
とはRailsでコントローラ内の例外をハンドリング(処理)するためのメソッドです。
エラーを発生させてみると、、、
エラーが発生した際により詳しいSlack通知を送信できるようになりました!!
5. まとめ
この記事では、Railsアプリでエラーが発生した際にSlackに自動で通知を送信する方法を紹介しました。簡単なTODOアプリに実装する形で手順を解説しましたので、実際のプロジェクトにも応用できます。
基本的な例外通知の設定は config/initializers/exception_notification.rb
で行いますが、通知の内容を細かくカスタマイズしたい場合は、ApplicationController
に例外をキャッチする処理を追加することで、より柔軟に対応できます。これで開発や運用中に発生するエラーにも、素早く対応できるようになります。
6. 参考資料