Log Fatigue, True Story
Avoid Log Fatigue: Debugging Smarter, Not Harder
Developers love their logging. Virtually every programming language lets you create additional output for your application in the form of logs. It’s an easy way to debug code and it’s understood even by junior developers. Logs tell you if a call to a certain method has failed if a specific line of code has been reached during execution, or when to get a local variable’s value.
And who could blame them? Virtually all tutorials for programming languages start with logging, so it comes as no surprise that developers resort to logs when things go wrong.
Many developers approach debugging by adding logs. The harder an issue is to reproduce locally, the more logs they add. While logging can help fix the bug, it should be handled with care. Cluttering your codebase with loglines can make reasoning about the code hard and even lead to performance degradation.
In this article, we’ll look at the pros and cons of logging for debugging specifically. If you need information for business analytics, you can’t get around logging. The same goes for auditing logs—compliance to HIPAA, for example, requires you to keep access logs to track who accessed which data. But when it comes to debugging, it’s important to learn to stay out of your own way.
What’s Gained from Logging?
Sometimes, logging can be a lifesaver. You can’t guarantee that everyone on your team will grasp what’s happening in every function. But putting loglines at key points in your code can help your whole team stay on the same page while collaborating and debugging.
Not all developers have the same skills, and a well-implemented logging system can help inexperienced developers debug code they didn’t write. When planned and executed carefully, logging can be a helpful guide that tells the application’s story and provides direction to new team members.
Sometimes you need to look at the sequence of events rather than a snapshot of the application’s current state. Was a button clicked before a request was received, or after it? Logs are a convenient way to make such processes visible. When logging is structured and maintained well, it can give you the details of the events that led to the error or current state.
Clearly, logging has its time and place in the software development process. But rather than treating it as a catch-all solution, it should be used as a well-considered addition to your software.
What’s Lost by Logging?
Logging doesn’t come without a price—a few prices, actually. Below are just some of the ways we pay for using logging in to our applications.
Developers spend a lot of time adding, modifying, and maintaining their loglines to collect meaningful information about the application. Ad-hoc logging meant to address a specific bug is especially time-consuming. In addition to adding those loglines, finding and removing them from the code before a new release can be quite daunting.
When you’re finished with the actual work of implementing a feature or fixing a bug, the last thing you want to do is comb through hundreds of code lines to clean things up.
Loglines can hold sensitive information, such as customer data. You can easily break the SOC, ISO, or HIPAA compliances without even being aware of it. While this may not be a problem when working with development data sets that have been scrubbed of sensitive information, it can become problematic if a developer forgot to remove debugging logs when pushing a new release to production.
Again, a well-architected logging approach is crucial. If you need to keep logs for monitoring your application, you also need to make sure that these logs don’t contain sensitive information. Going through all of your code to check loglines is a time-consuming task and, in turn, expensive.
Security standards can be hard to satisfy and a wrong step could put your whole business endeavor in jeopardy.
Storing and managing logs is a huge cost by itself. Generally, the biggest line item in a project is not compute, but the logs and database. While this usually isn’t a problem for debugging efforts when developing, the more log data that is retained for a production service, the higher the costs of storing them.
In addition to slowing down developers, logging too much data can slow down an application. Most systems run just fine without logging but become virtually unusable when it’s activated.
Many tasks performed by program code can be done in memory, but when you log intermediate results, this data has to move out of the memory so the system can write it to a hard drive or print it on display. Such actions are often magnitudes slower than working in memory.
To soothe their anxiety, some developers put more and more logging outputs into their code—just to be safe. This practice can quickly get out of control. While the logs are there to avoid errors, the bloated code becomes a hurdle for team productivity.
If your code is dominated by loglines, collaboration slows as understanding becomes harder. It’s like defensive programming, it can be helpful if used appropriately, but too much makes working with the code unbearable.
There’s a good chance that when you go back to the loglines you added earlier, you won’t understand them anymore. Your logging system is an important part of your application that needs to be maintained, just like everything else. If your software is cluttered with ad-hoc logging, it makes maintenance time-consuming and frustrates your team.
Motivate your team to build new features and improve your application, and implement good logging practices that will save them from being scared when they look back at code they wrote a week ago.
All of these logging costs are intertwined. It may not be obvious, but security risks, higher maintenance, lower productivity, and bad performance will all cost you money in the long run. It might not seem like much at first, but competitors that can add features faster and have better-performing applications could steadily draw your customers away.
Logging can be a great help when onboarding new developers. It’s also a debugging tool that’s easy to grasp, even for junior developers. But building and maintaining a reasonably sophisticated logging system for your product can feel like building another product.
Things can get especially cumbersome when you already have to maintain multiple logs for different purposes, like business analytics and auditing.
When creating software, you should work to eliminate redundant tasks from your workload, not add more. Otherwise, you end up pumping money into parts of your software that could have been easily solved by a third-party product.
Better Ways of Debugging
Modern solutions help developers to debug their code in the cloud without perpetuating bad logging habits. Live debugging solutions like Sidekick allow developers to collaborate without blocking each other or polluting the code with loglines. With Sidekick, developers can see the current state of the application with non-intrusive breakpoints, so the need for cluttering the code with ad-hoc logging disappears.
For particularly insidious bugs, you might need to look at the system’s state just before the error. If you have a distributed event-driven microservices application, the cost, and effort required to see that would be untenable.
Sidekick automatically correlates the distributed traces and connects the snapshots of the application for you. It’s a handy extension of Sidekick’s observability approach cast into an IDE plugin, and it comes as a plugin for the IntelliJ IDEA and VSCode extension.
As a developer, you need to know what’s going on in your cloud-based applications, and you don’t have time or money to waste on maintaining a logging system. Sidekick is the solution for you.