One thing that's an absolute must: Put an ISO-8601 timestamp at the very beginning of every line in your log. No apache format, no "sun" or "jan" or other words. ISO only. Seriously.<p>If the timestamp is in a weird format (or, god help you, multiple formats since some libraries log shit in a special way), it'll be just about impossible to tell when things <i>actually happened</i> instead of just when the logging server <i>saw them</i>. In a perfect world these would be milliseconds apart, but lots of bad stuff can happen.<p>Your log-grepping-guy will thank you.
I think all of this sounds fine in theory, but the reality is that most logged information will not be needed - ever. Exactly what information is needed when can be difficult to predict. So, if a developer feels something might be important, they should probably log it. Within reason, I think it is better to have it and not need it than to need it and not have it.<p>It seems the author is putting a heavy emphasis on trying to create readable logs. Finding the signal in the noise. I am biased, but I think this is a failure of the tools used to read the logs rather than the logs themselves. This is why I wrote LogViewPlus (<a href="https://www.logviewplus.com/" rel="nofollow">https://www.logviewplus.com/</a>).
One additional thing I like in structured logs is having some form of context level information be included eith your logs, so that you already know things like tenant id, user id, request id, and basic parameters of the request without having to rewrite all that everytime you get an exception.<p>Unrelated: I live in the Pacific north west and I clicked on this expecting to find a list like "don't log old growth for timber, don't log the entire area", fun how your brain can associate a word with a concept and ignore the more context-relevant meaning.
Should add that log messages should answer questions like:<p>- What happened
- When it happened?
- Where it happened?
- Why it happened?
- What's the next step?<p>If your log doesn't answer at least the first 3 questions, then it's useless. If you don't answer "why", then you should think harder whether that is useful or not.<p>If I had a cent for every time I see "Something went wrong" optionally followed by stack trace that is nearly entirely in 3rd party code with zero information to correlate it with anything - I would have retired to homestead ages ago.
Something I haven't seen discussed very widely: it feels like there's not only a balance needed in determine what to log vs what not to log, but also logging in a way that isn't a detriment to the readability of the code overall.<p>Over time I've actually found myself logging less just because having to sorta mentally elide logging lines added to the cognitive overhead of reading & understanding code.
I prefer this post which is more detailed: <a href="https://talktotheduck.dev/logging-best-practices-mdc-ingestion-and-scale" rel="nofollow">https://talktotheduck.dev/logging-best-practices-mdc-ingesti...</a>
One thing I'd add is the ability to tag certain data or certain loglines as containing personal information so that they can be scrubbed before transmitting or storing the logs. You don't want things like credit card numbers, government id numbers, home addresses, and so on sitting out there in your logs, available to any developer reading a bug report (or available to everyone, when your company has a data breach). You'd log these things during development, skipping the scrubbing step, while the prod logs get scrubbed.
The key is that the person writing the log message is in no position to judge whether it's right.<p>The measure of logs is whether you can put them in front of a smart but unfamiliar persons and have them figure out what's happening. At a minimum, they should understand generally what's happening and specifically what each message is saying (though perhaps not its significance).<p>(i.e., same as when writing code)
Question...why no mention of "change" logs? I'm curious as to why I don't see change logs mentioned often as an important overlay to general system logging.<p>I liken errors and debugs all related to heart beat and breathing rate but without information like "climbing stairs" or "changed medication", it may be hard to understand context or understand why new errors are being seen. The first question I would expect to ask when seeing logged issues, is what has changed recently that could be related to the new errors. Curious to hear thoughts on this?<p>I actually built software/startup related to the logging of changes (architecture change/software change/server restarts) but just didn't get traction and curious to know why it's not more interesting to people.
Personally since few yeas I feel more and more issues with logs:<p>- most devs have lost the concept of logging levels, considering normal spitting out crappy giants backtraces and wall of meaningless text;<p>- most devs have lost the idea of "being quiet" or "frugality", also have NEVER tried to read logs like an application user who do not have nor want to pass gazillion of lines of sources often crappily arranged.<p>In the classic *nix world skimming log for "alerting patterns" was easy, for modern crapplications it's a bit of a nightmare. Similarly using logs for debug and mere health check is sometimes useless since many messages should at maximum be debug level logs, others are meaningless and even looking at them from the sources does NOT clarify until you read much more.
I fight log infra all the time. I can't win the fight against structured logging anymore, so I'm now fighting against type systems and allergies to global state to make log output available everywhere. If you're going to ram structured logging down devs' throats, then the least you can do is to make it easy enough to use. I don't want to have to pass a logging object everywhere. There's like two pieces of information you need in order to make a logger. Just write it to global state somewhere so I don't have to worry about it and can call it anywhere.<p>I absolutely <i>loathe</i> reinventing global state by passing "context" objects and the like everywhere. It's the dumbest thing in the world but no one ever questions it.
> Whatever service you are using for logging, it costs money, and a fast way to burn money is to log the entire json object that was relatively small on your dev env, but blew up on production.<p>You could also, you know, run your own infrastructure and log to your heart's content.
On the levelled logging point, I stopped using levels after switching from Java -> Go and haven't looked back: <a href="https://thomshutt.github.io/opinionated-logging-in-go.html" rel="nofollow">https://thomshutt.github.io/opinionated-logging-in-go.html</a>
One question I always have about logging: how do I log valid and expected but prohibited actions? That is, the system is behaving as designed but the user is seeing an error message because they're using the system wrong, and I want to know how often this is happening?
We use SQLite for logging all the things. This sidesteps entire rabbit colonies worth of issues - especially with regard to downstream parsing & reporting.<p>I have found the extra structure and familiar semantics make it a lot easier to talk about what we log, how we log it and why.
Unrelated to the content: I really like the phrasing of the title. Not "…you should follow", not the tired "best practices", simply "Things I do".