Skip to content

Instantly share code, notes, and snippets.

@indirect
Created July 19, 2011 07:00
Show Gist options
  • Save indirect/1091527 to your computer and use it in GitHub Desktop.
Save indirect/1091527 to your computer and use it in GitHub Desktop.
Rails 3 logs with severity and PIDs
# You must require this file in application.rb, above the Application
# definition, for this to work. For example:
#
# # Syslog-like Rails logs
# if Rails.env.production?
# require File.expand_path('../../lib/better_logger', __FILE__)
# end
#
# module MyApp
# class Application < Rails::Application
require 'active_support/buffered_logger'
class BetterLogger < ActiveSupport::BufferedLogger
SEVERITIES = Severity.constants.sort_by{|c| Severity.const_get(c) }
def add(severity, message = nil, progname = nil, &block)
return if @level > severity
message = (message || (block && block.call) || progname).to_s
# Prepend pid and severity to the written message
log = "[%s] %-5.5s %s" % [$$, SEVERITIES[severity], message.gsub(/^\n+/, '')]
# If a newline is necessary then create a new message ending with a newline.
log << "\n" unless log[-1] == ?\n
buffer << log
auto_flush
message
end
class Railtie < ::Rails::Railtie
# overwrite Rails' initializer to set up our own instead
initializer :initialize_logger do |app|
Rails.logger = begin
logger = BetterLogger.new(app.config.paths.log.to_a.first)
level_name = app.config.log_level.to_s.upcase
logger.level = ActiveSupport::BufferedLogger.const_get(level_name)
logger.auto_flushing = false if Rails.env.production?
logger
end
ActiveSupport::Dependencies.logger = Rails.logger
# cache has no callback of its own, but is set before this callback
ActiveSupport.on_load(:before_initialize) do
Rails.cache.logger = Rails.logger
end
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.logger = Rails.logger
end
ActiveSupport.on_load(:action_controller) do
ActionController::Base.logger = Rails.logger
end
ActiveSupport.on_load(:action_mailer) do
ActionMailer::Base.logger = Rails.logger
end
end
end
end
@indirect
Copy link
Author

Ahh, that makes sense. I've updated to include a newline before the PID if the logged message starts with a newline. :)

@chaffeqa
Copy link

Couldnt you eliminate a bunch of the code by just overriding the add() method in an initializer?

Something like:

class Railtie < ::Rails::Railtie
    initializer "swap in PidLogger" do
      module ActiveSupport
         class BufferedLogger
            def add(severity, message = nil, progname = nil, &block)
               return if @level > severity
               message = (message || (block && block.call) || progname).to_s
               # Insert a newline before the log line if there was one in the first place.
               log = (message[0] == ?\n) ? "\n" : ""
               # Prepend pid and severity to the written message
               log << "[#{$$}] #{SEVERITIES[severity]} #{message.gsub(/^\n+/, '')}"
               # If a newline is necessary then end with a newline.
               log << "\n" unless log[-1] == ?\n
               buffer << log
              auto_flush
              log
            end
        end
    end
 end

@indirect
Copy link
Author

indirect commented Nov 19, 2011 via email

@edzhelyov
Copy link

Hi man,

I forked your code, but instead of recreating everything that is done in the method and the initializer I just extend the actual logger object.
Pretty neat solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment