sawmill

package module
v0.0.0-...-e2451da Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 23, 2015 License: MIT Imports: 11 Imported by: 3

README

Documentation Build status Coverage status

Sawmill is a flexible logging package for GO, with a strong emphasis on structured events.

By 'flexible', it is meant that sawmill has numerous configurable options out of the box. It is also designed for extensibility, being able to make use of third party packages.

The highlights:

  • Can send events to multiple destinations in parallel.
  • Supports writing to standard IO streams (STDOUT, files, etc), as well as external services (syslog, Splunk, Airbrake, etc).
  • Default formatters automatically colorize output when sending to a terminal.
  • Each destination can do it's own formatting, allowing you to do things like use one format for STDOUT, and another for syslog.
  • Formats are fully customizable, using standard GO text templates.
  • Serializes ancillary data, including nested structures (struct, map, slice, etc), into key/value format.
  • Supports synchronous & asynchronous processing, allowing you to resume execution without waiting for external services to accept a message.
  • ...and much more.

The project is fairly stable, but vendoring (e.g. godep) is recommended. Once issue #29 is resolved, I would consider the service as 1.0.


Example:

Example output

Source code:

package main

import sm "github.com/phemmer/sawmill"
import "time"

type Message struct {
	Sender string
	Recipients []string
	Content string
}

func main() {
	defer sm.Stop()
	timeStart := time.Now()

	message := Message{"Me", []string{"World","Mars"}, "Hello!"}
	sm.Info("Message relayed", message)

	sm.Debug("Finished", sm.Fields{"duration": time.Now().Sub(timeStart)})
	sm.Fatal("Whoops!")
}

Handlers

Handlers are the main workhorses of sawmill. After sawmill has generated an event, it routes it to all the registered handlers. Each handler can then process the event as it sees fit.

There are 2 main types of handlers, integration handlers, and utility handlers.
Integration handlers send the event outside of the program. This might be as simple as writing to STDOUT, or something more advanced like Splunk.
Utility handlers do something with the event internally. This could be filtering the events before sending them on to another handler, or storing the event in memory for later retrieval.

Integration handlers

Airbrake

The airbrake handler sends events to the Airbrake error reporting service.

Readme: https://github.com/phemmer/sawmill/blob/master/handler/airbrake/README.md
Godoc: http://godoc.org/github.com/phemmer/sawmill/handler/airbrake

import (
	"github.com/phemmer/sawmill"
	"github.com/phemmer/sawmill/handler/airbrake"
)

func main() {
	a := airbrake.New(123456, "0123456789abcdef0123456789abcdef", "production")
	filter := sawmill.FilterHandler(a).LevelMin(sawmill.ErrorLevel)
	sawmill.AddHandler("airbrake", filter)
}

Example

Sentry

The sentry handler sends events to the Sentry error reporting service.

Readme: https://github.com/phemmer/sawmill/blob/master/handler/sentry/README.md
Godoc: http://godoc.org/github.com/phemmer/sawmill/handler/sentry

import (
	"github.com/phemmer/sawmill"
	"github.com/phemmer/sawmill/handler/sentry"
)

var sentryDSN = "https://00112233445566778899aabbccddeeff:0123456789abcdef0123456789abcdef@app.getsentry.com/12345"

func main() {
	if s, err := sentry.New(sentryDSN); err == nil {
		filter := sawmill.FilterHandler(s).LevelMin(sawmill.ErrorLevel)
		sawmill.AddHandler("sentry", filter)
	}
}

Example

Splunk

The splunk handler sends events to a Splunk log collector. This includes both Splunk Cloud and Splunk Enterprise.

Readme: https://github.com/phemmer/sawmill/blob/master/handler/splunk/README.md
Godoc: http://godoc.org/github.com/phemmer/sawmill/handler/splunk

import (
	"github.com/phemmer/sawmill"
	"github.com/phemmer/sawmill/handler/splunk"
)

var splunkURL = "https://username:password@input-prd-p-xl29ahe4v1h3.cloud.splunk.com:8089/?index=development"

func main() {
	if s, err := splunk.New(splunkURL); err == nil {
		sawmill.AddHandler("splunk", s)
	}
}

Example

Syslog

The syslog handler sends events to a syslog service. This can be a service running locally on the box, or remote.

Godoc: http://godoc.org/github.com/phemmer/sawmill/handler/syslog

Writer

The writer handler sends events to any io.Writer object. This can be STDOUT/STDERR, a normal file, or anything.
The events can be formatted before being written out. The writer includes several pre-defined formats, including some which use colorization and tabulation to make the events easy to read on a console.

Readme: https://github.com/phemmer/sawmill/blob/master/handler/writer/README.md
Godoc: http://godoc.org/github.com/phemmer/sawmill/handler/writer

Utility handlers

Filter

The filter handler is used to filter events before sending them on to another handler. You can even chain multiple filter handlers together.

The most common use of this handler is to filter events based on their level, such as to send only error and above to an error reporting service.
The handler can also perform basic deduplication, so that multiple identical events don't flood an integration handler.
You can also provide your own function to determine whether to allow an event through.

Godoc: http://godoc.org/github.com/phemmer/sawmill/handler/filter

Documentation

Overview

Sawmill is an asynchronous, structured, log event handler.

Asynchronous: Sawmill does not block execution waiting for the log message to be delivered to the destination (e.g. STDOUT). Because of this asynchronous processing, it is critical that you add a `defer sawmill.Stop()` at the top of your `main()`. This will ensure that when the program exits, it waits for any pending log events to flush out to their destination.

Structured: Sawmill places a heavy emphasis on events with ancillary data. A log event (e.g. `sawmill.Error()`) should have a simple string that is an event description, such as "Image processing failed", and then a map or struct included with details on the event.

----

The base package provides a default logger that will send events to STDOUT or STDERR as appropriate. This default logger is shared by all consumers of the package.

Example
package main

import (
	"github.com/phemmer/sawmill"
)

type mystruct struct {
	Foo  string
	Bar  string
	Baz  []byte
	List []int
}

func main() {
	defer sawmill.Stop()

	data := &mystruct{
		Foo:  "FOO",
		Bar:  "BAR var",
		Baz:  []byte("abc\000def"),
		List: []int{4, 5, 6},
	}

	sawmill.Info("An event occurred", data)
	sawmill.Fatal("Whoops!", sawmill.Fields{"fu": "bar"})
}
Output:

Index

Examples

Constants

View Source
const (
	DebugLevel     = event.Debug
	InfoLevel      = event.Info
	NoticeLevel    = event.Notice
	WarningLevel   = event.Warning
	ErrorLevel     = event.Error
	CriticalLevel  = event.Critical
	AlertLevel     = event.Alert
	EmergencyLevel = event.Emergency
)

these are copied here for convenience

Variables

This section is empty.

Functions

func AddHandler

func AddHandler(name string, handler Handler)

AddHandler registers a new destination handler with the logger.

The name parameter is a unique identifier so that the handler can be targeted with RemoveHandler().

If a handler with the same name already exists, it will be replaced by the new one. During replacement, the function will block waiting for any pending events to be flushed to the old handler.

func Alert

func Alert(message string, fields ...interface{}) uint64

Alert generates an event at the alert level. It returns an event Id that can be used with Sync().

func CheckPanic

func CheckPanic()

CheckPanic is used to check for panics and log them when encountered. The function must be executed via defer. CheckPanic will not halt the panic. After logging, the panic will be passed through.

func Critical

func Critical(message string, fields ...interface{}) uint64

Critical generates an event at the critical level. It returns an event Id that can be used with Sync().

func Debug

func Debug(message string, fields ...interface{}) uint64

Debug generates an event at the debug level. It returns an event Id that can be used with Sync().

func Emergency

func Emergency(message string, fields ...interface{}) uint64

Emergency generates an event at the emergency level. It returns an event Id that can be used with Sync().

func Error

func Error(message string, fields ...interface{}) uint64

Error generates an event at the error level. It returns an event Id that can be used with Sync().

func Event

func Event(level event.Level, message string, fields ...interface{}) uint64

Event queues a message at the given level. Additional fields may be provided, which will be recursively copied at the time of the function call, and provided to the destination output handler. It returns an event Id that can be used with Sync().

func Fatal

func Fatal(message string, fields ...interface{})

Fatal generates an event at the critical level, and then exits the program with status 1

func FilterHandler

func FilterHandler(handler Handler, filterFuncs ...filter.FilterFunc) *filter.FilterHandler

FilterHandler is a convience wrapper for filter.New().

Example usage:

stdStreamsHandler := sawmill.GetHandler("stdStreams")
stdStreamsHandler = sawmill.FilterHandler(stdStreamsHandler).LevelMin(sawmill.ErrorLevel)
sawmill.AddHandler("stdStreams", stdStreamsHandler)

func GetStackMinLevel

func GetStackMinLevel() event.Level

GetStackMinLevel gets the minimum level at which to include a stack trace in events.

func GetSync

func GetSync() bool

GetSync indicates whether syncronous mode is enabled.

func Info

func Info(message string, fields ...interface{}) uint64

Info generates an event at the info level. It returns an event Id that can be used with Sync().

func InitStdStreams

func InitStdStreams()

InitStdStreams is a convience function to register a STDOUT/STDERR handler with the logger.

The is automatically invoked on the default package level logger, and should not normally be called.

func InitStdSyslog

func InitStdSyslog() error

InitStdSyslog is a convenience function to register a syslog handler with the logger.

The handler is added with the name 'syslog'

func NewWriter

func NewWriter(level event.Level) io.WriteCloser

NewWriter returns an io.WriteCloser compatable object that can be used for traditional writing into sawmill.

The main use case for this is to redirect the stdlib log package into sawmill. For example:

log.SetOutput(sawmill.NewWriter(sawmill.InfoLevel))
log.SetFlags(0) // sawmill does its own formatting

func Notice

func Notice(message string, fields ...interface{}) uint64

Notice generates an event at the notice level. It returns an event Id that can be used with Sync().

func RemoveHandler

func RemoveHandler(name string, wait bool)

RemoveHandler removes the named handler from the logger, preventing any further events from being sent to it. The wait parameter will result in the function blocking until all events queued for the handler have finished processing.

func SendEvent

func SendEvent(logEvent *event.Event) uint64

SendEvent queues the given event. The event's `Id` field will be updated with a value that can be used by Sync(). This value is also provided as the return value for convenience.

func SetStackMinLevel

func SetStackMinLevel(level event.Level)

SetStackMinLevel sets the minimum level at which to include a stack trace in events.

func SetSync

func SetSync(enabled bool)

SetSync controls synchronous event mode. When set to true, a function call to generate an event does not return until the event has been processed.

func Stop

func Stop()

Stop removes all destinations on the logger, and waits for any pending events to flush to their destinations.

func Sync

func Sync(eventId uint64)

Sync blocks until the given event Id has been flushed out to all destinations.

func Warning

func Warning(message string, fields ...interface{}) uint64

Warning generates an event at the warning level. It returns an event Id that can be used with Sync().

Types

type Fields

type Fields map[string]interface{}

Fields is a convenience type for passing ancillary data when generating events.

type Handler

type Handler interface {
	Event(event *event.Event) error
}

Handler represents a destination for sawmill to send events to. It responds to a single method, `Event`, which accepts the event to process. It must not return until the event has been fully processed.

func GetHandler

func GetHandler(name string) Handler

GetHandler retrieves the handler with the given name. Returns nil if no such handler exists.

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger is the core type in sawmill. The logger tracks a list of destinations, and when given an event, will asynchronously send that event to all registered destination handlers.

func DefaultLogger

func DefaultLogger() *Logger

DefaultLogger returns a common *Logger object that is shared among all consumers of the package. It is used implicitly by all the package level helper function (Event, Emergency, etc)

func NewLogger

func NewLogger() *Logger

NewLogger constructs a Logger. The new Logger will not have any registered handlers.

By default events will not include a stack trace. If any destination handler makes use of a stack trace, call SetStackMinLevel on the logger.

func (*Logger) AddHandler

func (logger *Logger) AddHandler(name string, handler Handler)

AddHandler registers a new destination handler with the logger.

The name parameter is a unique identifier so that the handler can be targeted with RemoveHandler().

If a handler with the same name already exists, it will be replaced by the new one. During replacement, the function will block waiting for any pending events to be flushed to the old handler.

func (*Logger) Alert

func (logger *Logger) Alert(message string, fields ...interface{}) uint64

Alert generates an event at the alert level. It returns an event Id that can be used with Sync().

func (*Logger) CheckPanic

func (logger *Logger) CheckPanic()

CheckPanic is used to check for panics and log them when encountered. The function must be executed via defer. CheckPanic will not halt the panic. After logging, the panic will be passed through.

func (*Logger) Critical

func (logger *Logger) Critical(message string, fields ...interface{}) uint64

Critical generates an event at the critical level. It returns an event Id that can be used with Sync().

func (*Logger) Debug

func (logger *Logger) Debug(message string, fields ...interface{}) uint64

Debug generates an event at the debug level. It returns an event Id that can be used with Sync().

func (*Logger) Emergency

func (logger *Logger) Emergency(message string, fields ...interface{}) uint64

Emergency generates an event at the emergency level. It returns an event Id that can be used with Sync().

func (*Logger) Error

func (logger *Logger) Error(message string, fields ...interface{}) uint64

Error generates an event at the error level. It returns an event Id that can be used with Sync().

func (*Logger) Event

func (logger *Logger) Event(level event.Level, message string, fields ...interface{}) uint64

Event queues a message at the given level. Additional fields may be provided, which will be recursively copied at the time of the function call, and provided to the destination output handler. It returns an event Id that can be used with Sync().

func (*Logger) Fatal

func (logger *Logger) Fatal(message string, fields ...interface{})

Fatal generates an event at the critical level, and then exits the program with status 1

func (*Logger) FilterHandler

func (logger *Logger) FilterHandler(handler Handler, filterFuncs ...filter.FilterFunc) *filter.FilterHandler

FilterHandler is a convience wrapper for filter.New().

Example usage:

stdStreamsHandler := logger.GetHandler("stdStreams")
stdStreamsHandler = logger.FilterHandler(stdStreamsHandler).LevelMin(sawmill.ErrorLevel)
logger.AddHandler("stdStreams", stdStreamsHandler)

func (*Logger) GetHandler

func (logger *Logger) GetHandler(name string) Handler

GetHandler retrieves the handler with the given name. Returns nil if no such handler exists.

func (*Logger) GetStackMinLevel

func (logger *Logger) GetStackMinLevel() event.Level

GetStackMinLevel gets the minimum level at which to include a stack trace in events.

func (*Logger) GetSync

func (logger *Logger) GetSync() bool

GetSync indicates whether syncronous mode is enabled.

func (*Logger) Info

func (logger *Logger) Info(message string, fields ...interface{}) uint64

Info generates an event at the info level. It returns an event Id that can be used with Sync().

func (*Logger) InitStdStreams

func (logger *Logger) InitStdStreams()

InitStdStreams is a convience function to register a STDOUT/STDERR handler with the logger.

The handler is added with the name 'stdStreams'

func (*Logger) InitStdSyslog

func (logger *Logger) InitStdSyslog() error

InitStdSyslog is a convenience function to register a syslog handler with the logger.

The handler is added with the name 'syslog'

func (*Logger) NewWriter

func (logger *Logger) NewWriter(level event.Level) io.WriteCloser

NewWriter returns an io.Writer compatable object that can be used for traditional writing into sawmill.

The main use case for this is to redirect the stdlib log package into sawmill. For example:

log.SetOutput(logger.NewWriter(sawmill.InfoLevel))
log.SetFlags(0) // sawmill does its own formatting

func (*Logger) Notice

func (logger *Logger) Notice(message string, fields ...interface{}) uint64

Notice generates an event at the notice level. It returns an event Id that can be used with Sync().

func (*Logger) RemoveHandler

func (logger *Logger) RemoveHandler(name string, wait bool)

RemoveHandler removes the named handler from the logger, preventing any further events from being sent to it. The wait parameter will result in the function blocking until all events queued for the handler have finished processing.

func (*Logger) SendEvent

func (logger *Logger) SendEvent(logEvent *event.Event) uint64

SendEvent queues the given event. The event's `Id` field will be updated with a value that can be used by Sync(). This value is also provided as the return value for convenience.

func (*Logger) SetStackMinLevel

func (logger *Logger) SetStackMinLevel(level event.Level)

SetStackMinLevel sets the minimum level at which to include a stack trace in events.

func (*Logger) SetSync

func (logger *Logger) SetSync(enabled bool)

SetSync controls synchronous event mode. When set to true, a function call to generate an event does not return until the event has been processed.

func (*Logger) Stop

func (logger *Logger) Stop()

Stop removes all destination handlers on the logger, and waits for any pending events to flush out.

func (*Logger) Sync

func (logger *Logger) Sync(eventId uint64)

Sync blocks until the given event Id has been flushed out to all destinations.

func (*Logger) Warning

func (logger *Logger) Warning(message string, fields ...interface{}) uint64

Warning generates an event at the warning level. It returns an event Id that can be used with Sync().

Directories

Path Synopsis
formatter
The formatter package is used to wrap an event with helper functions so it can be easily used in text templates.
The formatter package is used to wrap an event with helper functions so it can be easily used in text templates.
handler
airbrake
The airbrake package provides a handler which sends events to the Airbrake error reporting service.
The airbrake package provides a handler which sends events to the Airbrake error reporting service.
capture
The capture handler maintains a threadsafe slice of *event.Event.
The capture handler maintains a threadsafe slice of *event.Event.
channel
The channel handler provides an unbuffered `chan *event.Event` onto which each recieved event is written.
The channel handler provides an unbuffered `chan *event.Event` onto which each recieved event is written.
filter
The filter package provides a way to filter events from handlers.
The filter package provides a way to filter events from handlers.
sentry
The sentry package provides a handler which sends events to the Sentry exception reporting service.
The sentry package provides a handler which sends events to the Sentry exception reporting service.
splunk
The splunk package is an event handler responsible for sending events to Splunk via the HTTP API.
The splunk package is an event handler responsible for sending events to Splunk via the HTTP API.
syslog
The syslog package is an event handler responsible for sending events to syslog.
The syslog package is an event handler responsible for sending events to syslog.
writer
The writer package is an event handler responsible for sending events to a generic IO writer.
The writer package is an event handler responsible for sending events to a generic IO writer.
The log package provides stdlib log interface compatability to sawmill.
The log package provides stdlib log interface compatability to sawmill.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL