1
1
package no .nav .testnav .libs .reactivecore .logging ;
2
2
3
3
import ch .qos .logback .classic .spi .ILoggingEvent ;
4
- import ch .qos .logback .classic .spi .IThrowableProxy ;
5
4
import ch .qos .logback .classic .spi .ThrowableProxy ;
6
5
import com .fasterxml .jackson .core .JsonFactory ;
7
6
import lombok .Setter ;
8
7
import lombok .SneakyThrows ;
9
8
import lombok .extern .slf4j .Slf4j ;
10
9
import net .logstash .logback .encoder .LogstashEncoder ;
10
+ import org .springframework .util .StringUtils ;
11
11
12
12
import java .io .ByteArrayOutputStream ;
13
- import java .io .PrintWriter ;
14
13
import java .io .StringWriter ;
15
14
import java .util .regex .Pattern ;
16
15
16
+ import static java .util .Objects .isNull ;
17
17
import static java .util .Objects .nonNull ;
18
+ import static org .springframework .util .StringUtils .truncate ;
18
19
19
20
/**
20
21
* Config:
21
- * <li>{@code maxStackTraceLength}: Default 480, set to a negative number to disable truncation of stack trace altogether.</li>
22
- * <li>@{code addCauses}: If {@code true}, adds the cause(s) to the stack trace (without stack traces for each cause) Truncated according to above.</li>
22
+ * <ul>
23
+ * <li>{@code maxStackTraceLength}: Default 480, set to <1 to disable truncation of stack trace altogether.</li>
24
+ * <li>{@code addCauses}: If enabled, adds the cause(s) to the stack trace (with stack traces for each cause) Truncated according to above, filtered according to below.</li>
25
+ * <li>{@code stackTraceIncludePrefix}: If set, only include stack trace elements that starts with the given prefix, e.g. "no.nav.testnav".</li>
26
+ * </ul>
27
+ * Copy of {@code no.nav.testnav.libs.servletcore.logging.TestnavLogbackEncoder}.
28
+ *
29
+ * @see StringUtils#truncate(CharSequence, int)
23
30
*/
24
31
@ Slf4j
32
+ @ SuppressWarnings ("java:S110" )
25
33
public class TestnavLogbackEncoder extends LogstashEncoder {
26
34
27
35
// matches exactly 11 digits (\\d{11}) that are not immediately preceded ((?<!\\d)) or followed ((?!\\d)) by another digit.
@@ -33,6 +41,9 @@ public class TestnavLogbackEncoder extends LogstashEncoder {
33
41
@ Setter
34
42
private boolean addCauses = false ;
35
43
44
+ @ Setter
45
+ private String stackTraceIncludePrefix = null ;
46
+
36
47
@ SneakyThrows
37
48
@ Override
38
49
public byte [] encode (ILoggingEvent event ) {
@@ -47,21 +58,7 @@ public byte[] encode(ILoggingEvent event) {
47
58
generator .writeStringField ("logger_name" , event .getLoggerName ());
48
59
generator .writeStringField ("thread_name" , event .getThreadName ());
49
60
generator .writeStringField ("level" , event .getLevel ().toString ());
50
- if (nonNull (event .getThrowableProxy ())) {
51
- var exception = (ThrowableProxy ) event .getThrowableProxy ();
52
- if (nonNull (exception .getThrowable ())) {
53
- var sw = new StringWriter ();
54
- var pw = new PrintWriter (sw );
55
- for (StackTraceElement element : exception .getThrowable ().getStackTrace ()) {
56
- pw .println ("\t at " + element );
57
- }
58
- if (addCauses ) {
59
- recursivelyAddCauses (exception , pw );
60
- }
61
- var stackTrace = maxStackTraceLength < 0 ? sw .toString () : sw .toString ().substring (0 , maxStackTraceLength );
62
- generator .writeStringField ("stack_trace" , stackTrace );
63
- }
64
- }
61
+ generator .writeStringField ("stack_trace" , getStackTrace (event ));
65
62
generator .writeEndObject ();
66
63
67
64
generator .flush ();
@@ -71,16 +68,47 @@ public byte[] encode(ILoggingEvent event) {
71
68
return outputStream .toByteArray ();
72
69
}
73
70
74
- private static void recursivelyAddCauses (IThrowableProxy exception , PrintWriter pw ) {
75
- var cause = exception .getCause ();
76
- if (cause != null ) {
77
- pw
78
- .append ("caused by " )
79
- .append (cause .getClassName ())
80
- .append (": " )
81
- .append (cause .getMessage ())
82
- .append ("\n " );
83
- recursivelyAddCauses (cause , pw );
71
+ private String getStackTrace (ILoggingEvent event ) {
72
+ if (nonNull (event .getThrowableProxy ())) {
73
+ var exception = (ThrowableProxy ) event .getThrowableProxy ();
74
+ if (nonNull (exception .getThrowable ())) {
75
+ var writer = new StringWriter ();
76
+ appendStackTraceElements (exception .getThrowable ().getStackTrace (), writer );
77
+ appendStackTraceCauses (exception , writer );
78
+ return maxStackTraceLength > 0 ?
79
+ truncate (writer .toString (), maxStackTraceLength ) :
80
+ writer .toString ();
81
+ }
82
+ }
83
+ return null ;
84
+ }
85
+
86
+ private void appendStackTraceElements (StackTraceElement [] elements , StringWriter writer ) {
87
+ for (StackTraceElement element : elements ) {
88
+ if (isNull (stackTraceIncludePrefix ) || stackTraceIncludePrefix .isEmpty () || element .toString ().startsWith (stackTraceIncludePrefix )) {
89
+ writer
90
+ .append ("\t at " )
91
+ .append (element .toString ())
92
+ .append ("\n " );
93
+ }
94
+ }
95
+ }
96
+
97
+ private void appendStackTraceCauses (ThrowableProxy exception , StringWriter writer ) {
98
+ if (addCauses ) {
99
+ var cause = exception ;
100
+ while (!isNull (cause .getCause ())) {
101
+ cause = (ThrowableProxy ) cause .getCause ();
102
+ writer
103
+ .append ("caused by " )
104
+ .append (cause .getClassName ())
105
+ .append (": " )
106
+ .append (cause .getMessage ())
107
+ .append ("\n " );
108
+ if (!isNull (cause .getThrowable ())) {
109
+ appendStackTraceElements (cause .getThrowable ().getStackTrace (), writer );
110
+ }
111
+ }
84
112
}
85
113
}
86
114
0 commit comments