Ruby on Rails3で作成したアプリをHeroku上で動かす際のエラー処理についてのまとめです。
環境はruby-1.9.3-p0, rails3.2.2, postgres, Herokuです。
難易度★★★☆☆
はじめに
この記事はHeroku上で動くアプリのエラーをどう扱うかを試行錯誤したまとめです。正直、あまり良い方法とは思えなかったのですが、現在は記事の内容で対応しています。
対応方法
アプリに例外が発生したらエラーのメールを投げることでエラーを管理者が確認できるようにしました。
exceptional_notificationというpluginが例外を自動キャッチしてメールを投げてくれるのですが、私のアプリは独自処理で例外をキャッチしていたのでexceptional_notificationを使用できませんでした。なので、自分で実装することになりました。
詳細
Heroku
Herokuは,Ruby on Rails/RubyのWebサービスのホスティングサービスです。無料で手軽にWEBサービスを構築することができ、アプリケーションの負荷が高くなれば有料にすることもできます。
小さくはじめるスタートアップに非常に向いているサービスです。
Herokuログ
Herokuのlogはターミナルから「heroku logs」で確認できます。logの内容はproduction.logです。
Herokuログの問題点
log rotateができません。なのにアプリが動作している限りログは追記されていくので、後でエラーの原因を調査しようと思っても、ログを追うことができません。
エラー処理仕様
- 例外はキャッチして独自のエラーページを使用する。しかし、例外を独自処理でキャッチした場合exceptional_notificationは使えない。
- exceptional_notificationのようにエラー発生時にメールを送りたい。でも、独自で例外を補足したい。
- 有料のadd-onやサービスは利用したくない。なるべく無料が良い。
- 無料のheroku logsだけでは不安である。エラーは発生時に知りたい。
我がまま過ぎるって?でも、そんなもんです人間は。金がないなら知識と技術で解決しましょう。さあ実装です。
Gmailを使う
エラーメッセージのお知らせにはgmailを利用します。無料で一日500件まで使えます。500件以上利用する場合は、あきらめてメールサーバーを立てるか有料サービスを使いましょう。サービス立ち上げ時には十分な件数のはずです。
/config/environments/production.rbに設定を記載します。
config.action_mailer.default_url_options = { :host => 'your_app.heroku.com' } config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => 'smtp.gmail.com', :port => 587, :domain => 'your.host.name', # if local, localhost.localdomain :user_name => "your_username", # full email address (user@your.host.name.com) :password => "your_password", :authentication => 'plain', :enable_starttls_auto => true, }
開発環境でも利用したい場合は/config/environments/development.rbにコピーしてください。
GmailでIMAPが利用できるように設定されていることも確認してください。
GmailでIMAPを有効化にする
mailerを作成
rails g mailer TestMailer sendmail_confirm
メーラーを作成します。作成されたコントローラー/app/mailers/test_mailer.rbに処理を記述します。
class TestMailer < ActionMailer::Base default :from => 'full email address' # Subject can be set in your I18n file at config/locales/en.yml # with the following lookup: # # en.notice_mailer.sendmail_confirm.subject # def sendmail_confirm(exception) @exception = exception mail :to => "send_email_address", :subject => '[Web application Error]' end end
sendmail_confirmアクションは引数で例外を受け取っています。
mailメソッドを呼び出すタイミングで、テンプレートtest_mailer/sendmail_confirm.text.erbが呼び出されます。
text.erbには、メールの内容を記述します。
text.erbを作成
エラーが発生しました、 <%= @exception.message %>
エラーの内容を出力するようにしています。他にも欲しい情報があれば、ここに記述します。
独自エラー処理に追加
独自エラー処理はapplication_controller.rbで処理するのが一般的です。なので、ここに作成したメール処理を追加します。
# 例外ハンドル # ルーティングエラーと、データが見つからない場合は404エラー扱い rescue_from ActionController::RoutingError, ActiveRecord::RecordNotFound, :with => :render_404 rescue_from Exception, :with => :render_500 # 404エラーはログを取りエラー画面を表示 def render_404(exception = nil) if exception logger.info "Rendering 404 with exception: #{exception.message}" end flash[:msg] = 'ページは見つかりませんでした。' render 'shared/error' , :status => 404 end # 500エラーはログを取りエラー画面を表示 def render_500(exception = nil) if exception NoticeMailer.sendmail_confirm(exception).deliver end flash[:msg] = 'サーバーエラーが発生しました。' render 'shared/error', :status => 500 # statusがないとcompleted OKになってしまう。 end
赤い太文字の箇所が追加した処理です。メールでエラーを投げて、独自のエラー画面に遷移するようにしています。
ユーザーは大きな不具合以外は意外と報告してくれないので、メールでエラーが送信される仕組みはあると便利だと思います。
以上です。
参考サイト
0 件のコメント:
コメントを投稿