Why structured?

The apex/log package is a structured logging package Go, inspired by Logrus, one of Go’s most popular structured solutions.

I strongly believe that structured logging is the way to go for most, if not all applications. If you’re not familiar with structured logging, the basic idea is that you have discrete fields which can be used later for querying and subsequent processing. You can search logs by a user id, the name of a file they uploaded, errors, response times, and so on. Not only is this great for logging but it can be used to produce metrics, or even to derive billing information.

Here’s what you might see with plain-text:

log.Infof(“uploading %q for %s”, filename, user.ID)

Here’s a structured alternative, each field is captured on its own. Note that the log message itself does not contain dynamic content, this is important, as it is the unit for filtering, aggregation, and so on. If the message were “upload %s” you would have a difficult time differentiating it from a message like “failed to upload %s”, so make sure these are machine friendly!

log.Info(log.Fields{

“file”: filename,

“user”: user.ID,

}).Info(“upload”)

Structured logging is also great for contextual logging, it becomes trivial to inherit fields, without just prefixing a large string. Here’s an example of this, the log.WithFields() call returns an Entry which has the same methods as the logger itself, thus they are chain-able.