Using MongoHQ for logging with Heroku

Free logging on Heroku is limited, with basic giving you 500 lines of history and expanded giving you the ability to tail. If you want to keep anymore then you have to upgrade for $10 a month, which aint bad if your running something that generates money.

For my blog however I wanted to keep the last week or so of logs and not pay anything so I setup logging with MongoHQ and a gem called central_logger. MongoHQ offer a free shared DB of 16MB which is more than enough for me. Central Logger is a centralized logging gem for rails apps with MongoDB which includes support for Rails 3 and 2.

Setting it up

  #Gemfile
    gem "central_logger"

  #applicatication_controller.rb
    include CentralLogger::Filter

require 'central_logger' CentralLogger::Initializer.initialize_deprecated_logger(config)

#database.yml
development:
  adapter: mysql
  database: my_app_development
  user: root
  mongo:
    # required (the only required setting)
    database: my_app
    # default: 250MB for production; 100MB otherwise - MongoHQ free account caps out at 16MB
    capsize: <%= 10.megabytes %>
    # default: localhost - May not be flame.mongohq, may be one of there other subdomains
    host: flame.mongohq.com
    # default: 27017
    port: 27099
    # default: false - Adds retries for ConnectionFailure during voting for replica set master
    replica_set: true
    # default: false - Enable/Disable safe inserts (wait for insert to propagate to all nodes)
    safe_insert: true
    # default: Rails.application - Only really needed for non-capistrano Rails 2 deployments
    # Otherwise should set automatically.
    application_name: my_app
    # MongoHQ DB username
    username: myusername
     # MongoHQ DB password
    password: mypass

OR

#central_logger.yml
development:
    database: my_app
    capsize: <%= 10.megabytes %>
    host: flame.mongohq.com
    port: 27099
    replica_set: true
    username: myusername
    password: mypass

#test:
#......

#production:
#......

Remember that people may have access to this file, so storing the DB password in here is not the best idea.

That’s it, restart the server and you’re good to go. Once the page hits start coming in you will see a new collection developer_log (or w/e you set it up for) with documents being created per request. The log format will look like this

{
   'action'           : action_name,
   'application_name' : application_name (rails root),
   'controller'       : controller_name,
   'ip'               : ip_address,
   'messages'         : {
                          'info'  : [ ],
                          'debug' : [ ],
                          'error' : [ ],
                          'warn'  : [ ],
                          'fatal' : [ ]
                        },
   'params'           : { },
   'path'             : path,
   'request_time'     : date_of_request,
   'runtime'          : elapsed_execution_time_in_milliseconds,
   'url'              : full_url
}

If you want to add extra information to the base of the document (let’s say something like user_guid on every request that it’s available), you can just call the Rails.logger.add_metadata method on your logger like so (for example from a before_filter):

# make sure we're using the CentralLogger in this environment
if Rails.logger.respond_to?(:add_metadata)
    Rails.logger.add_metadata(:user_guid => @user_guid)
end

-Matt

·