Golang Logging Mess

Go has a logging mess. If you want to see it in action open up a Go application and look at the number of logging implementations that have been pulled into the application. For example, if you look into the Kubernetes modules you’ll find it’s using zap, logrus, klog, and others. This mess can lead to applications not exposing logs, binary bloat, and more. It also inverts control. Instead of the application controlling the logging the libraries do.

Many languages simply don’t have this problem. Some by design (e.g. Rust and Python) and some because the community chose to solve it (e.g., PHP with PSR-3).

This is a problem worth exploring and understanding.

Go log Package

The Go standard library does provide the log package. Unfortunately, this package was insufficient both inside and outside of Google. For example, at Google they created the glog package and out in the wild we got the logrus package (which is now in maintenance only mode). Hashicorp even created a package to add leveled logging to the standard library.

Some will want to debate if the log package is insufficient. The explosion of logging implementations that are far different from the Go standard library but similar to logging in other languages is clear sign. Those who created those package and used them found the standard library to be lacking.

Even saying that, one large lacking point is the ability to do leveled logging. When you run an application in development vs production you’re going to want to log different information. The verbosity will go up in development. The standard library simply lacks this ability.

Implementations Everywhere

As Go developers wrote their libraries and applications, whose non-main and non-internal packages can be imported by others, they used logging implementations like logrus, zap, and others. Instead of an interface being backed into all these locations the implementations were.

This worked find for the library as a stand along library or for the applications as they ran on their own.

Then those packages were pulled into other codebases. Different packages using different logging libraries pulled into new codebases who now have to deal with multiple logging implementations.

Do those new applications realize they have multiple logging implementations they need to get working correctly? I’ve learned that many Go developers don’t even realize there are multiple logging implementations much less that they need to set them up. And so, logs are dropped while those implementations are baked into the binaries.

This is ugly.

Untangling The Mess

There is no quick way to untangle the mess. A lot of logging packages are out there in many different places. Changing the way they do logging may even break APIs which means they need a major version bump, since Go packages are expected to follow semantic versioning.

Long term, the community needs to adopt an interface that everyone case use. Package and libraries would then use the logging interface while main packages would setup the logging implementation to use for that application. Or, the mess will just continue on.

One such option is github.com/Masterminds/log-go.