Skip to content

christianbak/sawmill

 
 

Repository files navigation

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

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

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

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

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

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

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

Releases

No releases published

Packages

No packages published

Languages

  • Go 100.0%