log

package module
v0.15.2 Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2024 License: MPL-2.0 Imports: 16 Imported by: 115

README

Go Reference

log

See the thorough Go package documentation via the badge.

Documentation

Overview

Package log implements a std log compatible logging system that draws some inspiration from the Python logging module from Python's standard library. It supports multiple handlers, log levels, zero-allocation, scopes, custom formatting, and environment and runtime configuration.

When not used to replace std log, the import should use the package name "analog" as in:

import analog "github.com/anacrolix/log"

Names

Each Logger has a sequence of names that are used for filtering and context. Names are commonly attached as Loggers are passed into code of deeper context. The full import path of the package where a message is generated, and the short source file name and line number are added as the last 2 names for each message (applying any Msg.Skip in finding the right frame) when filtering is applied. The names are included at the end of each logging line.

Rules

A sequence of rules are parsed from the environment variable with the key of EnvRules. Rules are separated by ",". Each rule is a substring of a log message name that or "*" to match any name. If there is no "=" in the rule, then all messages that match will be logged. If there is a "=", then a message must have the level following the "=", as parsed by Level.UnmarshalText or higher to be logged. Each rule is checked in order, and the last match takes precedence. This helps when you want to chain new rules on existing ones, you can always append to the end to override earlier rules.

GO_LOG := "" | rule ("," rule)*
rule := filter ("=" level) | ""
filter := name | "*"
level := "all", "debug" | "info" | "warn" | "err" | "crit" | see [Level.UnmarshalText]

Some examples:

  • GO_LOG=*

    Log everything, no matter the level

  • GO_LOG=*=,*,hello=debug

    Log everything, except for any message containing a name with the substring "hello", which must be at least debug level.

  • GO_LOG=something=info

    Handle messages at the info level or greater if they have a name containing "something".

If no rule matches, the Logger's filter level is checked. The Default filter level is Warning. This means only messages with the level of Warning or higher will be logged, unless overridden by the specific Logger in use, or a rule from the environment matches.

Rule reporting

If the environment variable with the key EnvReportRules is not the empty string, each message logged with a previously unseen permutation of names will output a message to a standard library logger with the minimum level required to log that permutation. The message itself is then handled as usual. The same permutation will not be reported on again. This is useful to determine what logging names are in use, and to debug their reporting level thresholds.

Index

Constants

View Source
const (
	EnvRules        = "GO_LOG"
	EnvTimeFormat   = "GO_LOG_TIME_FMT"
	EnvDefaultLevel = "GO_LOG_DEFAULT_LEVEL"
	EnvReportRules  = "GO_LOG_REPORT_RULES"
)

Variables

View Source
var (
	DefaultHandler = StreamHandler{
		W:   os.Stderr,
		Fmt: twoLineFormatter,
	}
	Default        Logger // Inited after GO_LOG is parsed.
	DiscardHandler = StreamHandler{
		W:   io.Discard,
		Fmt: func(Record) []byte { return nil },
	}
)
View Source
var (
	Never    = Level{-1} // A message at this level should never be logged.
	NotSet   = Level{0}
	Debug    = Level{1}
	Info     = Level{2}
	Warning  = Level{3}
	Error    = Level{4}
	Critical = Level{5}
)
View Source
var (
	Panicf = log.Panicf
	Fatalf = log.Fatalf
	Fatal  = log.Fatal
)

Deprecated: Logging shouldn't include control flow.

View Source
var DefaultTimeAppendFormatter = func(b []byte) []byte {
	return time.Now().AppendFormat(b, timeFmt)
}

Preferred and probably faster than DefaultTimeFormatter.

View Source
var DefaultTimeFormatter = func() string {
	return time.Now().Format(timeFmt)
}
View Source
var Fstr = Fmsg
View Source
var TimeAppendFormatSecondsSinceInit = func(b []byte) []byte {
	return fmt.Appendf(b, "%.3fs", time.Since(started).Seconds())
}
View Source
var TimeFormatSecondsSinceInit = func() string {
	return fmt.Sprintf("%.3fs", time.Since(started).Seconds())
}

Functions

func ContextWithLogger added in v0.13.0

func ContextWithLogger(ctx context.Context, logger Logger) context.Context

func GetDefaultTimeAppendFormatter added in v0.14.3

func GetDefaultTimeAppendFormatter() func([]byte) []byte

func Levelf added in v0.10.0

func Levelf(level Level, format string, a ...interface{})

Logs a message to the Default Logger with text formatted in the style of fmt.Printf, with the given Level.

func LineFormatter

func LineFormatter(msg Record) []byte

Formats like: "[2023-12-02 14:34:02 +1100 INF] prefix: text [name name import-path short-file:line]"

func Print

func Print(a ...interface{})

Prints the arguments to the Default Logger in the style of fmt functions of similar names.

func Printf

func Printf(format string, a ...interface{})

Prints the arguments to the Default Logger in the style of fmt functions of similar names.

func Println added in v0.11.0

func Println(a ...interface{})

Prints the arguments to the Default Logger in the style of fmt functions of similar names.

func WithLevel added in v0.14.0

func WithLevel(level Level, err error) error

Adds the error level to err, it can be extracted with ErrorLevel.

Types

type ByteFormatter

type ByteFormatter func(Record) []byte

type Handler added in v0.11.0

type Handler interface {
	Handle(r Record)
}

type Level

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

func ErrorLevel added in v0.14.0

func ErrorLevel(err error) Level

Extracts the most recent error level added to err with WithLevel, or NotSet.

func (Level) LessThan

func (l Level) LessThan(r Level) bool

func (Level) LogString

func (l Level) LogString() string

func (*Level) UnmarshalText added in v0.12.0

func (l *Level) UnmarshalText(text []byte) error

type Loc added in v0.14.0

type Loc struct {
	Package  string
	Function string
	File     string
	Line     int
}

type Logger

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

Logger handles logging in a specific context. It includes a bunch of helpers and compatibility over the loggerCore.

func ContextLogger added in v0.13.0

func ContextLogger(ctx context.Context) Logger

func NewLogger added in v0.14.0

func NewLogger(names ...string) Logger

Returns a new Logger with the names given, and Default's handlers. I'm not sure copying those handlers is the right choice yet, but it's better than having your messages vanish if you forget to configure them.

func (Logger) FilterLevel

func (l Logger) FilterLevel(minLevel Level) Logger

Deprecated. Use WithFilterLevel. This method name is misleading and doesn't follow the convention elsewhere.

func (Logger) IsEnabledFor added in v0.11.0

func (l Logger) IsEnabledFor(level Level) bool

Deprecated. This should require a msg, since filtering includes the location a msg is created at. That would require building a message before we can do checks, which means lazily constructing the message but not the caller location.

func (Logger) IsZero added in v0.9.0

func (l Logger) IsZero() bool

func (Logger) LazyLog added in v0.11.0

func (l Logger) LazyLog(level Level, f func() Msg)

func (Logger) LazyLogDefaultLevel added in v0.11.0

func (l Logger) LazyLogDefaultLevel(f func() Msg)

func (Logger) LevelPrint added in v0.14.0

func (l Logger) LevelPrint(level Level, a ...interface{})

Efficiently print arguments at the given level.

func (Logger) Levelf added in v0.11.0

func (l Logger) Levelf(level Level, format string, a ...interface{})

func (Logger) Log added in v0.11.0

func (l Logger) Log(m Msg)

func (Logger) LogLevel added in v0.11.0

func (l Logger) LogLevel(level Level, m Msg)

func (Logger) Print

func (l Logger) Print(v ...interface{})

Helper for compatibility with "log".Logger.

func (Logger) Printf

func (l Logger) Printf(format string, a ...interface{})

Helper for compatibility with "log".Logger.

func (Logger) Println added in v0.11.0

func (l Logger) Println(a ...interface{})

func (*Logger) SetHandlers added in v0.14.0

func (l *Logger) SetHandlers(h ...Handler)

Clobber the Loggers Handlers. Note this breaks convention by not returning a new Logger, but seems to fit here.

func (Logger) SkipCallers added in v0.10.0

func (l Logger) SkipCallers(skip int) Logger

func (Logger) WithContextText added in v0.8.0

func (l Logger) WithContextText(s string) Logger

func (Logger) WithContextValue added in v0.8.0

func (l Logger) WithContextValue(v interface{}) Logger

func (Logger) WithDefaultLevel

func (l Logger) WithDefaultLevel(level Level) Logger

func (Logger) WithFilterLevel added in v0.14.0

func (l Logger) WithFilterLevel(minLevel Level) Logger

func (Logger) WithMap

func (l Logger) WithMap(f func(m Msg) Msg) Logger

Returns a logger that for a given message propagates the result of `f` instead.

func (Logger) WithNames added in v0.11.0

func (l Logger) WithNames(names ...string) Logger

func (Logger) WithText

func (l Logger) WithText(f func(Msg) string) Logger

func (Logger) WithValues

func (l Logger) WithValues(v ...interface{}) Logger

Returns a logger that adds the given values to logged messages.

type Msg

type Msg struct {
	MsgImpl
}

A wrapper around MsgImpl that provides some extra helpers to modify a Msg.

func Call

func Call() Msg

func Fmsg

func Fmsg(format string, a ...interface{}) Msg

func Msgln added in v0.14.4

func Msgln(a ...interface{}) Msg

func Str

func Str(s string) (m Msg)

func (Msg) Add

func (m Msg) Add(key, value interface{}) Msg

func (Msg) AddValue

func (m Msg) AddValue(v interface{}) Msg

func (Msg) AddValues

func (m Msg) AddValues(v ...interface{}) Msg

func (Msg) HasValue

func (m Msg) HasValue(v interface{}) (has bool)

func (Msg) Log

func (m Msg) Log(l Logger) Msg

rename sink

func (Msg) LogLevel added in v0.11.0

func (m Msg) LogLevel(level Level, l Logger) Msg

func (Msg) Skip

func (m Msg) Skip(skip int) Msg

func (Msg) String

func (m Msg) String() string

func (Msg) With

func (m Msg) With(key, value interface{}) Msg

func (Msg) WithText

func (m Msg) WithText(f func(Msg) string) Msg

func (Msg) WithValues

func (m Msg) WithValues(v ...interface{}) Msg

TODO: What ordering should be applied to the values here, per MsgImpl.Values. For now they're traversed in order of the slice.

type MsgImpl

type MsgImpl interface {
	// Returns the message text. Allows for lazy evaluation/prefixing etc.
	Text() string
	// Sets the program counters in pc. Having it in the interface may allow us to cache/freeze them
	// for serialization etc.
	Callers(skip int, pc []uintptr) int
	// Iterates over the values as added LIFO.
	Values(callback valueIterCallback)
}

The minimal interface required for the Msg helper/wrapper to operate on.

type Record added in v0.11.0

type Record struct {
	Msg
	Level Level
	Names []string
}

type Rule added in v0.11.0

type Rule func(names []string) (level Level, matched bool)

type StreamHandler added in v0.11.0

type StreamHandler struct {
	W   io.Writer
	Fmt ByteFormatter
}

func (StreamHandler) Handle added in v0.11.0

func (me StreamHandler) Handle(r Record)

Directories

Path Synopsis
cmd/log-main
This package tests logging behaviour from a main package.
This package tests logging behaviour from a main package.

Jump to

Keyboard shortcuts

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