Mar 16, 2011

Log4r + Rails

There is only one way to integrate log4r with Rails.

If you do the following, you will encounter a very strange error, which is raised from "render :partial" because it cannot find outputters.

config.logger = Log4r::Logger.new("Application Log")
console_format = Log4r::PatternFormatter.new(:pattern => "%l:\t %m")
config.logger.add Log4r::StdoutOutputter.new('console', :formatter=>console_format)

file_format = Log4r::PatternFormatter.new(:pattern => "[ %d ] %l\t %m")
config.logger.add Log4r::FileOutputter.new('fileOutputter', :filename => RAILS_ROOT+"/log/"+RAILS_ENV+".log", :trunc => false, :formatter=>file_format)

config.log_level = :debug

SO DON'T DO THAT

Instead, please do this:

1. In environment.rb, put in this line:

... require File.join(File.dirname(__FILE__), 'boot')

require File.expand_path(File.dirname(__FILE__) + "/logger")

Rails::Initializer.run do |config| ...

2. Create logger.rb in config folder with these lines:

--------------------------

# Configure logging.
# We use various outputters, so require them, otherwise config chokes
require 'log4r'
require 'log4r/yamlconfigurator'
require 'log4r/outputter/fileoutputter'
require 'log4r/outputter/datefileoutputter'
require 'log4r/outputter/emailoutputter'


cfg = Log4r::YamlConfigurator
cfg['RAILS_ROOT'] = RAILS_ROOT
cfg['RAILS_ENV'] = RAILS_ENV

# load the YAML file with this
cfg.load_yaml_file("#{RAILS_ROOT}/config/log4r.yaml")
RAILS_DEFAULT_LOGGER = Log4r::Logger['default']
RAILS_DEFAULT_LOGGER.level = (RAILS_ENV == 'development' ? Log4r::DEBUG : Log4r::INFO)

if RAILS_ENV == 'test'
Log4r::Outputter['stderr'].level = Log4r::OFF
RAILS_DEFAULT_LOGGER.add( Log4r::Outputter['stderr_test'] )
end

if RAILS_ENV == 'production'
Log4r::Outputter['standardlog'].level = Log4r::OFF
Log4r::Outputter['stderr'].level = Log4r::OFF
else
Log4r::Outputter['email'].level = Log4r::OFF
end


--------------------------

3. Create log4r.yaml in config folder with these lines:


--------------------------

# *** YAML2LOG4R ***
log4r_config:
# define all loggers ...
loggers:
- name : default
level : DEBUG
additive : 'false'
trace : 'true'
outputters:
- stderr
- datefilelog
- standardlog
- email

# define all outputters (incl. formatters)
outputters:
- type : StderrOutputter
name : stderr
level : WARN
#only_at :
# - INFO
# - WARN
# - FATAL
formatter:
date_pattern: '%y%m%d %H:%M:%S'
#pattern : '%d %l: %m '
pattern : "[%l] %d :: %m"
type : PatternFormatter

- type : StderrOutputter
name : stderr_test
level : ERROR
formatter:
date_pattern: '%y%m%d %H:%M:%S'
# Added 'M' and 't' here - they are slow, but we're not calling unless we need to
pattern : "[%l] %d :: %M :: %t"
type : PatternFormatter

- type : DateFileOutputter
name : datefilelog
level : DEBUG
date_pattern: '%Y%m%d'
trunc : 'false'
dirname : "#{RAILS_ROOT}/log"
formatter :
date_pattern: '%y%m%d %H:%M:%S'
#pattern : '%d %l: %m '
pattern : "[%l] %d :: %m"
type : PatternFormatter

- type : FileOutputter
name : standardlog
level : DEBUG
trunc : 'false'
filename : "#{RAILS_ROOT}/log/#{RAILS_ENV}.log"
formatter :
date_pattern: '%y%m%d %H:%M:%S'
pattern : "[%l] %d :: %m"
type : PatternFormatter

- type : EmailOutputter
name : email
level : ERROR
server : smtp.example.com
port : '25'
#domain : smtp.example.com
authtype : none
#authtype : basic
#acct : dansketcher
#passwd : passwd
subject : 'Application Error'
from : error-handler-person@example.com
to : error-handler-person@example.com
immediate_at: "FATAL, ERROR"
formatfirst : 'true'
formatter :
date_pattern: '%y%m%d %H:%M:%S'
# Added 'M' and 't' here - they are slow, but we're not calling unless we need to
pattern : "[%l] %d :: %M :: %t"
type : PatternFormatter


--------------------------

Done !