diff --git a/src/main/java/in/maheshlangote/logdispatch/LogDispatchFilter.java b/src/main/java/in/maheshlangote/logdispatch/LogDispatchFilter.java index 1acfaa1..c1b544d 100644 --- a/src/main/java/in/maheshlangote/logdispatch/LogDispatchFilter.java +++ b/src/main/java/in/maheshlangote/logdispatch/LogDispatchFilter.java @@ -46,6 +46,7 @@ public class LogDispatchFilter extends OncePerRequestFilter { private final Set maskedHeaders; private final List excludePaths; private final Executor dispatchExecutor; + private final int maxStackFrames; private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher(); @@ -74,7 +75,12 @@ public LogDispatchFilter(String serverUrl, String apiKey, List maskedHea */ public LogDispatchFilter(boolean enabled, String serverUrl, String apiKey, List maskedHeaders, List excludePaths, int timeoutMs) { - this(enabled, serverUrl, apiKey, maskedHeaders, excludePaths, new RestTemplate(), null, timeoutMs); + this(enabled, serverUrl, apiKey, maskedHeaders, excludePaths, new RestTemplate(), null, timeoutMs, 100); + } + + public LogDispatchFilter(boolean enabled, String serverUrl, String apiKey, List maskedHeaders, + List excludePaths, int timeoutMs, int maxStackFrames) { + this(enabled, serverUrl, apiKey, maskedHeaders, excludePaths, new RestTemplate(), null, timeoutMs, maxStackFrames); } LogDispatchFilter(String serverUrl, String apiKey, List maskedHeaders, List excludePaths, @@ -84,10 +90,17 @@ public LogDispatchFilter(boolean enabled, String serverUrl, String apiKey, List< LogDispatchFilter(boolean enabled, String serverUrl, String apiKey, List maskedHeaders, List excludePaths, RestTemplate restTemplate, Executor dispatchExecutor, int timeoutMs) { + this(enabled, serverUrl, apiKey, maskedHeaders, excludePaths, restTemplate, dispatchExecutor, timeoutMs, 100); + } + + LogDispatchFilter(boolean enabled, String serverUrl, String apiKey, List maskedHeaders, + List excludePaths, RestTemplate restTemplate, Executor dispatchExecutor, int timeoutMs, + int maxStackFrames) { this.enabled = enabled; this.serverUrl = serverUrl; this.apiKey = apiKey; this.timeoutMs = (timeoutMs > 0) ? timeoutMs : 3000; + this.maxStackFrames = maxStackFrames > 0 ? maxStackFrames : 100; this.dispatchExecutor = dispatchExecutor; this.restTemplate = Objects.requireNonNull(restTemplate, "restTemplate"); @@ -252,8 +265,15 @@ private void pushErrorAsync(HttpServletRequest request, int statusCode, Throwabl String severity = (statusCode >= 500) ? "CRITICAL" : "WARNING"; StringBuilder stackTrace = new StringBuilder(); - for (StackTraceElement element : ex.getStackTrace()) { - stackTrace.append(element.toString()).append("\n"); + StackTraceElement[] frames = ex.getStackTrace(); + int limit = Math.min(frames.length, maxStackFrames); + for (int i = 0; i < limit; i++) { + stackTrace.append(frames[i].toString()).append("\n"); + } + if (frames.length > limit) { + stackTrace.append("... ") + .append(frames.length - limit) + .append(" more frames truncated\n"); } LogDispatchPayload payload = new LogDispatchPayload( diff --git a/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchAutoConfiguration.java b/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchAutoConfiguration.java index 47c8b0a..7a4cfae 100644 --- a/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchAutoConfiguration.java +++ b/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchAutoConfiguration.java @@ -56,7 +56,8 @@ public FilterRegistrationBean logDispatchFilterRegistration(L properties.getApiKey(), properties.getMaskedHeaders(), properties.getExcludePaths(), - properties.getTimeoutMs() + properties.getTimeoutMs(), + properties.getMaxStackFrames() )); registrationBean.addUrlPatterns("/*"); // Use Highest Precedence to ensure it wraps everything including security filters diff --git a/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchProperties.java b/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchProperties.java index 6d17fac..9b3734e 100644 --- a/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchProperties.java +++ b/src/main/java/in/maheshlangote/logdispatch/config/LogDispatchProperties.java @@ -18,6 +18,9 @@ public class LogDispatchProperties { private List excludePaths = List.of(); private int timeoutMs = 3000; + /** Max stack frames included in error payloads (default 100). */ + private int maxStackFrames = 100; + /** * Returns whether LogDispatch is enabled. * @@ -155,4 +158,23 @@ public int getTimeoutMs() { public void setTimeoutMs(int timeoutMs) { this.timeoutMs = timeoutMs; } + + /** + * Returns the maximum number of stack frames included in error payloads. + * + * @return max stack frames (default 100) + */ + public int getMaxStackFrames() { + return maxStackFrames; + } + + /** + * Sets the maximum number of stack frames included in error payloads. + * + * @param maxStackFrames positive frame cap; non-positive values fall back to 100 + */ + public void setMaxStackFrames(int maxStackFrames) { + this.maxStackFrames = maxStackFrames > 0 ? maxStackFrames : 100; + } + }