Structured logging

I’ve pondered a bit about how to do proper logging without it being an obnoxious part of the code base.

In my experience, the following pattern is often used for logging errors: if err != nil then log error and return it. I’ve come up with the following pattern to replace the need for creating a log statement for every instance of this pattern within a function. Basically, it is just using a named return value along with a defer function, so it is not very complicated. I have not seen it done anywhere else, so I was wondering what the community thinks about it?

Hi @Jgfrausing, welcome to the forum.

I would distinguish here between library code and executable code.

A library package should not do any logging whatsoever. All errors should be returned to the caller. When forwarding an error received from below, it should be wrapped with useful contextual information.

Why should a library not log errors? There are many different loggers around, and a similar number of logging philosophies. If a library uses a particular logger (even if it is only the standard library’s logger), it imposes a particular logging model on all its clients. Not good.

So for library code, the pattern “log and return” does not apply.

Code for a binary can decide what to do with errors from library code. As said, there are many options for logging, from plain stdlib log to sophisticated structured loggers. Every company surely has its own approach to logging.

At the level of binary code (that is, outside a library package), I daresay that the nesting of functions is not that deep to worry about reducing the number of log calls. But it might be interesting to dig into popular Go projects to see how they handle this.

1 Like

Hmm, I think I’m not so well versed in all languages ​​to draw reasoned conclusions, but in principle, you can use the option you are talking about to maintain a journal for those that are not in the library codes