Rails で、エラーが出たときにメールが送信されるようにしました。
環境
- Ubuntu 15.05 (64bit)
- Ruby 2.2.2
- Rails 4.1.8
昔のやり方
Rails 3 のときは、 ApplicationController
で rescue_in_public
にメール送信のコードを見たことがあります。
|
class ApplicationController < ActionController::Base protected def rescue_action_in_public(exception) SystemMailer.system_error( current_user, self, request, exception).deliver super(exception) end def local_request? false end end |
current_user
は ログインしているユーザです。 devise
を利用しています。
しかし同じことをやっても意図した通りにメールは送信されませんでした。
解決法
Rails 3 のときにもあった rescue_from
を使いました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class ApplicationController < ActionController::Base rescue_from Exception, :handle_exception private # handle exception # ==== Parameter # * +exception+ def handle_exception(exception) send_error_mail(exception) raise exception end # send error mail # ==== Parameter # * +exception+ def send_error_mail(exception) if !Rails.env.development? SystemMailer.error_mail( exception, current_user, self, request) end end end |
rescue_from Exception
とすることで、コントローラ内の処理で発生したすべての例外を拾います。 これが rescue_from StandardError
だと 単純に raise "exception!"
のように例外を起こしたときの RuntimeError
が拾えません。 また、0 = 1
の時に起きるような syntax error は拾いません。 拾うのはプログラムとして動いた上でのエラーです。 そして、コントローラに入る前の処理は拾いません。
重要なのは handle_exception
の中の raise exception
です。 handle_exception
ではエラーをもみ消したいわけではなく、メールを送りたいだけです。 AOP の考え方です。 今回は簡易的に application_controller.rb
にメソッドを追加しています。
send_error_mail
の中で使われている current_user
は gem devise で用意されているもので、ログインしているユーザを返します。 適宜変更してください。 self
はどのコントローラで例外が発生したのかをメールに載せるために渡しています。 request
はリクエストのURLなどを表示するのに使います。 また !Rails.env.development?
で評価を行っているところがありますが、 config
に書くようにできれば一番いいです。 Rails 4.2 になったらカスタムコンフィギュレーションが使えるそうなので、アップグレード後の課題としました。
注意点
コントローラに入った後の例外しか処理しないので、 コントローラに移る前の例外は別の方法で補足する必要があります。
それならばコントローラの中ではなく外側で例外処理を書けばいいという考え方もあるのですが、コントローラの中でしか参照できない値や、コントローラの中で使いやすくなっているオブジェクトなどがあるので、 applicatoin_controller.rb
に処理を書きました。
続きを読む Rails 4 メールでのエラー通知 →
Rails でシンプルにログローテーションする方法です。
環境
- Rails 4.1.8
- Ruby 2.2.2
- Ubuntu 15.04 (64bit)
設定
Rails の config/application.rb
に次の記述を追加します。
|
# configure log rotation # split log by 100MB, limit log file count up to 10 config.logger = Logger.new( "#{Rails.root}/log/#{Rails.env}.log", 10, 104857600) |
ここでは 100 MB (104,857,600 バイト) で 最大 10 ファイル まで保存するようにしています。 要するに 1 GB までログを保存する。 また、 10 ファイル を超えると、古いものから削除されていきます。
Rails の標準では daily, weekly などのログの設定方法もありますが、その場合は古いログファイルは削除されません。
テスト方法
例えば development 環境 でテストする場合、 次のコマンドで 100 MB を超えるログファイルをあらかじめ作成しておく。
|
dd if=/dev/zero of=log/development.log bs=1M count=100 |
bs
はブロックサイズ、count
は書き込み回数を表しています。
そこで、 rails s
のコマンドでサーバを起動して、 どこかのページにアクセスします。 すると、 development.log
, development.log.0
ができているはずです。
Rails のロギングは、 SyslogLogger
や Linux の logrotate を使う方法もあります。
Magnum CI は 無料で使える CI 環境で、 きっと愛用している人も多いと思います。 本記事では、 Bitbucket で管理している Rails のコードを、 Magnum CI でテストした時のメモを書いておきます。
続きを読む Magnum CI で Rails をテストした方法 →
事情があってとても古いマシン(Let’s Note CF-W2)に Lubuntu をインストールしようとしたとき、次のメッセージが表示されました。
|
This kernel requires the following features not present on the CPU: pae Unable to boot - please use a kernel appropriate for your CPU. |
Let’s Note CF-W2 のスペックは次の通りです。
環境
スペック
- CPU: Intel Pemtium M 32bit 1GHz
- RAM: 1GB
インストールするISO
- lubuntu-14.04.3-desktop-i386.iso
原因
メッセージを見ると、 64bit のイメージをインストールしてしまったか? と思ってしまうのですが、 32bit のイメージで上のメッセージが出ます。
原因は Intel Pentium M プロセッサ が PAE をサポートしていないことでした。
PAE
32bit CPU で 4GB 以上 のメモリを扱えるようにする技術で、 Intel だけでなく AMD でも採用されている CPU があります。
解決策
私がとった解決策は次の方法です。 Ubuntu の forcepae オプション を使います。
- DVD から起動します。
- 言語を選択します。
- 次に F6 キー を押し、 ESC キー を押します。 F6 でオプションが表示されるのですが、特に設定しません。
- こうすることで、 次のようなブートコマンドが表示されます。
|
Boot Options file=/cdrom/preseed/ubuntu.seed boot=casper initrd=/casper/initrd.lz quiet splash -- |
- そして Install をカーソルで選びます。
- 表示されているコマンドの最後の部分を次のように変更します。 forcepae を 2箇所に書きます。
|
Boot Options file=/cdrom/preseed/ubuntu.seed boot=casper initrd=/casper/initrd.lz quiet splash forcepae -- forcepae |
- 最初のパラメータはインストーラから実行されるカーネルのオプション、後ろのパラメータはインストールされた後のカーネルのオプションです。
これで動くようになりました。
下のサイトでは上の方法の他にもいくつか方法が紹介されています。
参考: How can I install on a non-PAE CPU?
サッカーボールで使われている 5角形と6角形 の数を計算する では サッカーボールに使われている 5角形と6角形 の数を計算しました。 ここではその面の数について、別の方面から考えてみます。 オイラーの定理は使いません。
6角形の中心を結ぶ
サッカーボールにある6角形の中心を頂点とする多面体を考えます。 その多面体は1つの面が正5角形になり、また正5角形だけからなる立体です。 これは正12面体になりますね。
正12面体の面の数は、サッカーボールに含まれる正5角形の数と同じになります。 これよりサッカーボールの正5角形は12個とわかります。
正12面体の頂点の数は、正6角形の数と同じになります。 頂点の数は ( 5 times 12 div 3 = 20 ) です。
これよりサッカーボールの面の数は
[ 12 + 20 = 32 ] です。
サッカーボールの辺の数は、5角形と6角形の辺の数を足して、重複を取り除くことで
[ ( 5 times 12 + 6 times 20 ) div 2 = 90 ] と計算できます。
サッカーボールの頂点の数は、1つの頂点を3つの図形で共有していることから
[ ( 5 times 12 + 6 times 20 ) div 3 = 60 ] と計算できます。
正6角形の中心を頂点として多面体を考えましたが、5角形の中心を頂点として考えることもできます。
5角形の中心を結ぶ
サッカーボールにある5角形の中心を頂点とする多面体は正20面体になります。 作り方から考えてわかりますが、これは上で見た正12面体の面の中心を頂点とした多面体と同じです。
切頂多面体
正20面体の頂点を切ってみましょう。
正20面体の頂点を切ると、サッカーボールの形になります。 この頂点を切った正20面体のことを、切頂正20面体または切頭正20面体と呼びます。
正12面体も頂点を切ることでサッカーボールの形にできますが、深く切る必要があります。
A Life Summary of an Gypsy