Introducing Non-Breaking Breakpoints
So, what are non-breaking breakpoints and why are they important?
Join the DZone community and get the full member experience.Join For Free
As R&D managers, we have learned to expect that a significant amount of time spent by our teams will be dedicated to debugging. In some technologies, the methods for debugging are tried and tested and the ecosystem is mature. In new, emerging technologies, such as serverless or microservices, dedicated debugging tools are still struggling to define the market.
One method that has become prominent in these emerging fields is one that tries to mix the traditional “caveman” log-based debugging with the more friendly and intuitive breakpoint-based debugging. Whether they are named “log points,” “trace points,” “snap(shot) points,” or “non-breaking breakpoints,” adopting this method of cloud-native debugging seems to be the way forward for many dev managers.
So what are these new “points” based tools and methods? How do they work? What are they useful for? And why are they necessary for the efficiency of your team and the quality of your application? Let us begin, well, at the beginning.
Traditionally, debugging is done in one of two ways.
The first method is often called “log debugging,” “print debugging,” or “caveman debugging.”
It is implemented by adding log statements in key paths in the application code and printing the logs to a local file or a remote logging server. When the application is re-built and re-deployed after adding the log lines, and the investigated issue is reproduced, the log lines are printed.
Those printed log lines provide information about the state of the application just before and just after the issue. Reading through the printed logs helps the developer understand what caused the problem.
In recent years, “log debugging” has grown and matured into tracing and observability, where context was added to the log statements in order to allow developers to analyze the behavior of complex, cloud native, service based systems. Log debugging allows the app to run as it is expected to run, without stopping. It is a natural fit for cloud-native applications and is considered the only valid approach to debugging microservices and serverless architectures by many software engineers.
However, log debugging requires adding code for printing the log statements and additional performance, storage, and configuration are required in order to maintain, store, and read through the printed log files.
The second method is often called breakpoint “debugging,” “step debugging,” or “just debugging.” It consists of running the application in debug mode, with a debugger attached to it. This could be either a visual debugger (usually as part of the IDE, where the code is also written, edited and version controlled), with breakpoints, a snapshot view, intellisense, and other visual enhancements. It could also be a command line debugger, where the visual noise is dropped for the sake of simplicity and robustness and focuses on the code itself.
Breakpoint debugging is often easier and more intuitive to a developer than Log debugging. It allows developers to debug their app with their code before their eyes, allowing them to learn how the application should behave.
However, the use of this type of debugging requires running the app in debug mode. And when attempting to debug a cloud-native, microservices, or serverless application, stopping the app usually means you’re not really reproducing the behavior of a multi-threaded/multi-service/cloud-native distributed system. And to make things worse, breakpoint debugging is usually hard to implement in remote servers, as attaching to a remote server is both a challenge and a security risk.
Let Our Powers Combine
In recent years, some tools have attempted to generate a best-of-breed hybrid approach. Tools that offer Tracepoints, Logpoints, Snappoints, or Non-Breaking Breakpoints are all tools that try to offer a way to fetch data about the running code, without stopping the code and without adding more code.
These tools usually offer a visual, code-focused interface, where fetching the additional data is done by clicking the relevant code line. Clicking the code line then dynamically adds a data collection point that will send a log line or a trace line, a full snapshot of all the local variables, a stack trace, and more to a selected target.
By mixing the non-stopping approach of log debugging with the visual ease of breakpoint debugging, this implementation makes the traditional practices of log-debugging and step-debugging possible, whereas in several use cases they had previously been considered impossible. For example:
Debugging live applications in production environments
Debugging dynamic remote environments, such as staging, integration environments and more
Debugging distributed, cloud native deployments such as Kubernetes, Lambda, and others
What’s in a Name?
We often get asked why we chose the name “Non-Breaking Breakpoints.” The answer starts with the message that we are trying to convey: that live, remote debuggers are first and foremost debuggers. And debuggers have breakpoints.
Breakpoints is something that developers expect in a debugger. It explains what they do and why they are useful. You click next to a line of code -> you hit the line of code -> you get all the data you need. This is simply what a breakpoint Does.
However, “breakpoints” is a problematic term, as breakpoints are expected to break the execution of the code. It’s literally in the name. And it’s the aversion to using the term ‘breakpoint’ that explains why some players in the market attempt to find a word that sounds like a breakpoint, but isn’t quite it. “Snappoints,” “Log points,” and “Tracepoints” are all ways of trying to find something that rhymes with a Breakpoint, thus hinting at debugging, without having the word “break” in it.
However, we feel that this approach doesn’t always hit the mark. Since the word isn’t exactly a breakpoint, you end up having to explain what your solution does. Furthermore, we feel it just doesn’t roll off the tongue. Non-breaking breakpoints, as much of a mouthful as it may be, is the best articulation we’ve found of the ability to debug live applications on the fly without stopping code execution.
Level Up Your Debugging Game
If your team is developing and maintaining a cloud native application, you already know that they are struggling with debugging. Some of your more seasoned engineers may invest significant time and effort in the ability to create a local version of the application, so that they can debug it using their favorite local debugger. Others may have given up altogether and have fallen back on log-debugging, while muttering to themselves begrudgingly that “logging is the only way to debug cloud native applications.”
But if your aim is to have happy, effective developers that can troubleshoot any issue in any environment, my best advice is to introduce them to non-breaking breakpoints. Show them that they can fetch code-level data from any application, wherever it is running, with the ease of a local debugger. This can be done without adding code and without waiting for log lines to be printed. You can also introduce them to snappoints, tracepoints, or log points— we don’t mind. Either way, they will find that they save precious hours by quickly debugging issues that were simply impossible to debug before.
Opinions expressed by DZone contributors are their own.