首页 > 解决方案 > 运行守护进程时 Puma 不记录

问题描述

当 Puma 作为守护进程运行时(即使用-d标志),Puma 似乎没有登录到stdout_redirect.

之前有没有人看到过这种行为,如果有的话,找到了一种解决方法来为 Puma 生成正确的日志文件(特别是stdout_redirect在适当的位置,特别是对于 Ruby on Rails 应用程序)?

标签: ruby-on-railsloggingpumapuma-dev

解决方案


不工作的原因stdout_redirect是因为config/puma.rb你运行时永远不会运行rails server -d。您可以通过更改端口号甚至在文件中引入语法错误来证明这一点。

Puma 作为 Rack 服务器运行,因此由 Rack 中间件启动。Rack 代码只是使用核心 RubyProcess类来分离进程:

def daemonize_app
  Process.daemon
end

不幸的是,Process.daemon默认情况下会做两件事:

  1. 将当前工作目录更改为根目录 ('/')。
  2. 将 stdout 和 stderr 重定向到/dev/null.

因此,当 Puma 服务器初始化时,所有进程输出都被分箱,并且由于/config/puma.rb不存在,puma 回退到其硬编码的默认设置。

如果您暂时破解rack代码以覆盖 chdir 行为,您实际上可以演示您想要的行为:

def daemonize_app
  Process.daemon(true)
end

如果第一个参数.daemontrue它不会更改当前工作目录,因此config/puma.rb会运行。

缺少某种丑陋的猴子补丁到 Rack,一个(可能也是丑陋的)解决方法是跳过该-d选项并在config/puma.rb. 例如:

# ... rest of the puma config

return unless ENV['DAEMONIZE_PUMA'].present?

puts 'Running puma as a daemon...'
Process.daemon(true)

然后:

% export DAEMONIZE_PUMA=true
% rails server
=> Booting Puma
=> Rails 6.1.4 application starting in development
=> Run `bin/rails server --help` for more startup options
Running puma as a daemon...
% tail log/puma.out
=== puma startup: 2021-07-17 10:03:37 +1200 ===

推荐阅读