- blogs:
- cles::blog
2009/05/09

予期しない例外でRubyが落ちたときのログを取る

最近、Rubyでバッチを書いているのですが、予期しないエラーでスクリプトが落ちるとスタックトレースがコンソールにだけ出力されてしまうという現象にちょっと頭を悩ませていました。自分だけがバッチを起動させるなら標準出力をファイルにリダイレクトしておけばいいのですが、自分がさわらないときにだけ落ちるという謎な挙動なのです。
ということで、Rubyの終了処理の部分に何かフックのようなものがないのかなと探してみたらRubyの終了処理のフックはいろいろ種類があるようです。
1. すべてのスレッドを Thread.kill
2. Ruby の疑似シグナル SIGEXIT のハンドラが登録されていればそれを実行
3. END ブロック(END { ... } または関数 at_exit で指定したブロック)が登録されていれば、 そのブロックを登録とは逆順に実行
4. ObjectSpace.define_finalizer により、ファイナ ライザが登録されていればそれらを実行(順序不定)
5. exit(3) により終了
今回のパターンであれば、2の疑似シグナル(SIGEXIT)に対するハンドラを登録するか、3のENDもしくはat_exitによるブロックを登録するかいずれかの方法が良さそうです。
† サンプルコード
コードを書くとすればこんな感じでしょうか。
fatallogtest.rb
#!/usr/bin/ruby
STDOUT.reopen "/dev/null"
STDERR.reopen "/dev/null"
require 'logger'
logger = Logger.new('app.log')
Signal.trap(:EXIT){
logger.fatal($!) if $!
}
raise "hoge"
実行すると、標準出力と標準エラーを捨てているので、画面には何も表示されませんが下記のようにログにはエラーの内容が記録されています。
app.log
# Logfile created on Sat May 9 22:32:20 +0900 2009 by logger.rb/1.5.2.9
F, [2009-05-09T22:32:20.152512 #20121] FATAL -- : hoge (RuntimeError)
test.rb:13
ただ、この実装だとexit()を使ったときにもexit (SystemExit)のようなログが残ってしまうので、本当に例外だけを拾うには$!の内容をもう少しチェックする必要がありそうです。僕は気にしないという解決方法をとってしまいましたけど。
トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3034
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
サイト内検索
検索ワードランキング
へぇが多いエントリ
閲覧数が多いエントリ
1 . アーロンチェアのポスチャーフィットを修理(112139)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110782)
3 . 年次の人間ドックへ(110377)
4 . 2023 年分の確定申告完了!(1つめ)(109924)
5 . 三菱鉛筆がラミーを買収(109823)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110782)
3 . 年次の人間ドックへ(110377)
4 . 2023 年分の確定申告完了!(1つめ)(109924)
5 . 三菱鉛筆がラミーを買収(109823)
cles::blogについて
Referrers