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
- Variables
- func ContextWithLogger(ctx context.Context, logger Logger) context.Context
- func GetDefaultTimeAppendFormatter() func([]byte) []byte
- func Levelf(level Level, format string, a ...interface{})
- func LineFormatter(msg Record) []byte
- func Print(a ...interface{})
- func Printf(format string, a ...interface{})
- func Println(a ...interface{})
- func WithLevel(level Level, err error) error
- type ByteFormatter
- type Handler
- type JsonHandler
- type Level
- type Loc
- type Logger
- func (l Logger) FilterLevel(minLevel Level) Logger
- func (l Logger) IsEnabledFor(level Level) bool
- func (l Logger) IsZero() bool
- func (l Logger) LazyLog(level Level, f func() Msg)
- func (l Logger) LazyLogDefaultLevel(f func() Msg)
- func (l Logger) LevelPrint(level Level, a ...interface{})
- func (l Logger) Levelf(level Level, format string, a ...interface{})
- func (l Logger) Log(m Msg)
- func (l Logger) LogLevel(level Level, m Msg)
- func (l Logger) Print(v ...interface{})
- func (l Logger) Printf(format string, a ...interface{})
- func (l Logger) Println(a ...interface{})
- func (l *Logger) SetHandlers(h ...Handler)
- func (l Logger) SkipCallers(skip int) Logger
- func (l Logger) Slogger() *slog.Logger
- func (l Logger) WithContextText(s string) Logger
- func (l Logger) WithContextValue(v interface{}) Logger
- func (l Logger) WithDefaultLevel(level Level) Logger
- func (l Logger) WithFilterLevel(minLevel Level) Logger
- func (l Logger) WithMap(f func(m Msg) Msg) Logger
- func (l Logger) WithNames(names ...string) Logger
- func (l Logger) WithText(f func(Msg) string) Logger
- func (l Logger) WithValues(v ...interface{}) Logger
- type Msg
- func (m Msg) Add(key, value interface{}) Msg
- func (m Msg) AddValue(v interface{}) Msg
- func (m Msg) AddValues(v ...interface{}) Msg
- func (m Msg) HasValue(v interface{}) (has bool)
- func (m Msg) Log(l Logger) Msg
- func (m Msg) LogLevel(level Level, l Logger) Msg
- func (m Msg) Skip(skip int) Msg
- func (m Msg) String() string
- func (m Msg) With(key, value interface{}) Msg
- func (m Msg) WithText(f func(Msg) string) Msg
- func (m Msg) WithValues(v ...interface{}) Msg
- type MsgImpl
- type Record
- type Rule
- type StreamHandler
Constants ¶
const ( EnvRules = "GO_LOG" EnvTimeFormat = "GO_LOG_TIME_FMT" EnvDefaultLevel = "GO_LOG_DEFAULT_LEVEL" EnvReportRules = "GO_LOG_REPORT_RULES" )
Variables ¶
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 }, } )
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} // It shouldn't be possible to define a message at this level. Filtering at this level should // mean no messages ever get through. Disabled = Level{6} )
Deprecated: Logging shouldn't include control flow.
var DefaultTimeAppendFormatter = func(b []byte) []byte { return time.Now().AppendFormat(b, timeFmt) }
Preferred and probably faster than DefaultTimeFormatter.
var DefaultTimeFormatter = func() string { return time.Now().Format(timeFmt) }
var Fstr = Fmsg
Functions ¶
func ContextWithLogger ¶ added in v0.13.0
func GetDefaultTimeAppendFormatter ¶ added in v0.14.3
func Levelf ¶ added in v0.10.0
Logs a message to the Default Logger with text formatted in the style of fmt.Printf, with the given Level.
func LineFormatter ¶
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.
Types ¶
type ByteFormatter ¶
type JsonHandler ¶ added in v0.16.0
type JsonHandler struct { // This is used to output JSON as it provides a more modern way and probably more efficient way // to modify log records. You can alter this in place after initing JsonHandler and before // logging to it. SlogHandler slog.Handler }
func NewJsonHandler ¶ added in v0.16.0
func NewJsonHandler(w io.Writer, minLevel Level) *JsonHandler
func (*JsonHandler) Handle ¶ added in v0.16.0
func (me *JsonHandler) Handle(r Record)
type Level ¶
type Level struct {
// contains filtered or unexported fields
}
func ErrorLevel ¶ added in v0.14.0
Extracts the most recent error level added to err with WithLevel, or NotSet.
func (*Level) UnmarshalText ¶ added in v0.12.0
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 NewLogger ¶ added in v0.14.0
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 ¶
Deprecated. Use WithFilterLevel. This method name is misleading and doesn't follow the convention elsewhere.
func (Logger) IsEnabledFor ¶ added in v0.11.0
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) LazyLogDefaultLevel ¶ added in v0.11.0
func (l Logger) LazyLogDefaultLevel(f func() Msg)
func (Logger) LevelPrint ¶ added in v0.14.0
Efficiently print arguments at the given level.
func (Logger) Print ¶
func (l Logger) Print(v ...interface{})
Helper for compatibility with "log".Logger.
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 (Logger) WithContextText ¶ added in v0.8.0
func (Logger) WithContextValue ¶ added in v0.8.0
func (Logger) WithDefaultLevel ¶
func (Logger) WithFilterLevel ¶ added in v0.14.0
func (Logger) WithMap ¶
Returns a logger that for a given message propagates the result of `f` instead.
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 (Msg) WithValues ¶
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) // Returns Some(slog.Record) if the Msg supports it. SlogRecord() g.Option[slog.Record] }
The minimal interface required for the Msg helper/wrapper to operate on.
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)
Source Files ¶
- callers.go
- callers_go1.21.go
- context.go
- doc.go
- env.go
- errors.go
- global.go
- handler.go
- init.go
- json-handler.go
- level.go
- log.go
- logger-core.go
- logger.go
- msg.go
- msgimpl.go
- report-rules.go
- reporting-rules.go
- slog-handler.go
- slog-record-formatter.go
- slog.go
- stdlog.go
- stream-handler.go
- time.go
- time_testing.go
Directories ¶
Path | Synopsis |
---|---|
cmd/log-main
This package tests logging behaviour from a main package.
|
This package tests logging behaviour from a main package. |