Sinatraのloggerヘルパーを使ったところ、なぜか標準エラーの出力先にログが吐かれており、標準出力の出力先にはログが吐かれない。
標準出力先にログを吐くものだと思っていたのだが、自分が想定していた挙動と違うので調べてみた。
まずは、Sinatraのloggerヘルパーのソースコードを確認してみる。
1 | def logger |
request.loggerを返している。
レシーバであるrequestは rack::requestなので、rack::request#loggerは何を返しているかを確認する。
1 | def logger; get_header(RACK_LOGGER) end |
https://github.com/rack/rack/blob/master/lib/rack/request.rb#L136
get_headerは@envから引数に与えられた値を返すだけのメソッド。
1 | def get_header(name) |
RACK_LOGGERは以下のように定義されている。
1 | RACK_LOGGER = 'rack.logger'.freeze |
https://github.com/rack/rack/blob/9073125f71afd615091f575d74ec468a0b1b79bf/lib/rack.rb#L64
ここまでで、loggerヘルパーはenv['rack.logger’]
を取得していることがわかった。
では、rack.loggerには何が設定されているのかという疑問が湧いてくる。
rackには3つのロガーがある。
- CommonLogger
- Logger
- NullLogger
このうち、LoggerとNullLoggerがRACK_LOGGERにセットしていた。
1 | # Rack::Logger |
通常、Rack::Loggerが使われる。
Rack::LoggerはRubyのloggerライブラリのラッパーで、log deviceにenv[RACK_ERRORS]をセットしている。
env[RACK_ERRORS]が何かを調べたところ、基本的には$stderrがセットされるようだ。
(例)webrickの場合は、$stderrがセットされている。
1 | env.update( |
ということで、結果的にSinatraのloggerは標準エラーに出力されることになる。
アプリケーションログを任意のファイルに出力するには
任意のファイルにログを出力したい場合は、自前でloggerを定義してやればよい。
1 | def logger |