问题
How can I make each unicorn worker of my Rails application writting in a different log file ?
The why : problem of mixed log files...
In its default configuration, Rails will write its log messages to a single log file: log/<environment>.log
.
Unicorn workers will write to the same log file at once, the messages can get mixed up. This is a problem when request-log-analyzer parses a log file. An example:
Processing Controller1#action1 ...
Processing Controller2#action2 ...
Completed in 100ms...
Completed in 567ms...
In this example, what action was completed in 100ms, and what action in 567 ms? We can never be sure.
回答1:
add this code to after_fork in unicorn.rb:
#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
回答2:
@slact's answer doesn't work on 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
来源:https://stackoverflow.com/questions/5551660/how-to-make-each-unicorn-worker-of-my-rails-application-log-to-a-different-file