deck

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 7, 2023 License: Apache-2.0 Imports: 4 Imported by: 13

README

Deck - Flexible Logging Framework for Go

The Deck package provides a flexible logging framework for Go apps. Deck supports Windows Event Log, syslog, Go's standard logging, logging to file, and log replays for testing. Deck is extensible, so new log backends can integrate seamlessly into existing application code.

Standard Logging

Deck can be a drop in replacement for some other logging packages, with support for common functions like Info, Error, & Warning. The standard logging functions write their outputs immediately and don't support additional attributes.

deck.Info("an info message")
deck.Errorf("an %v message", errors.New("error!"))

Extensible Logging with Attributes

Sometimes we want to be able to pass more complex inputs to our log messages. Deck facilitates this by allowing custom attributes to be attached to log messages.

When using the Attribute-supporting log functions, the message isn't output immediately. We use the With() function to attach additional metadata to the message first. The metadata can be anything supported by an attached backend. Once fully marked up with attributes, the Go() function then performs the final write of the message.

In this example, a log message is marked with Verbosity level 2. Verbosity can be used to dynamically show or hide log events at runtime.

deck.InfoA("a verbose message").With(deck.V(2)).Go()

The EventLog backend for Windows supports Event IDs:

deck.InfoA("a windows event").With(eventlog.EventID(123)).Go()

Multiple attributes can be attributed to the same message:

deck.InfoA("a verbose windows event").With(eventlog.EventID(123), deck.V(3)).Go()

Backends

Deck's logging functionality revolves around backends. A backend is any logging destination that deck should write messages to. Backends are plug-and-play, so you can reconfigure your application's logging behavior simply by adding and removing different backends.

import (
  "github.com/google/deck"
  "github.com/google/deck/backends/logger"
)

deck.Add(logger.Init(os.Stdout, 0))

Cross-platform builds can support platform-specific log outputs by calling Add from platform-specific source files.

// my_app_windows.go

func init() {
  evt, err := eventlog.Init("My App")
  if err != nil {
    panic(err)
  }
  deck.Add(evt)
}
// my_app_linux.go

func init() {
  sl, err := syslog.Init("my-app", syslog.LOG_USER)
  if err != nil {
    panic(err)
  }
  deck.Add(sl)
}
eventlog Backend

The eventlog backend is for Windows only. This backend supports logging to the Windows Event Log. It exports the EventID attribute that allows logging messages with custom Event IDs.

eventlog Documentation.

logger Backend

The logger backend is based on Go's core log package. It can take any io.Writer, including os.Stdout, os.Stderr, io.Multiwriter, and any open file handles.

logger Documentation.

syslog Backend

The syslog backend is based on Go's core syslog package for Linux/Unix.

syslog Documentation.

discard Backend

The discard backend discards all log events. Deck requires at least one backend to be registered to handle logs. To suppress all output, add the discard backend.

discard Documentation.

glog Backend

The glog backend provides support for logging to the glog package from github.com/golang/glog. This backend supports the Depth attribute as well as exporting a V() attribute for glog's V-style logging.

glog Documentation.

replay Backend

The replay backend provides the ability to record and replay log events for use in testing.

replay Documentation.

Message Verbosity

Verbosity is a special attribute implemented by the deck core package. The V() function decorates logs with a custom verbosity, and the SetVerbosity() function determines which verbosity levels get output. This allows the verbosity level to be changed at runtime, such as via a flag or setting.

deck.SetVerbosity(*verbosityFlag)
...
log.InfoA("a level one message").With(deck.V(1)).Go()
log.InfoA("a level three message").With(deck.V(3)).Go()

In this example, if verbosityFlag is 2 or lower, only "a level one message" will print. If it's 3 or higher, both messages will print. Verbosity defaults to 0, and all non-Attribute functions will be at verbosity 0.

Custom Decks

The deck package builds a global deck whenever it's imported, and most implementations can just use this deck directly via the package-level logging functions. For more advanced use cases, multiple decks can be constructed using deck.New(). Each deck can have its own set of attached backends, and supports the same functionality as the global deck.

Documentation

Overview

Package deck is a Flexible Logging Framework for Go.

Example
package main

import (
	"errors"
	"io"
	"io/ioutil"
	"os"

	"github.com/google/deck"
	"github.com/google/deck/backends/logger"
)

// The global instance of deck can be configured during init, main, or anywhere else, as long
// as it happens before log messages are used.
func init() {
	f, err := ioutil.TempFile("", "deck_example")
	if err != nil {
		panic(err)
	}

	// logger supports an io.Writer, so we can pass a single writer or a multiwriter
	mw := io.MultiWriter(os.Stdout, f)

	// Add the backends we want to the global deck instance.
	deck.Add(logger.Init(mw, 0))
}

func WriteToDeck(d *deck.Deck) {
	d.Infoln("hello from WriteToDeck")
}

func main() {
	// The global deck can be used in any package by referencing the top level deck package functions.
	deck.Info("this is the start of the example")
	deck.Errorf("this is an example error: %v", errors.New("oh no"))

	// Custom decks can also be initialized with separate settings and passed around.
	anotherDeck := deck.New()
	defer anotherDeck.Close()
	anotherDeck.Add(logger.Init(os.Stderr, 0))
	WriteToDeck(anotherDeck)
	anotherDeck.Info("this is the end of the example")
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Add

func Add(b Backend)

Add adds a backend to the default log deck.

func Close

func Close()

Close closes all backends in the default deck.

func Depth

func Depth(d int) func(*AttribStore)

Depth is a general attribute that allows specifying log depth to backends. Depth may be used to modify log rendering under certain circumstances.

func Error

func Error(message ...any)

Error immediately logs a message with no attributes to the default deck at the ERROR level.

func Errorf

func Errorf(format string, message ...any)

Errorf immediately logs a message with no attributes according to the format specifier to the default deck at the ERROR level.

func Errorln

func Errorln(message ...any)

Errorln immediately logs a message with no attributes and with a trailing newline to the default deck at the ERROR level.

func Fatal

func Fatal(message ...any)

Fatal immediately logs a message with no attributes to the default deck at the FATAL level.

func Fatalf

func Fatalf(format string, message ...any)

Fatalf immediately logs a message with no attributes according to the format specifier to the default deck at the FATAL level.

func Fatalln

func Fatalln(message ...any)

Fatalln immediately logs a message with no attributes and with a trailing newline to the default deck at the FATAL level.

func Info

func Info(message ...any)

Info immediately logs a message with no attributes to the default deck at the INFO level.

Example
package main

import (
	"github.com/google/deck"
)

func main() {
	deck.Info("This is a simple log line.")
}
Output:

func Infof

func Infof(format string, message ...any)

Infof immediately logs a message with no attributes according to the format specifier to the default deck at the INFO level.

Example
package main

import (
	"github.com/google/deck"
)

func main() {
	deck.Infof("Is this a %s line? %t", "format", true)
}
Output:

func Infoln

func Infoln(message ...any)

Infoln immediately logs a message with no attributes and with a trailing newline to the default deck at the INFO level.

func SetVerbosity

func SetVerbosity(v int)

SetVerbosity sets the internal verbosity level of the default deck.

func V

func V(v int) func(*AttribStore)

V is a special attribute that sets the verbosity level on a message.

deck.Info("example with verbosity 2").V(2).Go()

func Warning

func Warning(message ...any)

Warning immediately logs a message with no attributes to the default deck at the WARNING level.

func Warningf

func Warningf(format string, message ...any)

Warningf immediately logs a message with no attributes according to the format specifier to the default deck at the WARNING level.

func Warningln

func Warningln(message ...any)

Warningln immediately logs a message with no attributes with a trailing newline to the default deck at the WARNING level.

Types

type Attrib

type Attrib func(*AttribStore)

An Attrib is an attribute that can be associated with Logs.

Attributes are actually functions which modify values in the AttribStore.

type AttribStore

type AttribStore = sync.Map

An AttribStore stores unique attributes associated with a given Log.

The store is a string-keyed value map. Backends can interrogate the store for values, and use the values for their own purposes.

type Backend

type Backend interface {
	New(Level, string) Composer
	Close() error
}

Backend is the interface that identifies logging backends with NewMessage and Close methods.

type Composer

type Composer interface {
	Compose(s *AttribStore) error
	Write() error
}

Composer is the interface that groups Compose and Write methods.

type Deck

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

The Deck is the highest level of the logging hierarchy, consisting of one or more backends. All logs written to the deck get flushed to each backend. Multiple decks can be configured with their own sets of backends.

func Default

func Default() *Deck

Default returns the default (global) deck.

func New

func New() *Deck

New returns a new initialized log deck.

func (*Deck) Add

func (d *Deck) Add(b Backend)

Add adds an additional backend to the deck.

func (*Deck) Close

func (d *Deck) Close()

Close closes all backends in the deck.

func (*Deck) Error

func (d *Deck) Error(message ...any)

Error immediately logs a message with no attributes at the ERROR level.

func (*Deck) ErrorA

func (d *Deck) ErrorA(message ...any) *Log

ErrorA constructs a message at the ERROR level.

func (*Deck) Errorf

func (d *Deck) Errorf(format string, message ...any)

Errorf immediately logs a message with no attributes according to the format specifier at the ERROR level.

func (*Deck) ErrorfA

func (d *Deck) ErrorfA(format string, message ...any) *Log

ErrorfA constructs a message according to the format specifier at the ERROR level.

func (*Deck) Errorln

func (d *Deck) Errorln(message ...any)

Errorln immediately logs a message with no attributes and with a trailing newline at the ERROR level.

func (*Deck) ErrorlnA

func (d *Deck) ErrorlnA(message ...any) *Log

ErrorlnA constructs a message with a trailing newline at the ERROR level.

func (*Deck) Fatal

func (d *Deck) Fatal(message ...any)

Fatal immediately logs a message with no attributes at the FATAL level.

func (*Deck) FatalA

func (d *Deck) FatalA(message ...any) *Log

FatalA constructs a message at the FATAL level.

func (*Deck) Fatalf

func (d *Deck) Fatalf(format string, message ...any)

Fatalf immediately logs a message with no attributes according to the format specifier at the FATAL level.

func (*Deck) FatalfA

func (d *Deck) FatalfA(format string, message ...any) *Log

FatalfA constructs a message according to the format specifier at the FATAL level.

func (*Deck) Fatalln

func (d *Deck) Fatalln(message ...any)

Fatalln immediately logs a message with no attributes and with a trailing newline at the FATAL level.

func (*Deck) FatallnA

func (d *Deck) FatallnA(message ...any) *Log

FatallnA constructs a message with a trailing newline at the FATAL level.

func (*Deck) Info

func (d *Deck) Info(message ...any)

Info immediately logs a message with no attributes at the INFO level.

func (*Deck) InfoA

func (d *Deck) InfoA(message ...any) *Log

InfoA constructs a message at the INFO level.

func (*Deck) Infof

func (d *Deck) Infof(format string, message ...any)

Infof immediately logs a message with no attributes according to the format specifier at the INFO level.

func (*Deck) InfofA

func (d *Deck) InfofA(format string, message ...any) *Log

InfofA constructs a message according to the format specifier at the INFO level.

func (*Deck) Infoln

func (d *Deck) Infoln(message ...any)

Infoln immediately logs a message with no attributes and with a trailing newline at the INFO level.

func (*Deck) InfolnA

func (d *Deck) InfolnA(message ...any) *Log

InfolnA constructs a message with a trailing newline at the INFO level.

func (*Deck) SetVerbosity

func (d *Deck) SetVerbosity(v int)

SetVerbosity sets the internal verbosity level of the deck.

Messages are committed if the message's own verbosity level (default 0) is equal to or less than the deck's configured level.

func (*Deck) Warning

func (d *Deck) Warning(message ...any)

Warning immediately logs a message with no attributes at the WARNING level.

func (*Deck) WarningA

func (d *Deck) WarningA(message ...any) *Log

WarningA constructs a message at the WARNING level.

func (*Deck) Warningf

func (d *Deck) Warningf(format string, message ...any)

Warningf immediately logs a message with no attributes according to the format specifier at the WARNING level.

func (*Deck) WarningfA

func (d *Deck) WarningfA(format string, message ...any) *Log

WarningfA constructs a message according to the format specifier at the WARNING level.

func (*Deck) Warningln

func (d *Deck) Warningln(message ...any)

Warningln immediately logs a message with no attributes and with a trailing newline at the WARNING level.

func (*Deck) WarninglnA

func (d *Deck) WarninglnA(message ...any) *Log

WarninglnA constructs a message with a trailing newline at the WARNING level.

type Level

type Level uint

A Level is a recognized log level (Info, Error, etc). Behavior of a given level is backend-dependent, but they are generally used to determine how to tag, route, or mark-up individual log lines.

Levels should not be confused with the V() attribute. V() is used to set log verbosity, which can be used to include or exclude logging of events, regardless of their associated level.

const (
	DEBUG Level = iota
	INFO
	WARNING
	ERROR
	FATAL
)

type Log

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

Log is a single log event that will be flushed to all registered backends.

Each log may have one or more attributes associated with it.

func ErrorA

func ErrorA(message ...any) *Log

ErrorA constructs a message in the default deck at the ERROR level.

func ErrorfA

func ErrorfA(format string, message ...any) *Log

ErrorfA constructs a message according to the format specifier in the default deck at the ERROR level.

func ErrorlnA

func ErrorlnA(message ...any) *Log

ErrorlnA constructs a message with a trailing newline in the default deck at the ERROR level.

func FatalA

func FatalA(message ...any) *Log

FatalA constructs a message in the default deck at the FATAL level.

func FatalfA

func FatalfA(format string, message ...any) *Log

FatalfA constructs a message according to the format specifier in the default deck at the FATAL level.

func FatallnA

func FatallnA(message ...any) *Log

FatallnA constructs a message with a trailing newline in the default deck at the FATAL level.

func InfoA

func InfoA(message ...any) *Log

InfoA constructs a message in the default deck at the INFO level.

func InfofA

func InfofA(format string, message ...any) *Log

InfofA constructs a message according to the format specifier in the default deck at the INFO level.

func InfolnA

func InfolnA(message ...any) *Log

InfolnA constructs a message with a trailing newline in the default deck at the INFO level.

func NewLog

func NewLog(verbosity int) *Log

NewLog returns a new Log

func WarningA

func WarningA(message ...any) *Log

WarningA constructs a message in the default deck at the WARNING level.

func WarningfA

func WarningfA(format string, message ...any) *Log

WarningfA constructs a message according to the format specifier in the default deck at the WARNING level.

func WarninglnA

func WarninglnA(message ...any) *Log

WarninglnA constructs a message with a trailing newline in the default deck at the WARNING level.

func (*Log) Go

func (l *Log) Go()

Go commits a Log to all registered backends in the deck.

func (*Log) With

func (l *Log) With(attrs ...Attrib) *Log

With appends one or more attributes to a Log.

deck.Info("message with attributes").With(V(2), EventID(3))

Directories

Path Synopsis
backends
discard
Package discard provides a deck backend that discards all logs.
Package discard provides a deck backend that discards all logs.
eventlog
Package eventlog is a deck backend for writing log messages to Windows Event Log.
Package eventlog is a deck backend for writing log messages to Windows Event Log.
glog
Package glog provides a deck backend for github.com/golang/glog.
Package glog provides a deck backend for github.com/golang/glog.
logger
Package logger provides a deck backend that leverages Go's core log package.
Package logger provides a deck backend that leverages Go's core log package.
replay
Package replay provides a deck backend for replaying log messages.
Package replay provides a deck backend for replaying log messages.
syslog
Package syslog provides a deck backend for syslog.
Package syslog provides a deck backend for syslog.

Jump to

Keyboard shortcuts

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