Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make each unicorn worker of my Rails application log to a different file?

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.

like image 243
Nicolas De Nayer Avatar asked Apr 05 '11 12:04

Nicolas De Nayer


People also ask

Where are Rails logs stored?

In a Rails app, logs are stored under the /log folder.

What is Unicorn Rails?

Unicorn is an application server, like Passenger or Puma, that enables your Rails application to process requests concurrently. As Unicorn is not designed to be accessed by users directly, we will use Nginx as a reverse proxy that will buffer requests and responses between users and your Rails application.

How do you write logs in Rails?

To write in the current log use the logger. (debug|info|warn|error|fatal|unknown) method from within a controller, model, or mailer: logger. debug "Person attributes hash: #{@person.

What is Unicorn Heroku?

Unicorn is a Rack HTTP server that uses forked processes to handle multiple incoming requests concurrently.


2 Answers

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
like image 108
slact Avatar answered Oct 07 '22 23:10

slact


@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
like image 35
mahemoff Avatar answered Oct 07 '22 23:10

mahemoff