flog

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 12, 2019 License: MIT Imports: 11 Imported by: 0

README

go-flog

A library that provides structured and formatted logging for the Go programming language.

Documention

Online documentation, which includes examples, can be found at: http://godoc.org/github.com/reiver/go-flog

GoDoc

More Routers

In addition to the builtin routers that go-flog comes with, other external routers are also available. These include:

Documentation

Overview

Package flog provides structured and formatted logging.

Basic Usage

Basic usage of the flogger looks like this:

router := flog.NewPrettyWritingRouter(os.Stdout)

flogger := flog.New(router)

Once you have the flogger, you can do things such as:

flogger.Print("Hello world!")
flogger.Println("Hello world!")
flogger.Printf("Hello %s!", name)

flogger.Panic("Uh oh!")
flogger.Panicln("Uh oh!")
flogger.Panicf("Uh oh, had a problem happen: %s.", problemDescription)

flogger.Fatal("Something really bad happened!")
flogger.Fatalln("Something really bad happened!")
flogger.Fatalf("Something really bad happened: %s.", problemDescription)

BTW, if the PrettyWritingRouter was being used, then this:

flogger.Print("Hello world!")

Would generate output like the following:

Hello world!	(2015-10-10 17:28:49.397356044 -0700 PDT)

(Although note that in actual usage this would have color.)

(Note that for for other routers the actual output would look very different! What the output looks like is router dependent.)

Structured Logging

But those method calls all generated unstructure data.

To include structured data the flogger's With method needs to be used. For example:

newFlogger := flogger.With(map[string]interface{}{
	"method":"Toil",
	"secret_note":"Hi there! How are you?",
})

Then if the PrettyWritingRouter was being used, then this:

newFlogger.Print("Hello world!")

Would generate output like the following:

Hello world!	(2015-10-10 17:28:49.397356044 -0700 PDT)	method="Toil"	secret_note="Hi there! How are you?"

(Again, note that in actual usage this would have color.)

Deployment Environment

Of course in a real application system you should (probably) create a different kind of flogger for each deployment environment.

Even though the PrettyWritingRouter is great for a development deployment environment (i.e., "DEV") it is probably not appropriate for a production deployment environment (i.e., "PROD").

For example:

var flogger flog.Flogger

switch deploymentEnvironment {
case "DEV":
	router := flog.NewPrettyWritingRouter(os.Stdout)

	flogger = flog.New(router)
case "PROD":
	verboseRouter = flog.NewDiscardingRouter()
	if isVerboseMode {
		verboseRouter = NewCustomVerboseRouter()
	}

	panicDetectionRouter := flog.NewFilteringRouter(NewCustomerPanicRecordingRouter(), filterOnlyPanicsFunc)

	errorDetectionRouter := flog.NewFilteringRouter(NewCustomerPanicRecordingRouter(), filterOnlyErrorsFunc)

	router := NewFanoutRouter(verboseRouter, panicDetectionRouter, errorDetectionRouter)

	flogger = flog.New(router)
}

More Routers

In addition to the builtin routers that go-flog comes with, other external routers are also available. These include:

go-slackchannelrouter: Makes it so log messages get posted to a Slack channel. https://github.com/reiver/go-slackchannelrouter

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CopyingRouter

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

CopyingRouter is a Router that copies a message (and its context) to memory, and then re-routes a message (and its context) to a sub-router.

This router is NOT designed to be used for an indefinite number of routings, and instead should only be used for a limited amount of routings, as it stores all the copies in memory.

func NewCopyingRouter

func NewCopyingRouter(subrouter Router) *CopyingRouter

NewCopyingRouter returns an initialized CopyingRouter.

func (*CopyingRouter) Copies

func (router *CopyingRouter) Copies() <-chan struct {
	Message string
	Context map[string]interface{}
}

func (*CopyingRouter) Route

func (router *CopyingRouter) Route(message string, context map[string]interface{}) error

type DefaultWritingRouter

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

DefaultWritingRouter is a router that writes the log in a default format.

A DefaultWritingRouter is appropriate for a production (i.e., "PROD") deployment enviornment.

func NewDefaultWritingRouter

func NewDefaultWritingRouter(writer io.Writer) *DefaultWritingRouter

NewDefaultWritingRouter returns an initialized DefaultWritingRouter

func NewDefaultWritingRouterWithPrefix

func NewDefaultWritingRouterWithPrefix(writer io.Writer, prefix map[string]interface{}) *DefaultWritingRouter

NewDefaultWritingRouterWithPrefix returns an initialized DefaultWritingRouter

func (*DefaultWritingRouter) Route

func (router *DefaultWritingRouter) Route(message string, context map[string]interface{}) error

type DiscardingRouter

type DiscardingRouter struct{}

DiscardingRouter is a Router that discards any message (and its context) it is asked to route.

Conceptually it is similar to /dev/null

func NewDiscardingRouter

func NewDiscardingRouter() *DiscardingRouter

NewDiscardingRouter returns an initialized DiscardingRouter.

func (*DiscardingRouter) Route

func (router *DiscardingRouter) Route(message string, context map[string]interface{}) error

type FanoutRouter

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

FanoutRouter is a Router that re-routes any message (and its context) it receives to all of its sub-routers.

func NewFanoutRouter

func NewFanoutRouter(subrouters ...Router) *FanoutRouter

NewFanoutRouter returns an initialized FanoutRouter.

func (*FanoutRouter) Route

func (router *FanoutRouter) Route(message string, context map[string]interface{}) error

type FilteringRouter

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

FilteringRouter is a Router that conditionally re-routes or discards a message (and its context).

func NewFilteringRouter

func NewFilteringRouter(subrouter Router, filterFn func(string, map[string]interface{}) bool) *FilteringRouter

NewFilteringRouter returns an initialized FilteringRouter.

'subrouter' is the sub-router that a FilteringRouter will re-Route a 'message' (and 'context') to, but only on the condition that 'filterFn' returns 'true' for the 'message' and 'context' passed to it.

An example for 'filterFn' is the following.

func filterError(message string, context map[string]interface{})bool) bool {
	if datum, ok := context["error"]; !ok {
		return false
	} else if _, ok := datum.(error); !ok {
		return false
	} else {
		return true
	}
}

This func will cause the router it only re-route messages whose context #1 has the key "error" and #2 where the value of the context at key "key" fits the builtin Go 'error' interface.

So, for example, for 'filterError' this would pass:

context := map[string]interface{}{
	"apple":1,
	"banana":2,
	"cherry":3,
	"error": errors.New("Something bad happened :-("),
}

But, again for 'filterError', this would NOT pass:

context := map[string]interface{}{
	"apple":1,
	"banana":2,
	"cherry":3,
}

Also, a rather useless example, but a 'filterFn' that would reject all messages (and contexts) is:

func filterRejectAll(message string, context map[string]interface{})bool) bool {
	return false
}

And also, another rather useless example, but a 'filterFn' that would allow all messages (and contexts) is:

func filterAcceptAll(message string, context map[string]interface{})bool) bool {
	return true
}

func (*FilteringRouter) Route

func (router *FilteringRouter) Route(message string, context map[string]interface{}) error

type Flogger

type Flogger interface {
	Debug(...interface{})
	Debugf(string, ...interface{})
	Debugln(...interface{})

	Error(...interface{})
	Errorf(string, ...interface{})
	Errorfe(error, string, ...interface{})
	Errorln(...interface{})

	Fatal(...interface{})
	Fatalf(string, ...interface{})
	Fatalln(...interface{})

	Panic(...interface{})
	Panicf(string, ...interface{})
	Panicfv(interface{}, string, ...interface{})
	Panicln(...interface{})

	Print(...interface{})
	Printf(string, ...interface{})
	Println(...interface{})

	Trace(...interface{})
	Tracef(string, ...interface{})
	Traceln(...interface{})

	Warn(...interface{})
	Warnf(string, ...interface{})
	Warnln(...interface{})

	With(...interface{}) Flogger
}

func New

func New(router Router, cascade ...interface{}) Flogger

New returns an initialized Flogger.

type MappingRouter

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

MappingRouter is a Router that can modify the message and context before re-routing it to its sub-router.

Conceptually this is somewhat similar to "map" functions in functional programming.

func NewMappingRouter

func NewMappingRouter(subrouter Router, fn func(string, map[string]interface{}) (string, map[string]interface{})) *MappingRouter

NewMappingRouter returns an initialized MappingRouter.

func (*MappingRouter) Route

func (router *MappingRouter) Route(message string, context map[string]interface{}) error

type NonBlockingRouter

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

NonBlockingRouter is a Router when its Route method is call its does not block and dealing with the routing in parallel.

Note that this means that if the application could terminate before this completes.

func NewNonBlockingRouter

func NewNonBlockingRouter(subrouter Router) *NonBlockingRouter

NewNonBlockingRouter returns an initialized NonBlockingRouter.

func (*NonBlockingRouter) Route

func (router *NonBlockingRouter) Route(message string, context map[string]interface{}) error

type PrettyWritingRouter

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

PrettyWritingRouter is a router that writes a pretty version of the log it was give (including COLORS!) to the writer it was given when it was created.

A PrettyWritingRouter is appropriate for a development (i.e., "DEV") deployment enviornment. (And probably not appropriate a production (i.e., "PROD") deployment environment.)

func NewPrettyWritingRouter

func NewPrettyWritingRouter(writer io.Writer) *PrettyWritingRouter

PrettyWritingRouter returns an initialized PrettyWritingRouter

func (*PrettyWritingRouter) Route

func (router *PrettyWritingRouter) Route(message string, context map[string]interface{}) error

type Router

type Router interface {
	Route(message string, context map[string]interface{}) error
}

Jump to

Keyboard shortcuts

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