
ADD: * `iox` subpackage FIX: * `logging` now has a way to return logWritier directly * added significant `io.*` interface compat to logWriter -- allowing a `logging.Logger` to essentially be used for a large amount of io interaction in other libraries.
65 lines
3.2 KiB
Go
65 lines
3.2 KiB
Go
/*
|
|
Package logging implements and presents various loggers under a unified interface, making them completely swappable.
|
|
|
|
These particular loggers (logging.Logger) available are:
|
|
|
|
NullLogger
|
|
StdLogger
|
|
FileLogger
|
|
SystemDLogger (Linux only)
|
|
SyslogLogger (Linux/macOS/other *NIX-like only)
|
|
WinLogger (Windows only)
|
|
|
|
There is a seventh type of logging.Logger, MultiLogger, that allows for multiple loggers to be written to with a single call.
|
|
(This is similar to stdlib's io.MultiWriter()'s return value, but with priority awareness and fmt string support).
|
|
|
|
As you may have guessed, NullLogger doesn't actually log anything but is fully "functional" as a logging.Logger (similar to io.discard/io.Discard()'s return).
|
|
|
|
Note that for some Loggers, the prefix may be modified after the Logger has already initialized.
|
|
"Literal" loggers (StdLogger and FileLogger) will append a space to the end of the prefix by default.
|
|
If this is undesired (unlikely), you will need to modify (Logger).Prefix and run (Logger).Logger.SetPrefix(yourPrefixHere) for the respective logger.
|
|
|
|
Every logging.Logger type has the following methods that correspond to certain "levels".
|
|
|
|
Alert(s string, v ...interface{}) (err error)
|
|
Crit(s string, v ...interface{}) (err error)
|
|
Debug(s string, v ...interface{}) (err error)
|
|
Emerg(s string, v ...interface{}) (err error)
|
|
Err(s string, v ...interface{}) (err error)
|
|
Info(s string, v ...interface{}) (err error)
|
|
Notice(s string, v ...interface{}) (err error)
|
|
Warning(s string, v ...interface{}) (err error)
|
|
|
|
Not all loggers implement the concept of levels, so approximations are made when/where possible.
|
|
|
|
In each of the above methods, s is the message that is optionally in a fmt.Sprintf-compatible format.
|
|
If it is, the values to fmt.Sprintf can be passed as v.
|
|
|
|
Note that in the case of a MultiLogger, err (if not nil) will be a (r00t2.io/goutils/)multierr.MultiError.
|
|
|
|
logging.Logger types also have the following methods:
|
|
|
|
DoDebug(d bool) (err error)
|
|
GetDebug() (d bool)
|
|
SetPrefix(p string) (err error)
|
|
GetPrefix() (p string, err error)
|
|
Setup() (err error)
|
|
Shutdown() (err error)
|
|
|
|
In some cases, Logger.Setup and Logger.Shutdown are no-ops. In other cases, they perform necessary initialization/cleanup and closing of the logger.
|
|
It is recommended to *always* run Setup and Shutdown before and after using, respectively, regardless of the actual logging.Logger type.
|
|
|
|
Lastly, all logging.Loggers have a ToLogger() method. This returns a *log.Logger (from stdlib log), which also conforms to io.Writer inherently.
|
|
In addition. all have a ToRaw() method, which extends a Logger even further and returns an unexported type (*logging.logWriter) compatible with:
|
|
|
|
- io.ByteWriter
|
|
- io.Writer
|
|
- io.WriteCloser (Shutdown() on the Logger backend is called during Close(), rendering the underlying Logger unsafe to use afterwards)
|
|
- io.StringWriter
|
|
|
|
and, if stdlib io ever defines an e.g. RuneWriter (WriteRune(r rune) (n int, err error)), it will conform to that too (see (r00t2.io/goutils/iox).RuneWriter).
|
|
Obviously this and io.ByteWriter are fairly silly, as they're intended to be high-speed throughput-optimized methods, but if you wanted to e.g.
|
|
log every single byte on a wire as a separate log message, go ahead; I'm not your dad.
|
|
*/
|
|
package logging
|