25
25
import io .sentry .protocol .Message ;
26
26
import io .sentry .protocol .SdkVersion ;
27
27
import io .sentry .util .CollectionUtils ;
28
+ import io .sentry .util .ContextTagsUtil ;
29
+
28
30
import java .util .Arrays ;
29
31
import java .util .Collections ;
30
32
import java .util .List ;
31
33
import java .util .Map ;
32
34
import java .util .Objects ;
33
35
import java .util .Optional ;
34
36
import java .util .stream .Collectors ;
37
+
35
38
import org .apache .logging .log4j .Level ;
36
39
import org .apache .logging .log4j .core .Filter ;
37
40
import org .apache .logging .log4j .core .LogEvent ;
44
47
import org .jetbrains .annotations .NotNull ;
45
48
import org .jetbrains .annotations .Nullable ;
46
49
47
- /** Appender for Log4j2 in charge of sending the logged events to a Sentry server. */
50
+ /**
51
+ * Appender for Log4j2 in charge of sending the logged events to a Sentry server.
52
+ */
48
53
@ Plugin (name = "Sentry" , category = "Core" , elementType = "appender" , printObject = true )
49
54
@ Open
50
55
public class SentryAppender extends AbstractAppender {
@@ -61,49 +66,49 @@ public class SentryAppender extends AbstractAppender {
61
66
62
67
static {
63
68
SentryIntegrationPackageStorage .getInstance ()
64
- .addPackage ("maven:io.sentry:sentry-log4j2" , BuildConfig .VERSION_NAME );
69
+ .addPackage ("maven:io.sentry:sentry-log4j2" , BuildConfig .VERSION_NAME );
65
70
}
66
71
67
72
/**
68
73
* @deprecated This constructor is deprecated. Please use {@link #SentryAppender(String, Filter,
69
- * String, Level, Level, Level, Boolean, ITransportFactory, IScopes, String[])} instead.
74
+ * String, Level, Level, Level, Boolean, ITransportFactory, IScopes, String[])} instead.
70
75
*/
71
76
@ Deprecated
72
77
@ SuppressWarnings ("InlineMeSuggester" )
73
78
public SentryAppender (
74
- final @ NotNull String name ,
75
- final @ Nullable Filter filter ,
76
- final @ Nullable String dsn ,
77
- final @ Nullable Level minimumBreadcrumbLevel ,
78
- final @ Nullable Level minimumEventLevel ,
79
- final @ Nullable Boolean debug ,
80
- final @ Nullable ITransportFactory transportFactory ,
81
- final @ NotNull IScopes scopes ,
82
- final @ Nullable String [] contextTags ) {
79
+ final @ NotNull String name ,
80
+ final @ Nullable Filter filter ,
81
+ final @ Nullable String dsn ,
82
+ final @ Nullable Level minimumBreadcrumbLevel ,
83
+ final @ Nullable Level minimumEventLevel ,
84
+ final @ Nullable Boolean debug ,
85
+ final @ Nullable ITransportFactory transportFactory ,
86
+ final @ NotNull IScopes scopes ,
87
+ final @ Nullable String [] contextTags ) {
83
88
this (
84
- name ,
85
- filter ,
86
- dsn ,
87
- minimumBreadcrumbLevel ,
88
- minimumEventLevel ,
89
- null ,
90
- debug ,
91
- transportFactory ,
92
- scopes ,
93
- contextTags );
89
+ name ,
90
+ filter ,
91
+ dsn ,
92
+ minimumBreadcrumbLevel ,
93
+ minimumEventLevel ,
94
+ null ,
95
+ debug ,
96
+ transportFactory ,
97
+ scopes ,
98
+ contextTags );
94
99
}
95
100
96
101
public SentryAppender (
97
- final @ NotNull String name ,
98
- final @ Nullable Filter filter ,
99
- final @ Nullable String dsn ,
100
- final @ Nullable Level minimumBreadcrumbLevel ,
101
- final @ Nullable Level minimumEventLevel ,
102
- final @ Nullable Level minimumLevel ,
103
- final @ Nullable Boolean debug ,
104
- final @ Nullable ITransportFactory transportFactory ,
105
- final @ NotNull IScopes scopes ,
106
- final @ Nullable String [] contextTags ) {
102
+ final @ NotNull String name ,
103
+ final @ Nullable Filter filter ,
104
+ final @ Nullable String dsn ,
105
+ final @ Nullable Level minimumBreadcrumbLevel ,
106
+ final @ Nullable Level minimumEventLevel ,
107
+ final @ Nullable Level minimumLevel ,
108
+ final @ Nullable Boolean debug ,
109
+ final @ Nullable ITransportFactory transportFactory ,
110
+ final @ NotNull IScopes scopes ,
111
+ final @ Nullable String [] contextTags ) {
107
112
super (name , filter , null , true , null );
108
113
this .dsn = dsn ;
109
114
if (minimumBreadcrumbLevel != null ) {
@@ -124,64 +129,64 @@ public SentryAppender(
124
129
/**
125
130
* Create a Sentry Appender.
126
131
*
127
- * @param name The name of the Appender.
132
+ * @param name The name of the Appender.
128
133
* @param minimumBreadcrumbLevel The min. level of the breadcrumb.
129
- * @param minimumEventLevel The min. level of the event.
130
- * @param minimumLevel The min. level of the log event.
131
- * @param dsn the Sentry DSN.
132
- * @param debug if Sentry debug mode should be on
133
- * @param filter The filter, if any, to use.
134
+ * @param minimumEventLevel The min. level of the event.
135
+ * @param minimumLevel The min. level of the log event.
136
+ * @param dsn the Sentry DSN.
137
+ * @param debug if Sentry debug mode should be on
138
+ * @param filter The filter, if any, to use.
134
139
* @return The SentryAppender.
135
140
*/
136
141
@ PluginFactory
137
142
public static @ Nullable SentryAppender createAppender (
138
- @ Nullable @ PluginAttribute ("name" ) final String name ,
139
- @ Nullable @ PluginAttribute ("minimumBreadcrumbLevel" ) final Level minimumBreadcrumbLevel ,
140
- @ Nullable @ PluginAttribute ("minimumEventLevel" ) final Level minimumEventLevel ,
141
- @ Nullable @ PluginAttribute ("minimumLevel" ) final Level minimumLevel ,
142
- @ Nullable @ PluginAttribute ("dsn" ) final String dsn ,
143
- @ Nullable @ PluginAttribute ("debug" ) final Boolean debug ,
144
- @ Nullable @ PluginElement ("filter" ) final Filter filter ,
145
- @ Nullable @ PluginAttribute ("contextTags" ) final String contextTags ) {
143
+ @ Nullable @ PluginAttribute ("name" ) final String name ,
144
+ @ Nullable @ PluginAttribute ("minimumBreadcrumbLevel" ) final Level minimumBreadcrumbLevel ,
145
+ @ Nullable @ PluginAttribute ("minimumEventLevel" ) final Level minimumEventLevel ,
146
+ @ Nullable @ PluginAttribute ("minimumLevel" ) final Level minimumLevel ,
147
+ @ Nullable @ PluginAttribute ("dsn" ) final String dsn ,
148
+ @ Nullable @ PluginAttribute ("debug" ) final Boolean debug ,
149
+ @ Nullable @ PluginElement ("filter" ) final Filter filter ,
150
+ @ Nullable @ PluginAttribute ("contextTags" ) final String contextTags ) {
146
151
147
152
if (name == null ) {
148
153
LOGGER .error ("No name provided for SentryAppender" );
149
154
return null ;
150
155
}
151
156
return new SentryAppender (
152
- name ,
153
- filter ,
154
- dsn ,
155
- minimumBreadcrumbLevel ,
156
- minimumEventLevel ,
157
- minimumLevel ,
158
- debug ,
159
- null ,
160
- ScopesAdapter .getInstance (),
161
- contextTags != null ? contextTags .split ("," ) : null );
157
+ name ,
158
+ filter ,
159
+ dsn ,
160
+ minimumBreadcrumbLevel ,
161
+ minimumEventLevel ,
162
+ minimumLevel ,
163
+ debug ,
164
+ null ,
165
+ ScopesAdapter .getInstance (),
166
+ contextTags != null ? contextTags .split ("," ) : null );
162
167
}
163
168
164
169
@ Override
165
170
public void start () {
166
171
try {
167
172
Sentry .init (
168
- options -> {
169
- options .setEnableExternalConfiguration (true );
170
- options .setInitPriority (InitPriority .LOWEST );
171
- options .setDsn (dsn );
172
- if (debug != null ) {
173
- options .setDebug (debug );
174
- }
175
- options .setSentryClientName (
176
- BuildConfig .SENTRY_LOG4J2_SDK_NAME + "/" + BuildConfig .VERSION_NAME );
177
- options .setSdkVersion (createSdkVersion (options ));
178
- if (contextTags != null ) {
179
- for (final String contextTag : contextTags ) {
180
- options .addContextTag (contextTag );
181
- }
173
+ options -> {
174
+ options .setEnableExternalConfiguration (true );
175
+ options .setInitPriority (InitPriority .LOWEST );
176
+ options .setDsn (dsn );
177
+ if (debug != null ) {
178
+ options .setDebug (debug );
179
+ }
180
+ options .setSentryClientName (
181
+ BuildConfig .SENTRY_LOG4J2_SDK_NAME + "/" + BuildConfig .VERSION_NAME );
182
+ options .setSdkVersion (createSdkVersion (options ));
183
+ if (contextTags != null ) {
184
+ for (final String contextTag : contextTags ) {
185
+ options .addContextTag (contextTag );
182
186
}
183
- Optional .ofNullable (transportFactory ).ifPresent (options ::setTransportFactory );
184
- });
187
+ }
188
+ Optional .ofNullable (transportFactory ).ifPresent (options ::setTransportFactory );
189
+ });
185
190
} catch (IllegalArgumentException e ) {
186
191
LOGGER .warn ("Failed to init Sentry during appender initialization: " + e .getMessage ());
187
192
}
@@ -192,7 +197,7 @@ public void start() {
192
197
@ Override
193
198
public void append (final @ NotNull LogEvent eventObject ) {
194
199
if (scopes .getOptions ().getLogs ().isEnabled ()
195
- && eventObject .getLevel ().isMoreSpecificThan (minimumLevel )) {
200
+ && eventObject .getLevel ().isMoreSpecificThan (minimumLevel )) {
196
201
captureLog (eventObject );
197
202
}
198
203
if (eventObject .getLevel ().isMoreSpecificThan (minimumEventLevel )) {
@@ -227,7 +232,12 @@ protected void captureLog(@NotNull LogEvent loggingEvent) {
227
232
228
233
if (nonFormattedMessage != null && !formattedMessage .equals (nonFormattedMessage )) {
229
234
attributes .add (
230
- SentryAttribute .stringAttribute ("sentry.message.template" , nonFormattedMessage ));
235
+ SentryAttribute .stringAttribute ("sentry.message.template" , nonFormattedMessage ));
236
+ }
237
+
238
+ final Map <String , String > contextData = loggingEvent .getContextData ().toMap ();
239
+ if (contextData != null ) {
240
+ ContextTagsUtil .applyContextTagsToLogAttributes (attributes , contextData );
231
241
}
232
242
233
243
final @ NotNull SentryLogParameters params = SentryLogParameters .create (attributes );
@@ -259,8 +269,8 @@ protected void captureLog(@NotNull LogEvent loggingEvent) {
259
269
final Mechanism mechanism = new Mechanism ();
260
270
mechanism .setType (MECHANISM_TYPE );
261
271
final Throwable mechanismException =
262
- new ExceptionMechanismException (
263
- mechanism , throwableInformation .getThrowable (), Thread .currentThread ());
272
+ new ExceptionMechanismException (
273
+ mechanism , throwableInformation .getThrowable (), Thread .currentThread ());
264
274
event .setThrowable (mechanismException );
265
275
}
266
276
@@ -273,21 +283,14 @@ protected void captureLog(@NotNull LogEvent loggingEvent) {
273
283
}
274
284
275
285
final Map <String , String > contextData =
276
- CollectionUtils .filterMapEntries (
277
- loggingEvent .getContextData ().toMap (), entry -> entry .getValue () != null );
286
+ CollectionUtils .filterMapEntries (
287
+ loggingEvent .getContextData ().toMap (), entry -> entry .getValue () != null );
278
288
if (!contextData .isEmpty ()) {
279
289
// get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been
280
290
// initialized somewhere else
281
291
final List <String > contextTags = scopes .getOptions ().getContextTags ();
282
- if (contextTags != null && !contextTags .isEmpty ()) {
283
- for (final String contextTag : contextTags ) {
284
- // if mdc tag is listed in SentryOptions, apply as event tag
285
- if (contextData .containsKey (contextTag )) {
286
- event .setTag (contextTag , contextData .get (contextTag ));
287
- // remove from all tags applied to logging event
288
- contextData .remove (contextTag );
289
- }
290
- }
292
+ if (contextTags != null ) {
293
+ ContextTagsUtil .applyContextTagsToEvent (event , contextTags , contextData );
291
294
}
292
295
// put the rest of mdc tags in contexts
293
296
if (!contextData .isEmpty ()) {
@@ -301,9 +304,9 @@ protected void captureLog(@NotNull LogEvent loggingEvent) {
301
304
private @ NotNull List <String > toParams (final @ Nullable Object [] arguments ) {
302
305
if (arguments != null ) {
303
306
return Arrays .stream (arguments )
304
- .filter (Objects ::nonNull )
305
- .map (Object ::toString )
306
- .collect (Collectors .toList ());
307
+ .filter (Objects ::nonNull )
308
+ .map (Object ::toString )
309
+ .collect (Collectors .toList ());
307
310
} else {
308
311
return Collections .emptyList ();
309
312
}
0 commit comments