/timber

Configurable Logger for Go

Primary LanguageGoMIT LicenseMIT

Timber!

Timber is a logger for go with a similar interface as log4go and also can be used as a drop-in replacement for the go standard logger.

Features

  • Log levels: Finest, Fine, Debug, Trace, Info, Warn, Error, Critical
  • External configuration via XML
  • Multiple log destinations (console, file, socket)
  • Configurable format per destination
  • Extensible and pluggable design (if you configure via code rather than XML)

Motivation

I like the log4go design with multiple configurable loggers, but it did not support adding formatters to all of the loggers (it is only supported for files). I thought about trying to contribute patches to log4go but some of the features I wanted would break complete backwards compatibility so I decided to do a rewrite from scratch.

I try to expose everything possible that I think might be useful for someone to replace or extend.

Usage

The easiest way to use Timber is to use configure the built-in singleton:

import (
	log "timber"
)

func main() {
	// load xml config
	log.LoadConfiguration("timber.xml")
	log.Info("Timber!!!")
}

An example timber.xml file is included in the package. Timber does implement the interface of the go log package so replacing the log with Timber will work ok.

log.Close() should be called before your program exits to make sure all the buffers are drained and all messages are printed.

Design

Logger is the interface that is used for logging itself with methods like Warn, Critical, Error, etc. All of these functions expect a Printf-like arguments and syntax for the message.

LogFormatter is a generic interface for taking a LogRecord and formatting into a string to be logged. PatFormatter is the only included implementation of this interface.

LogWriter interface wraps an underlying Writer but doesn't allow errors to propagate. There are implementations for writing to files, sockets and the console.

Timber is a MultiLogger which just means that it implements the Logger interface but can log messages to multiple destinations. Each destination has a LogWriter, level and LogFormatter.

Global is the default unconfigured instance of Timber which may be configured and used or, less commonly, replaced with your own instance (be sure to call Global.Close() before replacing for proper cleanup).

Are you planning to wrap Timber in your own logger? Ever notice that if you wrap the go log package or log4go the source file that gets printed is always your wrapper? Timber.FileDepth sets how far up the stack to go to find the file you actually want. It's set to DefaultFileDepth so add your wrapper stack depth to that.

Completeness

  • Some of the runtime configuration changes have not been implemented, such as MultiLogger.SetLevel and MultiLogger.SetFormatter which change the Level or LogFormatter on-the-fly. Loggers may be added at any time with AddLogger but there is no way to delete loggers right now.

Compatibility

  • I don't support the log4go special handling of the first parameter and probably never will. Right now, all of the Logger methods just expect a Printf-like syntax. If there is demand, I may get the proc syntax in for delayed evaluation.
  • PatFormatter format codes are not the same as log4go
  • PatFormatter always adds a newline at the end of the string so if there's already one there, then you'll get 2 so using Timber to replace the go log package may look a bit messy depending on how you formatted your logging.