logging

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2021 License: BSD-3-Clause Imports: 17 Imported by: 23

README

Golang logging library

godoc build

Package logging implements a logging infrastructure for Go. Its output format is customizable and supports different logging backends like syslog, file and memory. Multiple backends can be utilized with different log levels per backend and logger.

Example

Let's have a look at an example which demonstrates most of the features found in this library.

Example Output

package main

import (
	"os"

	"github.com/moisespsena-go/logging"
)

var log = logging.MustGetLogger("example")

// Example format string. Everything except the message has a custom color
// which is dependent on the log level. Many fields have a custom output
// formatting too, eg. the time returns the hour down to the milli second.
var format = logging.MustStringFormatter(
	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)

// Password is just an example type implementing the Redactor interface. Any
// time this is logged, the Redacted() function will be called.
type Password string

func (p Password) Redacted() interface{} {
	return logging.Redact(string(p))
}

func main() {
	// For demo purposes, create two backend for os.Stderr.
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend2 := logging.NewLogBackend(os.Stderr, "", 0)

	// For messages written to backend2 we want to add some additional
	// information to the output, including the used log level and the name of
	// the function.
	backend2Formatter := logging.NewBackendFormatter(backend2, format)

	// Only errors and more severe messages should be sent to backend1
	backend1Leveled := logging.AddModuleLevel(backend1)
	backend1Leveled.SetLevel(logging.ERROR, "")

	// Set the backends to be used.
	logging.SetBackend(backend1Leveled, backend2Formatter)

	log.Debugf("debug %s", Password("secret"))
	log.Info("info")
	log.Notice("notice")
	log.Warning("warning")
	log.Error("err")
	log.Critical("crit")
}

Installing

Using go get

$ go get github.com/moisespsena-go/logging

After this command go-logging is ready to use. Its source will be in:

$GOPATH/src/pkg/github.com/moisespsena-go/logging

You can use go get -u github.com/moisespsena-go/logging to update the package.

Documentation

For docs, see http://godoc.org/github.com/moisespsena-go/logging or run:

$ godoc github.com/moisespsena-go/logging

Additional resources

  • wslog -- exposes log messages through a WebSocket.

Documentation

Overview

Package logging implements a logging infrastructure for Go. It supports different logging backends like syslog, file and memory. Multiple backends can be utilized with different log levels per backend and logger.

Example
// This call is for testing purposes and will set the time to unix epoch.
InitForTesting(DEBUG)

var log = GetOrCreateLogger("example")

// For demo purposes, create two backend for os.Stdout.
//
// os.Stderr should most likely be used in the real world but then the
// "Output:" check in this example would not work.
backend1 := NewLogBackend(os.Stdout, "", 0)
backend2 := NewLogBackend(os.Stdout, "", 0)

// For messages written to backend2 we want to add some additional
// information to the output, including the used log level and the name of
// the function.
var format = MustStringFormatter(
	`%{time:15:04:05.000} %{shortfunc} %{level:.1s} %{message}`,
)
backend2Formatter := NewBackendFormatter(backend2, format)

// Only errors and more severe messages should be sent to backend2
backend2Leveled := AddModuleLevel(backend2Formatter)
backend2Leveled.SetLevel(ERROR, "")

// Set the backends to be used and the default level.
SetBackend(backend1, backend2Leveled)

log.Debugf("debug %s", "arg")
log.Error("error")
Output:

debug arg
error
00:00:00.000 Example E error

Index

Examples

Constants

View Source
const (
	ColorBlack = iota + 30
	ColorRed
	ColorGreen
	ColorYellow
	ColorBlue
	ColorMagenta
	ColorCyan
	ColorWhite
)

Variables

View Source
var (
	// DefaultFormatter is the default formatter used and is only the message.
	DefaultFormatter = MustStringFormatter("%{message}")

	// GlogFormatter mimics the glog format
	GlogFormatter = MustStringFormatter("%{level:.1s}%{time:0102 15:04:05.999999} %{pid} %{shortfile}] %{message}")
)
View Source
var ErrInvalidLogLevel = errors.New("logger: invalid log level")

ErrInvalidLogLevel is used when an invalid log level has been used.

View Source
var MustGetLogger = GetOrCreateLogger

Functions

func ColorSeq

func ColorSeq(color color) string

func ColorSeqBold

func ColorSeqBold(color color) string

func ConvertColors

func ConvertColors(colors []int, bold bool) []string

ConvertColors takes a list of ints representing colors for log levels and converts them into strings for ANSI color formatting

func Redact

func Redact(s string) string

Redact returns a string of * having the same length as s.

func Reset

func Reset()

Reset restores the internal state of the logging library.

func SetFormatter

func SetFormatter(f Formatter)

SetFormatter sets the default formatter for all new backends. A backend will fetch this value once it is needed to format a record. Note that backends will cache the formatter after the first point. For now, make sure to set the formatter before logging.

func SetLevel

func SetLevel(level Level, module string)

SetLevel sets the logging level for the specified module. The module corresponds to the string specified in GetOrCreateLogger.

func SetLogLevel

func SetLogLevel(log Logger, level Level, module string)

SetLogLevel sets the logging level for the specified module in Log.

Types

type Backend

type Backend interface {
	Log(Level, int, *Record) error
}

Backend is the interface which a log backend need to implement to be able to be used as a logging backend.

func NewBackendFormatter

func NewBackendFormatter(b Backend, f Formatter) Backend

NewBackendFormatter creates a new backend which makes all records that passes through it beeing formatted by the specific formatter.

type BackendCloser

type BackendCloser interface {
	Backend
	io.Closer
}

BackendCloser is the interface which a closeable log backend need to implement to be able to be used as a logging backend.

func NewBackendClose

func NewBackendClose(backend Backend, closer ...io.Closer) BackendCloser

func NewBackendPrintClose

func NewBackendPrintClose(backend Backend, closer ...io.Closer) BackendCloser

type BackendPrintCloser

type BackendPrintCloser interface {
	BackendPrinter
	io.Closer
}

BackendPrintCloser is the interface which a log backend with Print and Closer methods need to implement to be able to be used as a logging backend.

type BackendPrinter

type BackendPrinter interface {
	Backend
	Printer
}

BackendPrinter is the interface which a log backend with Print method need to implement to be able to be used as a logging backend.

type Basic

type Basic struct {

	// ExtraCallDepth can be used to add additional call depth when getting the
	// calling function. This is normally used when wrapping a logger.
	ExtraCalldepth int
	// contains filtered or unexported fields
}

func NewBasic

func NewBasic(writer LogWriter) Basic

NewBasic creates Basic with writer

func (Basic) Critical

func (l Basic) Critical(args ...interface{})

Critical logs a message using CRITICAL as log level.

func (Basic) Criticalf

func (l Basic) Criticalf(format string, args ...interface{})

Criticalf logs a message using CRITICAL as log level.

func (Basic) Debug

func (l Basic) Debug(args ...interface{})

Debug logs a message using DEBUG as log level.

func (Basic) Debugf

func (l Basic) Debugf(format string, args ...interface{})

Debugf logs a message using DEBUG as log level.

func (Basic) Error

func (l Basic) Error(args ...interface{})

Error logs a message using ERROR as log level.

func (Basic) Errorf

func (l Basic) Errorf(format string, args ...interface{})

Errorf logs a message using ERROR as log level.

func (Basic) Fatal

func (l Basic) Fatal(args ...interface{})

Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1).

func (Basic) Fatalf

func (l Basic) Fatalf(format string, args ...interface{})

Fatalf is equivalent to l.Critical followed by a call to os.Exit(1).

func (Basic) Info

func (l Basic) Info(args ...interface{})

Info logs a message using INFO as log level.

func (Basic) Infof

func (l Basic) Infof(format string, args ...interface{})

Infof logs a message using INFO as log level.

func (Basic) Notice

func (l Basic) Notice(args ...interface{})

Notice logs a message using NOTICE as log level.

func (Basic) Noticef

func (l Basic) Noticef(format string, args ...interface{})

Noticef logs a message using NOTICE as log level.

func (Basic) Panic

func (l Basic) Panic(args ...interface{})

Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic().

func (Basic) Panicf

func (l Basic) Panicf(format string, args ...interface{})

Panicf is equivalent to l.Critical followed by a call to panic().

func (Basic) Warning

func (l Basic) Warning(args ...interface{})

Warning logs a message using WARNING as log level.

func (Basic) Warningf

func (l Basic) Warningf(format string, args ...interface{})

Warningf logs a message using WARNING as log level.

func (Basic) Writer

func (l Basic) Writer() LogWriter

type ChannelMemoryBackend

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

ChannelMemoryBackend is very similar to the MemoryBackend, except that it internally utilizes a channel.

func NewChannelMemoryBackend

func NewChannelMemoryBackend(size int) *ChannelMemoryBackend

NewChannelMemoryBackend creates a simple in-memory logging backend which utilizes a go channel for communication.

Start will automatically be called by this function.

func (*ChannelMemoryBackend) Flush

func (b *ChannelMemoryBackend) Flush()

Flush waits until all records in the buffered channel have been processed.

func (*ChannelMemoryBackend) Head

func (b *ChannelMemoryBackend) Head() *node

Head returns the oldest record node kept in memory. It can be used to iterate over records, one by one, up to the last record.

Note: new records can get added while iterating. Hence the number of records iterated over might be larger than the maximum size.

func (*ChannelMemoryBackend) Log

func (b *ChannelMemoryBackend) Log(level Level, calldepth int, rec *Record) error

Log implements the Log method required by Backend.

func (*ChannelMemoryBackend) Start

func (b *ChannelMemoryBackend) Start()

Start launches the internal goroutine which starts processing data from the input channel.

func (*ChannelMemoryBackend) Stop

func (b *ChannelMemoryBackend) Stop()

Stop signals the internal goroutine to exit and waits until it have.

type Formatter

type Formatter interface {
	Format(calldepth int, r *Record, w io.Writer) error
}

Formatter is the required interface for a custom log record formatter.

func MustStringFormatter

func MustStringFormatter(format string) Formatter

MustStringFormatter is equivalent to NewStringFormatter with a call to panic on error.

func NewStringFormatter

func NewStringFormatter(format string) (Formatter, error)

NewStringFormatter returns a new Formatter which outputs the log record as a string based on the 'verbs' specified in the format string.

The verbs:

General:

%{id}        Sequence number for log message (uint64).
%{pid}       Process id (int)
%{time}      Time when log occurred (time.Time)
%{level}     Log level (Level)
%{module}    Module (string)
%{program}   Basename of os.Args[0] (string)
%{message}   Message (string)
%{longfile}  Full file name and line number: /a/b/c/d.go:23
%{shortfile} Final file name element and line number: d.go:23
%{callpath}  Callpath like main.a.b.c...c  "..." meaning recursive call ~. meaning truncated path
%{color}     ANSI color based on log level

For normal types, the output can be customized by using the 'verbs' defined in the fmt package, eg. '%{id:04d}' to make the id output be '%04d' as the format string.

For time.Time, use the same layout as time.Format to change the time format when output, eg "2006-01-02T15:04:05.999Z-07:00".

For the 'color' verb, the output can be adjusted to either use bold colors, i.e., '%{color:bold}' or to reset the ANSI attributes, i.e., '%{color:reset}' Note that if you use the color verb explicitly, be sure to reset it or else the color state will persist past your log message. e.g., "%{color:bold}%{time:15:04:05} %{level:-8s}%{color:reset} %{message}" will just colorize the time and level, leaving the message uncolored.

For the 'callpath' verb, the output can be adjusted to limit the printing the stack depth. i.e. '%{callpath:3}' will print '~.a.b.c'

Colors on Windows is unfortunately not supported right now and is currently a no-op.

There's also a couple of experimental 'verbs'. These are exposed to get feedback and needs a bit of tinkering. Hence, they might change in the future.

Experimental:

%{longpkg}   Full package path, eg. github.com/go-logging
%{shortpkg}  Base package path, eg. go-logging
%{longfunc}  Full function name, eg. littleEndian.PutUint32
%{shortfunc} Base function name, eg. PutUint32
%{callpath}  Call function path, eg. main.a.b.c

type Level

type Level int

Level defines all available log levels for log messages.

const (
	CRITICAL Level = iota
	ERROR
	WARNING
	NOTICE
	INFO
	DEBUG
)

Log levels.

func GetLevel

func GetLevel(module string) Level

GetLevel returns the logging level for the specified module.

func GetLogLevel

func GetLogLevel(log Logger, module string) Level

GetLogLevel returns the logging level for the specified module in Log.

func LogLevel

func LogLevel(level string) (Level, error)

LogLevel returns the log level from a string representation.

func (Level) String

func (p Level) String() string

String returns the string representation of a logging level.

type Leveled

type Leveled interface {
	GetLevel(string) Level
	SetLevel(Level, string)
	IsEnabledFor(Level, string) bool
}

Leveled interface is the interface required to be able to add leveled logging.

type LeveledBackend

type LeveledBackend interface {
	Backend
	Leveled
}

LeveledBackend is a log backend with additional knobs for setting levels on individual modules to different levels.

func AddModuleLevel

func AddModuleLevel(backend Backend) LeveledBackend

AddModuleLevel wraps a log backend with knobs to have different log levels for different modules.

func DefaultBackendProxy

func DefaultBackendProxy() LeveledBackend

func MultiLogger

func MultiLogger(backends ...Backend) LeveledBackend

MultiLogger creates a logger which contain multiple loggers.

func SetBackend

func SetBackend(backends ...Backend) LeveledBackend

SetBackend replaces the backend currently set with the given new logging backend.

type LeveledBackendProxy

type LeveledBackendProxy struct {
	Get func() LeveledBackend
}

func NewLeveledBackendProxy

func NewLeveledBackendProxy(get func() LeveledBackend) *LeveledBackendProxy

func (LeveledBackendProxy) GetLevel

func (this LeveledBackendProxy) GetLevel(module string) Level

func (LeveledBackendProxy) IsEnabledFor

func (this LeveledBackendProxy) IsEnabledFor(level Level, module string) bool

func (LeveledBackendProxy) Log

func (this LeveledBackendProxy) Log(level Level, calldepth int, rec *Record) error

func (LeveledBackendProxy) SetLevel

func (this LeveledBackendProxy) SetLevel(level Level, module string)

type Log

type Log struct {
	Basic
	Module string
	// contains filtered or unexported fields
}

Log is the actual logger which creates log records based on the functions called and passes them to the underlying logging backend.

func NewLogger

func NewLogger(module string) *Log

NewLogger crates new Log object with module name

func (*Log) Backend

func (l *Log) Backend() LeveledBackend

Backend return current backend if has be defined

func (*Log) IsEnabledFor

func (l *Log) IsEnabledFor(level Level) bool

IsEnabledFor returns true if the logger is enabled for the given level.

func (*Log) SetBackend

func (l *Log) SetBackend(backend LeveledBackend)

SetBackend overrides any previously defined backend for this logger.

type LogBackend

type LogBackend struct {
	Logger      *log.Logger
	Color       bool
	ColorConfig []string
}

LogBackend utilizes the standard log module.

func NewLogBackend

func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend

NewLogBackend creates a new LogBackend.

func (*LogBackend) Log

func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error

Log implements the Backend interface.

type LogPrefix

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

func (LogPrefix) Critical

func (this LogPrefix) Critical(args ...interface{})

func (LogPrefix) Criticalf

func (this LogPrefix) Criticalf(format string, args ...interface{})

func (LogPrefix) Debug

func (this LogPrefix) Debug(args ...interface{})

func (LogPrefix) Debugf

func (this LogPrefix) Debugf(format string, args ...interface{})

func (LogPrefix) Error

func (this LogPrefix) Error(args ...interface{})

func (LogPrefix) Errorf

func (this LogPrefix) Errorf(format string, args ...interface{})

func (LogPrefix) Fatal

func (this LogPrefix) Fatal(args ...interface{})

func (LogPrefix) Fatalf

func (this LogPrefix) Fatalf(format string, args ...interface{})

func (LogPrefix) Info

func (this LogPrefix) Info(args ...interface{})

func (LogPrefix) Infof

func (this LogPrefix) Infof(format string, args ...interface{})

func (LogPrefix) Notice

func (this LogPrefix) Notice(args ...interface{})

func (LogPrefix) Noticef

func (this LogPrefix) Noticef(format string, args ...interface{})

func (LogPrefix) Panic

func (this LogPrefix) Panic(args ...interface{})

func (LogPrefix) Panicf

func (this LogPrefix) Panicf(format string, args ...interface{})

func (LogPrefix) Parent

func (this LogPrefix) Parent() Logger

func (LogPrefix) Prefix

func (this LogPrefix) Prefix() string

func (LogPrefix) SetPrefix

func (this LogPrefix) SetPrefix(v string)

func (LogPrefix) Warning

func (this LogPrefix) Warning(args ...interface{})

func (LogPrefix) Warningf

func (this LogPrefix) Warningf(format string, args ...interface{})

type LogPrefixer

type LogPrefixer interface {
	Logger
	Prefix() string
	Parent() Logger
}

LogPrefixer is an interface for types that creates log records with prefix.

func WithPrefix

func WithPrefix(parent Logger, prefix string, sep ...string) LogPrefixer

type LogWriter

type LogWriter interface {
	Write(lvl Level, extraCalldepth int, format *string, args ...interface{})
}

func DefaultWriter

func DefaultWriter(l Logger, module string) LogWriter

func NewWriter

func NewWriter(f func(lvl Level, extraCalldepth int, format *string, args ...interface{})) LogWriter

type Logger

type Logger interface {
	IsEnabledFor(level Level) bool

	// SetBackend overrides any previously defined backend for this logger.
	SetBackend(backend LeveledBackend)
	// Backend return current backend if has be defined
	Backend() LeveledBackend

	Fatal(args ...interface{})
	Fatalf(format string, args ...interface{})
	Panic(args ...interface{})
	Panicf(format string, args ...interface{})
	Critical(args ...interface{})
	Criticalf(format string, args ...interface{})
	Error(args ...interface{})
	Errorf(format string, args ...interface{})

	// Warning logs a message using WARNING as log level.
	Warning(args ...interface{})
	// Warningf logs a message using WARNING as log level.
	Warningf(format string, args ...interface{})
	// Notice logs a message using NOTICE as log level.
	Notice(args ...interface{})
	// Noticef logs a message using NOTICE as log level.
	Noticef(format string, args ...interface{})
	// Info logs a message using INFO as log level.
	Info(args ...interface{})
	// Infof logs a message using INFO as log level.
	Infof(format string, args ...interface{})
	// Debug logs a message using DEBUG as log level.
	Debug(args ...interface{})
	// Debugf logs a message using DEBUG as log level.
	Debugf(format string, args ...interface{})
	// Writer returns the log writer.
	Writer() LogWriter
}

Logger is an interface for types that creates log records based on the functions called and passes them to the underlying logging backend.

func GetLogger

func GetLogger(module string) Logger

GetLogger returns a Logger object based on the module name registered in Loggers.

func GetOrCreateLogger

func GetOrCreateLogger(module string) Logger

GetOrCreateLogger returns a Logger object is has be registered in Loggers, other wise, creates and registry new object

func MainLogger

func MainLogger() Logger

MainLogger returns a Logger object based on the sys.Argv[0].

func Tee

func Tee(logger ...Logger) Logger

Tee copy log messages to all loggers.

type MemoryBackend

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

MemoryBackend is a simple memory based logging backend that will not produce any output but merly keep records, up to the given size, in memory.

func InitForTesting

func InitForTesting(level Level) *MemoryBackend

InitForTesting is a convenient method when using logging in a test. Once called, the time will be frozen to January 1, 1970 UTC.

func NewMemoryBackend

func NewMemoryBackend(size int) *MemoryBackend

NewMemoryBackend creates a simple in-memory logging backend.

func (*MemoryBackend) Head

func (b *MemoryBackend) Head() *node

Head returns the oldest record node kept in memory. It can be used to iterate over records, one by one, up to the last record.

Note: new records can get added while iterating. Hence the number of records iterated over might be larger than the maximum size.

func (*MemoryBackend) Log

func (b *MemoryBackend) Log(level Level, calldepth int, rec *Record) error

Log implements the Log method required by Backend.

type MustPrint

type MustPrint func(args ...interface{}) (err error)

func (MustPrint) Print

func (this MustPrint) Print(args ...interface{})

type Printer

type Printer interface {
	Print(args ...interface{}) (err error)
}

type PrinterLeveledBackend

type PrinterLeveledBackend interface {
	BackendPrinter
	Leveled
}

type Record

type Record struct {
	ID     uint64
	Time   time.Time
	Module string
	Level  Level
	Args   []interface{}
	// contains filtered or unexported fields
}

Record represents a log record and contains the timestamp when the record was created, an increasing id, filename and line and finally the actual formatted log line.

func (*Record) Data

func (r *Record) Data() RecordData

Data returns the RecordData object.

func (*Record) Formatted

func (r *Record) Formatted(calldepth int) string

Formatted returns the formatted log record string.

func (*Record) Message

func (r *Record) Message() string

Message returns the log record message.

type RecordData

type RecordData struct {
	ID      uint64
	Time    time.Time
	Module  string
	Level   Level
	Message string
}

Record representslog static record and contains the timestamp when the record was created, an increasing id, filename and line and finally the actual formatted log line.

type Redactor

type Redactor interface {
	Redacted() interface{}
}

Redactor is an interface for types that may contain sensitive information (like passwords), which shouldn't be printed to the log. The idea was found in relog as part of the vitness project.

type SyncedLoggers

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

SyncedLoggers represents a parallel by module Logger registrator

func (*SyncedLoggers) Get

func (this *SyncedLoggers) Get(module string) Logger

Get returns a Logger object is has be registered, other wise, nil

func (*SyncedLoggers) GetOrCreate

func (this *SyncedLoggers) GetOrCreate(module string) (log Logger)

GetOrCreate returns a Logger object is has be registered, other wise, creates and registry new object

type SyslogBackend

type SyslogBackend struct {
	Writer *syslog.Writer
}

SyslogBackend is a simple logger to syslog backend. It automatically maps the internal log levels to appropriate syslog log levels.

func NewSyslogBackend

func NewSyslogBackend(prefix string) (b *SyslogBackend, err error)

NewSyslogBackend connects to the syslog daemon using UNIX sockets with the given prefix. If prefix is not given, the prefix will be derived from the launched command.

func NewSyslogBackendPriority

func NewSyslogBackendPriority(prefix string, priority syslog.Priority) (b *SyslogBackend, err error)

NewSyslogBackendPriority is the same as NewSyslogBackend, but with custom syslog priority, like syslog.LOG_LOCAL3|syslog.LOG_DEBUG etc.

func (*SyslogBackend) Log

func (b *SyslogBackend) Log(level Level, calldepth int, rec *Record) error

Log implements the Backend interface.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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