如何让我的 Rails 应用程序的每个独角兽工作者登录到不同的文件?

Posted

技术标签:

【中文标题】如何让我的 Rails 应用程序的每个独角兽工作者登录到不同的文件?【英文标题】:How to make each unicorn worker of my Rails application log to a different file? 【发布时间】:2011-07-29 22:17:54 【问题描述】:

如何让我的 Rails 应用程序的每个独角兽工作者写入不同的日志文件?

原因:混合日志文件的问题... 在其默认配置中,Rails 会将其日志消息写入单个日志文件:log/<environment>.log

Unicorn worker 会一次写入同一个日志文件,消息可能会混淆。这是 request-log-analyzer 解析日志文件时的问题。一个例子:

Processing Controller1#action1 ...
Processing Controller2#action2 ...
Completed in 100ms...
Completed in 567ms...

在这个例子中,什么动作在 100 毫秒内完成,什么动作在 567 毫秒内完成?我们永远无法确定。

【问题讨论】:

【参考方案1】:

将此代码添加到 unicorn.rb 中的 after_fork 中:

#one log per unicorn worker
if log = Rails.logger.instance_values['log']
  ext = File.extname log.path
  new_path =log.path.gsub %r(.*)(#Regexp.escape ext), "\\1.#worker.nr\\2"
  Rails.logger.instance_eval do
    @log.close
    @log= open_log new_path, 'a+'
  end
end

【讨论】:

这个实现应该在 Rails 2.3 应用程序中工作吗?这个线程中没有人真正指定他们的代码可以在哪些版本中运行,我正试图在一个相当老的应用程序中做这个确切的事情,但不知道如何去做。【参考方案2】:

@slact 的回答不适用于 Rails 3。This works:

after_fork do |server, worker|

  # Override the default logger to use a separate log for each Unicorn worker.
  # https://github.com/rails/rails/blob/3-2-stable/railties/lib/rails/application/bootstrap.rb#L23-L49
  Rails.logger = ActiveRecord::Base.logger = ActionController::Base.logger = begin
    path = Rails.configuration.paths["log"].first
    f = File.open(path.sub(".log", "-#worker.nr.log"), "a")
    f.binmode
    f.sync = true
    logger = ActiveSupport::TaggedLogging.new(ActiveSupport::BufferedLogger.new(f))
    logger.level = ActiveSupport::BufferedLogger.const_get(Rails.configuration.log_level.to_s.upcase)
    logger
  end
end

【讨论】:

以上是关于如何让我的 Rails 应用程序的每个独角兽工作者登录到不同的文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Rails 让我的 Twitter Bot 保持清醒?

通过 nginx 流式传输来自独角兽的 rails 生成的响应

如何让我的 Rails 应用程序使用我的 postgresql 数据库?

独角兽超时处理

rails: 如何基于子域覆盖locale?

独角兽请求排队