How to Build a Java Method Call Stack Tracker for Faster Debugging
This article examines the common pain points of on‑call debugging, explains how to extract useful information from error screenshots, and presents a Java‑based method call stack tracing tool that filters and visualizes stack frames to quickly locate code origins and improve troubleshooting efficiency.
When on‑call developers receive error screenshots, they often lack sufficient context to diagnose the problem; the article starts by analyzing this pain point, extracting menu names, error messages, and auxiliary data, and outlining typical troubleshooting steps.
Menu name: e.g., "Change order off‑shelf".
Error info: "Serial number status is off‑stock, please check."
Auxiliary info: user‑entered codes, SKU, product name, storage location, etc.
Common debugging ideas include verifying the serial number, confirming its off‑stock status, locating the code source of the error message via code search or log inspection, and handling multiple occurrences of the same message.
Inspiration from Exception Stack Traces
Exception stack traces provide four key pieces of information: fully qualified class name, method name, file name, and line number. Each thread records stack frames (StackTraceElement) even outside exceptions, and StackTraceElement represents a single stack frame.
Tool Development
The core implementation leverages Java's StackTraceElement, filters out unnecessary entries, and assembles a linear, readable call chain. Important parameters: pretty: only concatenate class and method names (no file name or line number). simple: filter out proxy‑generated methods such as those from Spring CGLIB. specifiedPrefix: retain stack frames whose package prefixes match the given list, removing noisy middleware entries.
Built‑in filters also exclude common proxy identifiers: FastClassBySpringCGLIB, EnhancerBySpringCGLIB, lambda$, Aspect, Interceptor.
The tool outputs the filtered chain in a concise string, making the call sequence instantly visible.
Usage Effects
Examples of output under different filter settings:
1. No middleware filtering:
Thread#run → ThreadPoolExecutor$Worker#run → … → StackTraceUtils#trace
2. Package‑path filtering:
LockAspect#lock → StockTransferAppServiceImpl#increaseStock → … → StockTransferAppServiceImpl#increaseStock
3. Removing Spring proxies:
LogAspect#log → LockAspect#lock → ValidationAspect#validate → … → StockRepositoryImpl#operateStock
4. Removing custom proxies:
StockTransferAppServiceImpl#increaseStock → StockTransferServiceImpl#increaseStock → … → StockRepositoryImpl#operateStock
5. Including file name and line number:
StockTransferAppServiceImpl#increaseStock (StockTransferAppServiceImpl.java:103) → … → StockRepositoryImpl#operateStock (StockRepositoryImpl.java:303)
Online Practice
After integrating the tool, developers can search logs using error keywords; for example, the chain
ImmediateTransferController#offShelf → AopConfig#pointApiExpression → TransferOffShelfAppServiceImpl#offShelf → TransferOffShelfAppServiceImpl#doOffShelfquickly reveals the entry point of the request.
Applicable Scenarios
Output stack traces in business exception logs.
Include call‑stack information in monitoring alerts.
Print call stacks in complex reusable‑method scenarios to visualize the invocation chain.
Other custom debugging situations.
Extension
The author previously released a SQL‑coloring MyBatis plugin that provides statement IDs. By adding the method‑call‑stack tracer, the plugin now also displays the originating method chain for each SQL statement.
JD Tech
Official JD technology sharing platform. All the cutting‑edge JD tech, innovative insights, and open‑source solutions you’re looking for, all in one place.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
