About
Lug is a logging library for Golang.
It is currently little more than a wrapper for
go-kit's log package
which is largely a wrapper which simplifies logrus.
Why another logging library for Golang.
There are many logging libraries for Go. Lug was born due to the desire
for some very specific functionality.
Logging is, and has been for many years, kind of horrible. It is historically
difficult to adjust the signal to noise ratio for your logging. Some times
it's simply impossible to troubleshoot your app without VERY detailed logging.
But most logging frameworks (and all of the currently maintained logging
frameworks for Go) provide only a single dial which can be used to
increase log detail. The result is that many applications log far too
much when running in production and the more common errors which we are
looking for get lost amidst the noise. An entire industry has spawned
in an attempt to allow us to get information from this mass of data
(Splunk, kibana, etc.)
The log4j library for Java provides the ability to configure logging with
an external file. It allows you to configure different log levels, formats
and destinations for individual classes. The benefit of this is difficult
to overstate.
Lug
Lug exists to provide some features.
Per Package and Per File log levels
When adding a new feature there are frequently new kinks to work out.
We often want to turn logging up to a nearly absurd level. It can then
be difficult to wade through the absurd level detail for the previous
nine features added. Lug will allow you to leave logging down at
a lower level for the bulk of your code and turn up (or down) the specific
features you are troubleshooting.
Pass through Support for other logging libraries (Experimental.)
It should then also be possible to tune the log levels of external
dependencies which may have been built with other logging libraries.
Structured logging
Lug provides structured logging via logrus
(simplified via go-kit/log.)
I.E.:
Message="New request." Scheme="HTTPS" URL="/app/shoestore" Params="?login=true"
Which are far easier to parse and index enabling us to get more information
out of the piles of data we may generate.
External Configuration
We frequently write our code to accept a log level argument but this
will get hairy when trying to support different levels (and eventually
different destinations) for any of the various components of your app.
Lug will read a configuration from an external file (let's do YAML or
JSON instead of XML) and use it to configure logging down to the
per-file level.
Re-loadable Config
This will allow us to provide a mechanism for updating the config during
execution. Often when you're trying to track down an irritating issue
having to restart your application in order to change your log settings
removes the problem. Lug will be able to update logging settings at run-time.
Configuration Via Code
Lug will also allow for the configuration of log levels within code for
those who do not wish to bundle configuration files with their apps.
More Log Levels
Initially it will provide all of the log levels of go-kit/log which are
unfortunately somewhat limited.
They are None, Error, Warn, Info, Debug and All which really only give
us 4 levels on our dial.
Lug supports these levels:
- None
- Fatal
- Error
- Warn
- Info
- Debug
- Trace (otherwise known as Absurd)
Each level of logging includes the levels above it.
I do not see a benefit of ALL in a system where log levels are
additive. However we could make Lug configurable to take levels as a list
and only log the individual levels specified (far future.)
Custom Levels (Future)
In the future we should add support for custom log levels.
Log4j does this through the ability to define new levels in your code
however I am rather enamored with the .V(#)
construct provided by
libraries like glog which allow you to use any arbitrary int for the
level of your log message and then read that value from a command
line flag.
We need to evaluate the benefit of using that as a separate level
on the list (probably above Trace) or providing it at each level.
Log Destinations
Initially the only concern of Lug will be logging to standard out
(because I have become a complete Kubernetes nerd) but we should
support different log file (and possibly socket) destinations. This
shouldn't be difficult because the underlying libraries support at
least file destinations.
References
- log4go (alecthomas) -
An abandoned attempt to create log4j for golang
- log4go (Jeanphorn) -
A repo which recreates alecthomas' (originally lost) log4go repo. It
might be slightly more up to date than the former I need to confirm.
- Google's glog -
Probably the de-facto logging library for go at this point.
- Go-kit's log -
A simpler way to use logrus' excellent structured logging support.
- Sirupsen's logrus -
An excellent structured logging library.