Passenger5系でRailsのログローテートを行う

Railsのログローテト、Rails側でやるのか logrotated でやるのかというざっくり2パターンありますが、 個人的にはlogrotatedでやることが多いです。
久しぶりにPassengerを触ったので、最近のPassengerではどうするのが良いのだろうかと調べてみました。

公式ドキュメント

Log rotation - Nginx - Passenger Library を見てみると
 
ログは以下の3種類があると。

  1. The Nginx webserver log files.
  2. The Passenger log files.
  3. The application log files.

で、nginx webserverとpassengerのログローテート時には
以下のようにログの再読み込みをさせるか

$ passenger-config reopen-logs

もしくは pipetool という謎のsignalをいい感じで送ってくれそうなやつを使えとのこと。
 
 
また、application logのローテート時には再起動かましとけと書いてあります。
(ここはsignal投げるでも良いのかもしれません。)

$ passenger-config restart-app <path to app>

やってみる

nginx

nginx のpostrotateのみ抜粋。
lotate後にnginxとpassengerのログファイルの再読み込みを行うようにしています。

# /etc/logrotate.d/nginx
    postrotate
    [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
    passenger-config reopen-logs
    endscript

rails

railsのpostrotateのみ抜粋。

# /etc/logrotate.d/rails
    postrotate
        passenger-config restart-app /
    endscript

アプリの再起動を行なっていますが、最後の引数が/にしています。
/の場合、現在起動している全アプリを再起動してくれるようです。
Restarting applications - Nginx - Passenger Library

余談:passenger-config reopen-logs について調べてみる

passenger-config というもので色々できるようになっているようなので、reopen-logs周りのソースを眺めて見ました。
(passengerはrpmで入れています。さらに余談だけど、最新版の提供が追いついていないのでrpmで入れたのは失敗かもと思い始めました。)

passenger-config

$ less `which passenger-config`
require '/usr/lib/ruby/1.8/phusion_passenger'

PhusionPassenger.locate_directories
PhusionPassenger.require_passenger_lib 'config/main'
PhusionPassenger::Config.run!(ARGV)

ふむふむ関連ファイルの読み込みを行なって、run! してますね。

config/main.rb

/usr/lib/ruby/1.8/phusion_passenger/config/main.rb

なるほど、サブコマンドとクラスのmappingが定義されています。

module PhusionPassenger
  module Config
    KNOWN_COMMANDS = [
        略
      ["reopen-logs", "ReopenLogsCommand"],
        略      

ありました run!
サブコマンドのclassをnewしてrunしてますね。

    def self.run!(argv)
      command_class, new_argv = lookup_command_class_by_argv(argv)
      if help_requested?(argv)
        help
      elsif help_all_requested?(argv)
        help(true)
      elsif command_class
        command = command_class.new(new_argv)    # <= ここ
        command.run
      else
        help
        abort
      end
    end

config/reopen_logs_command.rb

/usr/lib/ruby/1.8/phusion_passenger/config/reopen_logs_command.rb

perform_reopen_logs をcallしています。

      def run
        parse_options
        select_passenger_instance
        perform_reopen_logs    # <= ここ
      end

次はperform_reopen_logs を見て見ます。
なんだろう?watchdog?
ググってみると Phusion Passengerの設計と構造
log監視を行うモジュールのようです。ちなみに ps叩くと Passenger watchdog という名前のprocessが上がっています。

      def perform_reopen_logs
        perform_reopen_logs_on("watchdog", "watchdog_api")    # <= ここ
        perform_reinherit_logs_on("core", "core_api")
        perform_reinherit_logs_on("UstRouter", "ust_router_api")
        if using_standalone_nginx_engine?
          perform_reopen_logs_on_nginx    # <= standalone nginxの場合はシグナル投げてます
        end
        puts "All done"
      end

次はperform_reopen_logs_on。

      def perform_reopen_logs_on(name, socket_name)
        puts "Reopening logs for #{PROGRAM_NAME} #{name}"
        request = Net::HTTP::Post.new("/reopen_logs.json")
        try_performing_full_admin_basic_auth(request, @instance)
        request.content_type = "application/json"
        response = @instance.http_request("agents.s/#{socket_name}", request)

ふむふむ。どうやら /reopen_logs.json にPOSTすることでrestartする仕組みのようです。
ここから先は、おそらくrubyではない(C++)と思われるので、一旦ここまで。
passengerも結構変わりましたね。