/rf_logger

Standardized logger with optional notification system

Primary LanguageRuby

RF Logger provides a consistent API to log events of different severity levels. Severities include:

    :debug # dev-only, for exploring issues
    :info  # end users, to audit process
    :warn  # weird thing happened, but isn't really an issue
    :error # someone fix the code
    :fatal # system-wide errors

The API provides helper methods for each severity (i.e. Logger.debug). In addition to logging severity levels, the following fields are optional:

  • actor (The user or caller of the event that you are logging)
  • action (The event you are logging)
  • target_type (We use this in cases where we want to tie a log record to a particular entity or object in the database, for example User)
  • target_id (This is used in conjunction with target_type, as the unique identifier for the relevant entity)
  • metadata (Additional information such as error details and backtraces or other messages, stored as a hash)

This gem includes RfLogger::SimpleLogger and RfLogger::Sequel logger as two options that adhere to this API. The fields above should be passed into helper methods as a hash.

##Configuration## Configuration mostly sets up additional notifications beyond the actual logging.

RfLogger.configure do |c|
  # environment attempts to determine this for Rails, Sinatra, Padrino, and Rory, but is otherwise
  c.environment = 'production'  required
  # fields from above can be interpolated into the notification subject
  c.notification_subject = "Oh no!  An error of {{level}} severity just occurred."
  c.set_notifier_list do |n|
    c.add_notifier Notification::DefinedElsewhere, :levels => [:error], :except => ['test', 'development']
    c.add_notifier Notification::OhNo, :levels => [:fatal, :error], :only => ['production']
    c.add_notifer Notifcation:VeryVerbose
  end
end

As you seen above, you can specify different notifications for different levels or environments whend you log an event.

##Notification## While you have to implement notifiers yourself, the API is fairly simple. The class must respond to .send_notification. The argument passed in is an object that includes a #subject (which can be defined in the configuration (see above), and #details, which is the metadata in YAML format. Future versions of this may allow for other transformations of the log data.

Example:

require 'tinder'
module Notification
  class Campfire
    class << self
      def send_error_notification log_info
        message = log_info.subject + "\n" + log_info.details
        post_message message
      end

      def post_message message
        campfire = Tinder::Campfire.new(config['user'], :token => config['api_token'])
        room = campfire.find_room_by_id(config['room_id'])
        room.paste message
      end

      def config
        @config ||= YAML.load_file(File.join(Rails.root, 'config/campfire.yml'))
      end
    end
  end
end