2

I am trying to create a custom outputter that logs remotely using a message queue... I found an outputter in the log4r project and tried to modify it... but i suck... so there is likely a WAY better way to do this. i.e.: one that works. ;)

Here i create my duplicate outputter with modified inatializer and write methods.

/lib/rabbit_outputter.rb

require 'log4r'
require 'bunny'

class RabbitOutputter < Log4r::Outputter
  attr_reader :host, :port
  attr_accessor :udpsock
  @exchange = "test1"

  def initialize(_name, hash={})
   super(_name, hash)

   bunny = Bunny.new
   bunny.start
   q = bunny.queue(@exchange)
   @e = bunny.exchange("")
   @e.publish("BOOSH!", :key => @exchange)
   #uncomment this later... b.stop

  end

  #######
  private
  #######

  def write(data)  
    @e.publish(data, :key => @exchange)
  end

end

Then i mixed it into my rails initializers. /config/initalizers/rabbit_outputter.rb

require "#{Rails.root}/lib/rabbit_outputter.rb"

Then i swap out my log4r loggers in my log4r.yaml file

/config/log4r.yaml

log4r_config:
  loggers:
    - name : development
      level : DEBUG
      additive : 'false'
      trace : 'true'
      outputters:
      - rabbit_outputter
    - name : test
      level : DEBUG
      additive : 'false'
      trace : 'true'
      outputters:
      - rabbit_outputter
    - name : staging
      level : INFO
      additive : 'false'
      trace : 'true'
      outputters:
      - rabbit_outputter
    - name : production
      level : INFO
      additive : 'false'
      trace : 'true'
      outputters:
      - rabbit_outputter
  outputters:
    - type : RabbitOutputter
      name : rabbit_outputter
      level : INFO
      filename : <%= "#{Rails.root}/log/#{Rails.env}.log" %>
      formatter:
        date_pattern: '%Y-%m-%d %H:%M:%S %z'
        pattern : '{ \"date\":\"%d\", \"level\":\"%l\", \"appname\":\"MyApp\", \"event fullname\": \"%C\", \"global_diagnostic_context\":\"%g\",\"trace\":\"%t\", \"message\": %m }'
        type : PatternFormatter

Here is the error when i open a rails console:

rails c
/Users/<myusername>/.rvm/gems/ruby-1.9.3-p392/gems/log4r-1.1.10/lib/log4r/yamlconfigurator.rb:68:in `block in decode_yaml': 
Problem creating outputter: uninitialized constant Log4r::RabbitOutputter (Log4r::ConfigError)
Pandem1c
  • 778
  • 1
  • 5
  • 12

1 Answers1

2

I had this same problem and was able to solve it by putting the following code at the top of my application.rb, after my Bundler.require statement:

require 'log4r'
require 'log4r/yamlconfigurator'
require "#{Rails.root}/lib/rollable_file_outputter.rb"
include Log4r

Then, at the bottom on the Application class block, add this and with dynamic loggers:

# 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'] )
Server::Application::config.logger = Log4r::Logger[Rails.env]

Then I could use type: RollableFileOutputter in my config/log4r.yml file.

I tried putting all this into a single initializer (config/initializers/logging.rb), but then the default logger was not log4r, just the standard rails logger. I don't really understand why.

RussK
  • 199
  • 1
  • 17
  • This led me to the solution to another problem I was having. Using EmailOutputter in an XML config only works if you add require 'log4r/emailoutputter' in application.rb – Brad Urani Jan 15 '14 at 21:22