この記事で扱うrailsのバージョン
rails 7.0.4.2
ログのローテーションがうまくいかない
rubyのLoggerクラスでログのローテーションを設定したところ、
なぜかログがローテーション後のログファイルに吐き出されていた15:04 production.log
17:42 production.log.20241111 <- こちらのファイルにログが吐き出されていた
ログの設定はこんな感じ
Rails.application.configure do
~~~
# 日数でローテート
config.logger = Logger.new("log/production.log", "daily")
~~~
end
No such file or directory @ rb_sysopen - log/production.log
がエラーとして出力されていたため出力先の設定を絶対パスにしたところ解決
修正後の設定ファイルRails.application.configure do
~~~
# 日数でローテート
config.logger = Logger.new(Rails.root.join("log/production.log"), "daily")
~~~
end
めでたしめでたし
ところで
絶対パスとするべきところを相対パスにするという初歩的なミスが原因でローテションがうまくいっていなかったわけですが、ログ自体は吐き出されているのに、なぜローテーションの時だけ No such file or ~
になってしまうのかがよくわからなかったので少し調査してみました
犯人は Process.daemon
アプリをバックグラウンドで起動するために -d
オプションをrailsコマンドにつけてデーモン化していたのですが、これが原因でした
raisコマンドに-dをオプションで渡すと、daemonize_appが呼び出されるのですが、Prodess.daemonを引数なしで呼び出しています
def daemonize_app
# Cannot be covered as it forks
# :nocov:
Process.daemon
# :nocov:
end
daemon(nochdir = nil, noclose = nil) -> 0
プロセスから制御端末を切り離し、バックグラウンドにまわってデーモンとして動作させます。
カレントディレクトリを / に移動します。ただし nochdir に真を指定したときにはこの動作は抑制され、カレントディレクトリは移動しません。
https://docs.ruby-lang.org/ja/latest/method/Process/m/daemon.html
rubyのProcess.daemonは引数なしで呼び出すと、プロセスのカレントディレクトリを / に移動するようです
ログの初期化時は実行ディレクトリがカレントディレクトリなので相対パスでも問題ないが、デーモン化したタイミングで / に切り替わっていたため、ローテーションの時には相対パスだとログファイルが見つからないと怒られていたわけでした(ちなみに7.1以降のrailsではカレントディレクトリは移動しないようになっています)def daemonize_app
# Cannot be covered as it forks
# :nocov:
Process.daemon(true, options[:daemonize] == :noclose)
# :nocov:
end
コメント