-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMgntStackTraceConverter.java
More file actions
85 lines (75 loc) · 3.29 KB
/
MgntStackTraceConverter.java
File metadata and controls
85 lines (75 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.example.stamboot.config.logging;
import com.mgnt.utils.TextUtils;
import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import org.apache.commons.lang3.StringUtils;
/**
* Custom throwable converter that replaces Logback's standard exception rendering
* with MgntUtils-based stacktrace filtering via
* {@link TextUtils#getStacktrace(Throwable, boolean)}. This class only implements
* the {@link ThrowableProxyConverter} contract — the wiring is done in
* {@code logback.xml} (see the comments there for details).
*
* <p>For details of the filtering algorithm itself and how to configure the
* relevant-package prefix, see the MgntUtils Javadoc and README.
*
* <p>The defensive shape (try/catch(Throwable), null/empty guards, conditional
* leading-newline strip) may look over-protective given the current library
* contract; it is intentional. Logback's appender drops the entire log event if a
* converter throws, and customer integrations should not rely on a third-party
* library's current internal behavior. On any unusable input the converter falls
* through to {@code super.convert(event)}, so filtering may be lost in those edge
* cases but the log event itself is not.
*
* @see TextUtils#getStacktrace(Throwable, boolean)
*/
public class MgntStackTraceConverter extends ThrowableProxyConverter {
private static volatile boolean cutTheBS = true;
@Override
public String convert(ILoggingEvent event) {
IThrowableProxy proxy = event.getThrowableProxy();
if (proxy == null) {
return "";
}
if (proxy instanceof ThrowableProxy) {
Throwable rawException = ((ThrowableProxy)proxy).getThrowable();
if (rawException != null) {
String filtered = safeGetStacktrace(rawException);
if (StringUtils.isNotEmpty(filtered)) {
// TextUtils.getStacktrace currently prepends a newline; strip it only if present
// so a future library change cannot leak a leading blank line into the output.
String body = filtered.startsWith("\n") ? filtered.substring(1) : filtered;
return body + "\n";
}
}
}
// Fallback for serialized remote exceptions, a null raw Throwable, unexpected
// library output, or a library failure — defer to standard Logback rendering so
// nothing is ever lost.
return super.convert(event);
}
/**
* Calls the MgntUtils filter under a Throwable-catching guard. An uncaught
* exception inside a Logback converter is suppressed at the appender level and
* the entire log event is dropped — so any failure (RuntimeException,
* StackOverflowError on a cyclic cause chain, LinkageError, etc.) MUST be
* contained here. Returning {@code null} causes the caller to fall through to
* {@code super.convert(event)}, which renders the standard Logback stacktrace
* (unfiltered, but never silently dropped).
*/
private String safeGetStacktrace(Throwable rawException) {
try {
return TextUtils.getStacktrace(rawException, cutTheBS);
} catch (Throwable libraryFailure) {
return null;
}
}
public static synchronized boolean isCutTheBS() {
return cutTheBS;
}
public static synchronized void setCutTheBS(boolean cutTheBs) {
MgntStackTraceConverter.cutTheBS = cutTheBs;
}
}