Hatchet

Ruby logging library that provides the ability to add class/module specific filters

View the Project on GitHub gshutler/hatchet

Navigation


Build status


Hosted on GitHub Pages — Theme by orderedlist

Configuration

Hatchet’s configuration revolves around three concepts:

Hatchet knows about the 5 standard log levels:

The meanings of these levels are identical to their meanings in the standard Ruby Logger.

Hatchet comes with one appender out of the box, the LoggerAppender. This is an appender that delegates its log calls to an instance of the standard Ruby logger.

Hatchet also comes with three formatters, the PlainFormatter, the StandardFormatter, and the SimpleFormatter.

The PlainFormatter is a formatter that outputs messages as they are received with no additional information or cleansing.

The StandardFormatter is a formatter that outputs messages in the TTCC format of log4j. This is a format that is easy to grep and works well with log monitoring tools like Chainsaw.

The development version of Chainsaw plays best with Hatchet’s output.

The SimpleFormatter is formats messages similarly to the StandardFormatter but only outputs the level, context, and text of the log message.

Example Configuration

This is an example bringing together all the functionality of levels, appenders, and formatters into a single example of logging nirvana:

Hatchet.configure do |config|
  config.level :warn
  config.level :debug, 'Application::BankTransfer'

  config.appenders << Hatchet::LoggerAppender.new do |appender|
    appender.logger = Logger.new('log/application.log')
  end

  config.appenders << CustomEmailAppender.new do |appender|
    appender.level :fatal
    appender.formatter = CustomEmailFormatter.new
    appender.recipient = 'alerts@example.com'
  end
end

This creates a Hatchet configuration that logs :warn and higher messages to file by default but adds a special case for the Application::BankTransfer class it logs :debug and higher messages. If a fatal message is ever logged it will also send an email about it, in a pretty format, to alerts@example.com.

All this functionality is abstracted away from your application code. Your application calls the logging methods in the same way regardless of the number of appenders.

Levels

Hatchet knows about the 5 standard log levels:

The meanings of these levels are identical to their meanings in the standard Ruby Logger.

The configuration object has a level method that takes the level you want to log at and an optional scope that level applies to. If no scope is specified then it sets the default level to be used if no specific level is set for the scope of a logging call.

Scope is defined hierarchically at the module and/or class level. For example, if we have the class Application::Models::Person we can specify the level for logging within that class through 4 levels of scope:

Hatchet.configure do |config|
  config.level :error
  config.level :warn,  'Application'
  config.level :info,  'Application::Models'
  config.level :debug, 'Application::Models::Person'
end

The logging level is taken from the most specific scope for the context of the logging call, not the order in which the levels are specified.

For the above configuration:

Individual appenders can have their levels configured separately. However, if their levels are not touched during configuration then Hatchet will share the default set of levels with them.

Appenders

Hatchet has the concept of appenders as unlike the standard Logger class a single message can be logged to many destinations. For example, you might want to log all :warn and higher messages to a regular log file on disk but you might want to receive an email whenever a :fatal message is logged. Hatchet allows you to do this through a single logging interface.

The configuration object has a appenders array that contains all the appenders that should process each logging message. Adding a new appender is as simple as appending a new appender instance to this array. Whether the appender writes the message to its destination or not depends on how its levels are configured, be it through inheriting the default levels or having its own levels explicitly set.

For our example of a log file recording all :warn and higher messages and an appender emailing all :fatal messages the configuration would look like this:

Hatchet.configure do |config|
  config.level :warn

  config.appenders << Hatchet::LoggerAppender.new do |appender|
    appender.logger = Logger.new('log/application.log')
  end

  config.appenders << CustomEmailAppender.new do |appender|
    appender.level :fatal
    appender.recipient 'alerts@example.com'
  end
end

Related:

Formatters

Hatchet has the concept of formatters which are classes that receive the level and context of a message and produce a formatted message including the text specified as part of the logging call.

Formatters are specific to each appender. If no formatter is assigned to the formatter property of an appender then Hatchet will give it an instance of the StandardFormatter that comes with Hatchet.

The StandardFormatter outputs messages in the TTCC of log4j. This is a format that is easy to grep and works well with log monitoring tools like Chainsaw.

If you don’t like that type of output you can set the formatter of your appender to a formatter you do like the style of:

Hatchet.configure do |config|
  config.appenders << Hatchet::LoggerAppender.new do |appender|
    appender.formatter = CustomFormatter.new
  end
end

You can also change the default formatter used by all appenders:

Hatchet.configure do |config|
  config.formatter = CustomFormatter.new
end

Changing the default formatter will change the formatter for all future appenders and all those already using the default appender.

Related: