6

I have been researching this topic for far too long now, so I have to post this. I have a few applications running this setup and one of them completely borks on rails startup (rails s). They are both configured nearly the exact same, but I can not seem to find the needle in the haystack here. Does anyone have any pointers on how to find this issue?

setup based on: http://blog.mmlac.com/log4r-for-rails/comment-page-1/#comment-1731

when I try to run rails s:

=> Booting WEBrick
=> Rails 4.0.0 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Exiting
/Users/chrishough/Placewise/code/ApiDigest/.bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands/server.rb:78:in `start': undefined method `formatter' for #<Log4r::Logger:0x007f85be89abe8> (NoMethodError)
    from /Users/chrishough/Placewise/code/ApiDigest/.bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands.rb:78:in `block in <top (required)>'
    from /Users/chrishough/Placewise/code/ApiDigest/.bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands.rb:73:in `tap'
    from /Users/chrishough/Placewise/code/ApiDigest/.bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands.rb:73:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

how I have log4r configured in my application.rb file:

#log4r requirements
require 'log4r'
require 'log4r/yamlconfigurator'
require 'log4r/outputter/datefileoutputter'
include Log4r

module DigestApi
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

   # -----------------------------------------------------------------------------------
    # assign log4r's logger as rails' logger.
    log4r_config= YAML.load_file(File.join(File.dirname(__FILE__),"log4r.yml"))
    log_cfg = YamlConfigurator
    log_cfg["ENV"] = Rails.env 
    log_cfg.decode_yaml(log4r_config['log4r_config'])

    # # disable standard Rails logging
    config.logger = Log4r::Logger['rails']
    ActiveRecord::Base.logger = Log4r::Logger['sqlserver']

    # #nice for multiple-instance webservers like unicorn
    # #to monitor (re-)starts
    # #log whenever a worker (re-)started
    Log4r::Logger['rails'].info "LAUNCH PUMA WORKER"
    # -----------------------------------------------------------------------------------

My log4r.yml file:

log4r_config:
  # define all loggers:
  loggers:
    - name          : rails
      level         : DEBUG
      trace         : 'true'
      outputters    :
      - console
      - rails_file

    - name          : sqlserver
      level         : DEBUG
      trace         : 'false'
      outputters    :
      - sqlserver_file

    - name          : sqlserver_long_query
      level         : DEBUG
      trace         : 'false'
      outputters    :
      - sqlserver_long_query_file

    - name          : missing_route
      level         : DEBUG
      trace         : 'false'
      outputters    :
      - missing_route_file

  # define all outputters (incl. formatters)
  outputters:
  - type: StdoutOutputter
    name: console
    formatter:
      date_pattern: '%H:%M:%S'
      pattern     : '%d %l: %m'
      type        : PatternFormatter

  - type: FileOutputter
    name: rails_file
    filename: "log/#{ENV}.log"
    trunc: false
    formatter:
      date_pattern: '%Y %m %d %H:%M:%S.%L %z'
      pattern     : '%d %l: %m'
      type        : PatternFormatter

  - type: FileOutputter
    name: sqlserver_file
    filename: "log/sql.log"
    trunc: false
    formatter:
      date_pattern: '%Y %m %d %H:%M:%S.%L %z'
      pattern     : '%d %l: %m'
      type        : PatternFormatter

  - type: FileOutputter
    name: sqlserver_long_query_file
    filename: "log/sql_qry_long.log"
    trunc: false
    formatter:
      date_pattern: '%Y %m %d %H:%M:%S.%L %z'
      pattern     : '%d %l: %m'
      type        : PatternFormatter

  - type: FileOutputter
    name: missing_route_file
    filename: "log/missing_route.log"
    trunc: false
    formatter:
      date_pattern: '%Y %m %d %H:%M:%S.%L %z'
      pattern     : '%d %l: %m'
      type        : PatternFormatter
Chris Hough
  • 3,389
  • 3
  • 41
  • 80

3 Answers3

10

I was running into the same problem, so I created an initializer to extend log4r with an empty formatter method. Just create a file named log_formatting.rb in initializers and paste the following into it:

class Log4r::Logger
  def formatter()
  end
end

This worked for me. I hope it helps.

Cheese Widget
  • 201
  • 2
  • 4
2

Looking at this post [1] you might have to import the FileOutputter as well. Not really sure.

I think it's an import issue when the other server works fine. Just try to import everything you might possibly use from Log4r and make sure you don't call in [1] mentioned functions directly on the logger somewhere else.

If that does not work, try setting up a simple logger programmatically, then move that logger to the .yml and then expand it back to where it was before.

Hope this helps you, let me know if you need more help

[1] Undefined Method Formatter for Log4r in RAILS 4.0

Community
  • 1
  • 1
mmlac
  • 1,091
  • 1
  • 9
  • 24
  • Are you referring to using a different require statement? i.e. require 'log4r/outputter/fileoutputter' – Chris Hough Oct 25 '13 at 03:58
  • exactly. Try to import every class that is used in the yml, try re-indenting it, should there been an error. If it still breaks start from scratch with the simplest code-defined logger possible, then work your way up and see if and when it breaks again – mmlac Oct 25 '13 at 04:43
  • yep, I have tried everything, it is still breaking for some reason. I am following your blog post exactly, and no matter what I do it keeps blowing up on this application. Any other ideas? – Chris Hough Oct 25 '13 at 05:19
  • ok, I think I may have found the issue... In the new application we have a gem that is using Rails::Logger, where the other application only uses Log4r::Logger. Is there anyway to have Rails:Logger map to Log4r:Logger? – Chris Hough Oct 25 '13 at 05:41
  • Hmm, this is weird. So the gem expects the logger to be of type Rails::Logger and executes functions on it? I don't see an easy way to solve that except giving this gem the original logger via other means / forking the gem and uncomment the offending lines (you format the logs yourself anyway) Maybe the gem allows setting a logger programmatically? – mmlac Oct 25 '13 at 06:02
  • 1
    Conclusion: We were using a gem that was using the syntax Rails.logger which was triggering this error. Log4r loggers should use the Log4r.logger syntax instead. We are working to correct this now. Also, please note , that Log4r does not work on Heroku as of this post. – Chris Hough Oct 25 '13 at 21:16
  • Do you mind elaborating why Log4r does currently not work with heroku? – mmlac Oct 26 '13 at 07:54
0

The other possible could be to see your environment.rb file if you have accidentally commented/removed the following lines.

require_relative 'application'
Rails.application.initialize!