Programming Journal

学習したことの整理用です。

エラー発生時にslackへ通知する

実装の流れ

  • gem Slack-notifier, Exception Notification導入
  • slack通知の設定
  • エラーハンドリングの設定

細かい設定については参考にしたブログが詳しいので、自分が理解しにくかった部分だけメモしていきます。
Rubyの文法が難しい。基礎力のなさを感じるので復習します。

gem

slack_notifier
GitHub - stevenosloan/slack-notifier: A simple wrapper for posting to slack channels

exception_notification
https://smartinez87.github.io/exception_notification/

exception_notificationの挙動

rack middlewareとして使われるので、configに設定さえしておけば、エラー時に勝手に呼び出される

※これが最初分からなくて、メソッドもないし、どう呼び出せばいいか悩んだ。

slack通知設定

Run 'rails generate exception_notification:install' to create

rails generate exception_notification:install

こちらのファイルが生成されるので、通知したいslackの情報を記述する。

if Rails.env.production? #本番環境のときだけ通知がいくようにする。
  require 'exception_notification/rails'

  ExceptionNotification.configure do |config|
    config.add_notifier :slack,
                        webhook_url: Rails.application.credentials.secret_url, #後述
                        channel: '#channel' #通知したいチャンネル名
  end
end

credentials.yaml.encの編集

先のwebhook_url: Rails.application.credentials.secret_url,については、credentials.yml.encで設定した値を読み込んでいます。
webhook_urlを直接記述してしまうとセキュリティ上NGなので、秘密の文字列はこちらのファイルに記述します。

webhook_urlの取得方法についても下記ブログが分りやすかった。 ターミナルでEDITOR=vim bin/rails credentials:editを入力すると編集モードになります。
エディターでは編集できないので、ターミナル上で編集します。 vim操作が分からなかった。
iで文字を挿入できるようにして、webhook_urlを記述したら、escキーと:wqで保存して終了。

f:id:Study-Diary:20200909133722p:plain
credentials.yaml.enc

コンソールでRails.application.credentials.secret_urlが機能しているか確認

f:id:Study-Diary:20200909133823p:plain
コンソール

エラーハンドリング設定

アプリケーションで例外が発生したときの対応を記述する。

class ApplicationController < ActionController::Base
  rescue_from StandardError, with: :render_500
  rescue_from ActiveRecord::RecordNotFound, with: :render_404

  def render_404
    render file: Rails.root.join('public/404.html'), status: :not_found, layout: false, content_type: 'text/html'
  end

  def render_500(error)
    logger.error(error.message)
    logger.error(error.backtrace.join("\n"))
    render file: Rails.root.join('public/500.html'), status: :internal_server_error, layout: false, content_type: 'text/html'
  end
end
Rails.root.joinって…?

Rails.rootメソッドでPathnameオブジェクトを返す。 Rails.root.joinを使うと簡潔にファイルパス(ファイルやフォルダの置いてある場所のこと)を取得できる

Rails Root directory path? - Stack Overflow

Pathnameってなんじゃらほい - Qiita

Rails.root.join("foo", "bar")よりも、Rails.root.join("foo/bar")が良いのでは?というお話 - Qiita

Pathnameとは

パス名をオブジェクト指向らしく扱うクラスです。

Pathname オブジェクトはパス名を表しており、ファイルやディレクトリそのものを表してはいません。 当然、存在しないファイルのパス名も扱えます。

絶対パス相対パスも扱えます。

class Pathname (Ruby 2.2.0)

Pathname#joinは単純に複数の文字列を連結しているだけではない、という話 - Qiita

他の分かりにくかったコード

join("\n") 改行\nを使って文字列に連結joinしている。

logger

ログを記録するためのクラスです。

logger.error で、ERROR 情報を出力します。
class Logger (Ruby 2.7.0 リファレンスマニュアル)

Rails アプリケーションのデバッグ - Railsガイド

renderのオプション

:content_typeオプション/Railsがデフォルトで出力する結果のMIME content-typeは、デフォルトでtext/htmlになります

render layout: false/ 出力時にレイアウトをまったく使用しないよう指定することもできます。

:statusオプションを使用することで、レスポンスのステータスコードを変更できます。

レイアウトとレンダリング - Railsガイド

エラー

application controllerの private内に記述してしまって、反映しなかった。

参考にしたもの

『パーフェクトRuby on Rails』 P400-405
『プロを目指す人のためのRuby入門』9章

例外設計について
Railsアプリケーションにおけるエラー処理(例外設計)の考え方 - Qiita

exception_notification をslackで使うには
exception_notification/slack.md at master · smartinez87/exception_notification · GitHub

credential.yml の編集方法について(vim操作)
たった30分でわかるcredentials.yml.enc[rails5.2] - 環境変数を定義する使い方 - - Qiita

Vimの操作について(credential.yml編集時に使う)
Vim / Vi を終了させる方法 - Qiita

505エラー時にslackに通知する
【Rails】500番エラーをslack通知する - Qiita

Railsでエラーのslack通知を実装 | Boys Be Engineer 非エンジニアよ、エンジニアになれ