Search code examples
ruby-on-railsruby-on-rails-3log4r

How to configure Log4r with Rails 3.0.x?


I tried configuring log4r with Rails 3.0.4 based on this article: http://www.dansketcher.com/2007/06/16/integrating-log4r-and-ruby-on-rails/

/Users/toto/.rvm/gems/ruby-1.9.2-p0/gems/log4r-1.1.9/lib/log4r/yamlconfigurator.rb:166:in `sub!': can't convert Pathname into String (TypeError)
    from /Users/toto/.rvm/gems/ruby-1.9.2-p0/gems/log4r-1.1.9/lib/log4r/yamlconfigurator.rb:166:in `block in paramsub'
    from /Users/toto/.rvm/gems/ruby-1.9.2-p0/gems/log4r-1.1.9/lib/log4r/yamlconfigurator.rb:165:in `each'
    from /Users/toto/.rvm/gems/ruby-1.9.2-p0/gems/log4r-1.1.9/lib/log4r/yamlconfigurator.rb:165:in `paramsub'
    from /Users/toto/.rvm/gems/ruby-1.9.2-p0/gems/log4r-1.1.9/lib/log4r/yamlconfigurator.rb:156:in `block in decode_hash_params'

I have Googled for a Rails 3 integration, but have not found a working solution. Can anyone point me to a working code snippet that will allow log configuration using a YAML file, and initialization at runtime?

Just as a reference, I placed the sample logger.rb in the config/initializers folder and the log4r.yml in the config directory.

Thanks


Solution

  • Hehe ...The idea of Log4r comes from the famous "Log4j", which is my favorite logger in my java programming life. However log4r's doc is really poor, and it's really hard for newbies. Let me show my solution:

    Step1. create the log4r config file: (file name: config/log4r.yml)

    log4r_config:
      # define all loggers ...
      loggers:
        - name      : production
          level     : WARN
          trace     : 'false'
          outputters :
          - datefile
        - name      : development
          level     : DEBUG
          trace     : 'true'
          outputters :
          - datefile
    
      # define all outputters (incl. formatters)
      outputters:
      - type: DateFileOutputter
        name: datefile
        dirname: "log"
        # notice the file extension is needed! 
        # if you want the file is named by the process, just comment it,
        # then it will automatically get the same name with its process,
        # e.g.  rails_2017-05-03.log
        filename: "my_app.log" 
        formatter:
          date_pattern: '%H:%M:%S'
          pattern     : '%d %l: %m '
          type        : PatternFormatter
    

    step2. modify config/application.rb

    require 'rails/all'
    # add these line for log4r
    require 'log4r'
    require 'log4r/yamlconfigurator'
    require 'log4r/outputter/datefileoutputter'
    include Log4r
    
    Bundler.require(:default, Rails.env) if defined?(Bundler)
    module Zurich
      class Application < Rails::Application
        #...
        # assign log4r's logger as rails' logger.
        log4r_config= YAML.load_file(File.join(File.dirname(__FILE__),"log4r.yml"))
        YamlConfigurator.decode_yaml( log4r_config['log4r_config'] )
        config.logger = Log4r::Logger[Rails.env]
      end
    end
    

    step3. add this line to your Gemfile.

    # which is the latest version and support "datefileoutputter"
    gem 'log4r', '1.1.9'  
    

    (if you are using Rails 4+ (including Rails6), there still is step4: add this file to config/initializers folder

    # config/initializers/log4r_patch_for_rails4.rb
    class Log4r::Logger
      def formatter()       # for rails4+
        Proc.new{|severity, time, progname, msg|
          formatted_severity = sprintf("%-5s",severity.to_s)
          formatted_time = time.strftime("%Y-%m-%d %H:%M:%S")
          "[#{formatted_severity} #{formatted_time} #{$$}]\n #{msg}\n"
        }
    
      end
      def formatter= temp   # for rails6+
      end
    end  
    

    )

    It's done. Now "cd" into your Rails application folder, run "bundle" to install log4r, then "rails s", you will find the log files in "/log" folder like this:

    May  9 17:05 rails_2011-05-09.log
    May 10 13:42 rails_2011-05-10.log
    

    and the log content is( my favorite format ) :

    $ tail log/rails_2011-05-10.log
    Started GET "/????_settings/19/edit" for 127.0.0.1 at ...
    13:42:11 INFO:   Processing by ????SettingsController ...
    13:42:11 INFO:   Parameters: {"id"=>"19"}
    13:42:12 DEBUG:   ????Setting Load (0.0ms)  SELECT "d ...
    13:42:12 INFO: Completed 200 OK in 750ms
    

    My environment:

    1. OS: cygwin running in XP
    2. ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]
    3. rails: 3.0.5
    4. gem: 1.6.0

    Any question please let me know~ :-)

    refer to: https://stackoverflow.com/a/20154414/445908 ,and rails6 log4r tagged_logging.rb:22:in `call': wrong number of arguments