From 042dcefec9ceef1e9ae8fe59c6e3a9bfc19d95b2 Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Tue, 22 Mar 2022 12:23:29 +0100 Subject: [PATCH 1/9] Pass MDC tags as Sentry tags in Logback integration. --- .../io/sentry/logback/SentryAppender.java | 15 ++++++++++++- .../io/sentry/logback/SentryAppenderTest.kt | 19 ++++++++++++++++- .../src/main/resources/logback.xml | 1 + .../main/java/io/sentry/SentryOptions.java | 21 +++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java index a7d6a321029..627a469ff5a 100644 --- a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java +++ b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java @@ -112,7 +112,20 @@ protected void append(@NotNull ILoggingEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getMDCPropertyMap(), entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - event.getContexts().put("MDC", mdcProperties); + if (!options.getMdcTags().isEmpty()) { + for (final String mdcTag : options.getMdcTags()) { + // if mdc tag is listed in SentryOptions, apply as event tag + if (mdcProperties.containsKey(mdcTag)) { + event.setTag(mdcTag, mdcProperties.get(mdcTag)); + // remove from all tags applied to logging event + mdcProperties.remove(mdcTag); + } + } + } + // put the rest of mdc tags in contexts + if (!mdcProperties.isEmpty()) { + event.getContexts().put("MDC", mdcProperties); + } } return event; diff --git a/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt b/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt index 4eb90906e80..29424c19e71 100644 --- a/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt +++ b/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt @@ -31,7 +31,7 @@ import kotlin.test.assertNull import kotlin.test.assertTrue class SentryAppenderTest { - private class Fixture(dsn: String? = "http://key@localhost/proj", minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null) { + private class Fixture(dsn: String? = "http://key@localhost/proj", minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, mdcTags: List? = null) { val logger: Logger = LoggerFactory.getLogger(SentryAppenderTest::class.java) val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext val transportFactory = mock() @@ -43,6 +43,7 @@ class SentryAppenderTest { val appender = SentryAppender() val options = SentryOptions() options.dsn = dsn + mdcTags?.forEach { options.addMdcTag(it) } appender.setOptions(options) appender.setMinimumBreadcrumbLevel(minimumBreadcrumbLevel) appender.setMinimumEventLevel(minimumEventLevel) @@ -217,6 +218,22 @@ class SentryAppenderTest { ) } + @Test + fun `sets tags as sentry tags from MDC`() { + fixture = Fixture(minimumEventLevel = Level.WARN, mdcTags = listOf("mdcTag1")) + MDC.put("key", "value") + MDC.put("mdcTag1", "mdcTag1Value") + fixture.logger.warn("testing MDC tags") + + verify(fixture.transport).send( + checkEvent { event -> + assertEquals(mapOf("key" to "value"), event.contexts["MDC"]) + assertEquals(mapOf("mdcTag1" to "mdcTag1Value"), event.tags) + }, + anyOrNull() + ) + } + @Test fun `ignore set tags with null values from MDC`() { fixture = Fixture(minimumEventLevel = Level.WARN) diff --git a/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml b/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml index 9c975143122..33cc93951da 100644 --- a/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml +++ b/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml @@ -11,6 +11,7 @@ true https://502f25099c204a2fbf4cb16edc5975d1@o447951.ingest.sentry.io/5428563 + userId diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index f9bd8d9c186..1a0aa72dbfe 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -297,6 +297,11 @@ public class SentryOptions { /** Proguard UUID. */ private @Nullable String proguardUuid; + /** + * Contains a list of MDC tags names that are meant to be applied as Sentry tags to events. + */ + private final @NotNull List mdcTags = new CopyOnWriteArrayList<>(); + /** * Adds an event processor * @@ -1442,6 +1447,22 @@ public void setProguardUuid(final @Nullable String proguardUuid) { this.proguardUuid = proguardUuid; } + /** + * Returns MDC tags names applied to Sentry events as Sentry tags. + * @return mdc tags + */ + public @NotNull List getMdcTags() { + return mdcTags; + } + + /** + * Adds MDC tag name that is applied to Sentry events as Sentry tag. + * @param mdcTag - the MDC tag + */ + public void addMdcTag(final @NotNull String mdcTag) { + this.mdcTags.add(mdcTag); + } + /** The BeforeSend callback */ public interface BeforeSendCallback { From c83507687e8b7d849c91eb96469d816d51c6c8b3 Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Tue, 22 Mar 2022 12:39:52 +0100 Subject: [PATCH 2/9] Pass MDC tags as Sentry tags in Log4j2 integration. --- .../java/io/sentry/log4j2/SentryAppender.java | 32 ++++++++++++++++--- .../io/sentry/log4j2/SentryAppenderTest.kt | 20 ++++++++++-- .../src/main/resources/log4j2.xml | 2 ++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java index 3e4390532d4..7860b00d398 100644 --- a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java +++ b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java @@ -16,6 +16,7 @@ import io.sentry.protocol.Message; import io.sentry.protocol.SdkVersion; import io.sentry.util.CollectionUtils; + import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -46,6 +47,7 @@ public class SentryAppender extends AbstractAppender { private @NotNull Level minimumEventLevel = Level.ERROR; private final @Nullable Boolean debug; private final @NotNull IHub hub; + private final @Nullable List mdcTags; public SentryAppender( final @NotNull String name, @@ -55,7 +57,8 @@ public SentryAppender( final @Nullable Level minimumEventLevel, final @Nullable Boolean debug, final @Nullable ITransportFactory transportFactory, - final @NotNull IHub hub) { + final @NotNull IHub hub, + final @Nullable String[] mdcTags) { super(name, filter, null, true, null); this.dsn = dsn; if (minimumBreadcrumbLevel != null) { @@ -67,6 +70,7 @@ public SentryAppender( this.debug = debug; this.transportFactory = transportFactory; this.hub = hub; + this.mdcTags = mdcTags != null ? Arrays.asList(mdcTags) : null; } /** @@ -87,7 +91,8 @@ public SentryAppender( @Nullable @PluginAttribute("minimumEventLevel") final Level minimumEventLevel, @Nullable @PluginAttribute("dsn") final String dsn, @Nullable @PluginAttribute("debug") final Boolean debug, - @Nullable @PluginElement("filter") final Filter filter) { + @Nullable @PluginElement("filter") final Filter filter, + @Nullable @PluginAttribute("mdcTags") final String mdcTags) { if (name == null) { LOGGER.error("No name provided for SentryAppender"); @@ -101,7 +106,8 @@ public SentryAppender( minimumEventLevel, debug, null, - HubAdapter.getInstance()); + HubAdapter.getInstance(), + mdcTags != null ? mdcTags.split(",") : null); } @Override @@ -117,6 +123,11 @@ public void start() { } options.setSentryClientName(BuildConfig.SENTRY_LOG4J2_SDK_NAME); options.setSdkVersion(createSdkVersion(options)); + if (mdcTags != null) { + for (final String mdcTag : mdcTags) { + options.addMdcTag(mdcTag); + } + } Optional.ofNullable(transportFactory).ifPresent(options::setTransportFactory); }); } catch (IllegalArgumentException e) { @@ -177,7 +188,20 @@ public void append(final @NotNull LogEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getContextData().toMap(), entry -> entry.getValue() != null); if (!contextData.isEmpty()) { - event.getContexts().put("Context Data", contextData); + if (mdcTags != null && !mdcTags.isEmpty()) { + for (final String mdcTag : mdcTags) { + // if mdc tag is listed in SentryOptions, apply as event tag + if (contextData.containsKey(mdcTag)) { + event.setTag(mdcTag, contextData.get(mdcTag)); + // remove from all tags applied to logging event + contextData.remove(mdcTag); + } + } + } + // put the rest of mdc tags in contexts + if (!contextData.isEmpty()) { + event.getContexts().put("Context Data", contextData); + } } return event; diff --git a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt index aee203f1d62..01c781f3af6 100644 --- a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt +++ b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt @@ -43,13 +43,13 @@ class SentryAppenderTest { whenever(transportFactory.create(any(), any())).thenReturn(transport) } - fun getSut(transportFactory: ITransportFactory? = null, minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, debug: Boolean? = null): ExtendedLogger { + fun getSut(transportFactory: ITransportFactory? = null, minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, debug: Boolean? = null, mdcTags: List? = null): ExtendedLogger { if (transportFactory != null) { this.transportFactory = transportFactory } loggerContext.start() val config: Configuration = loggerContext.configuration - val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, HubAdapter.getInstance()) + val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, HubAdapter.getInstance(), mdcTags?.toTypedArray()) config.addAppender(appender) val ref = AppenderRef.createAppenderRef("sentry", null, null) @@ -241,6 +241,22 @@ class SentryAppenderTest { ) } + @Test + fun `sets tags from ThreadContext as Sentry tags`() { + val logger = fixture.getSut(minimumEventLevel = Level.WARN, mdcTags = listOf("mdcTag1")) + ThreadContext.put("key", "value") + ThreadContext.put("mdcTag1", "mdcTag1Value") + logger.warn("testing MDC tags") + + verify(fixture.transport).send( + checkEvent { event -> + assertEquals(mapOf("key" to "value"), event.contexts["Context Data"]) + assertEquals(mapOf("mdcTag1" to "mdcTag1Value"), event.tags) + }, + anyOrNull() + ) + } + @Test fun `ignore set tags with null values from ThreadContext`() { val logger = fixture.getSut(minimumEventLevel = Level.WARN) diff --git a/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml b/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml index 8e6c14fd921..214833775c8 100644 --- a/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml +++ b/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml @@ -11,6 +11,8 @@ dsn="https://502f25099c204a2fbf4cb16edc5975d1@o447951.ingest.sentry.io/5428563" minimumBreadcrumbLevel="DEBUG" minimumEventLevel="WARN" + debug="true" + mdcTags="userId" /> From f55be8b68b8c9ab7884dc6842b4895727dabf24d Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Tue, 22 Mar 2022 12:46:48 +0100 Subject: [PATCH 3/9] Configure MDC tags through external configuration. --- sentry/src/main/java/io/sentry/ExternalOptions.java | 12 ++++++++++++ sentry/src/main/java/io/sentry/SentryOptions.java | 4 ++++ .../src/test/java/io/sentry/ExternalOptionsTest.kt | 7 +++++++ sentry/src/test/java/io/sentry/SentryOptionsTest.kt | 3 +++ 4 files changed, 26 insertions(+) diff --git a/sentry/src/main/java/io/sentry/ExternalOptions.java b/sentry/src/main/java/io/sentry/ExternalOptions.java index ae70b091a83..3a8a62449a3 100644 --- a/sentry/src/main/java/io/sentry/ExternalOptions.java +++ b/sentry/src/main/java/io/sentry/ExternalOptions.java @@ -32,6 +32,7 @@ public final class ExternalOptions { private final @NotNull List inAppExcludes = new CopyOnWriteArrayList<>(); private final @NotNull List inAppIncludes = new CopyOnWriteArrayList<>(); private final @NotNull List tracingOrigins = new CopyOnWriteArrayList<>(); + private final @NotNull List mdcTags = new CopyOnWriteArrayList<>(); private @Nullable String proguardUuid; private final @NotNull Set> ignoredExceptionsForType = new CopyOnWriteArraySet<>(); @@ -81,6 +82,9 @@ public final class ExternalOptions { for (final String tracingOrigin : propertiesProvider.getList("tracing-origins")) { options.addTracingOrigin(tracingOrigin); } + for (final String mdcTag : propertiesProvider.getList("mdc-tags")) { + options.addMdcTag(mdcTag); + } options.setProguardUuid(propertiesProvider.getProperty("proguard-uuid")); for (final String ignoredExceptionType : @@ -212,6 +216,10 @@ public void setProxy(final @Nullable SentryOptions.Proxy proxy) { return inAppIncludes; } + public @NotNull List getMdcTags() { + return mdcTags; + } + public @Nullable String getProguardUuid() { return proguardUuid; } @@ -236,6 +244,10 @@ public void addTracingOrigin(final @NotNull String tracingOrigin) { this.tracingOrigins.add(tracingOrigin); } + public void addMdcTag(final @NotNull String mdcTag) { + this.mdcTags.add(mdcTag); + } + public void addIgnoredExceptionForType(final @NotNull Class exceptionType) { this.ignoredExceptionsForType.add(exceptionType); } diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index 1a0aa72dbfe..ace7ceb8609 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -1610,6 +1610,10 @@ void merge(final @NotNull ExternalOptions options) { for (final String tracingOrigin : tracingOrigins) { addTracingOrigin(tracingOrigin); } + final List mdcTags = new ArrayList<>(options.getMdcTags()); + for (final String mdcTag : mdcTags) { + addMdcTag(mdcTag); + } if (options.getProguardUuid() != null) { setProguardUuid(options.getProguardUuid()); } diff --git a/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt b/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt index ae9b5d2af1a..13d2b8120d9 100644 --- a/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt +++ b/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt @@ -136,6 +136,13 @@ class ExternalOptionsTest { } } + @Test + fun `creates options with mdc tags using external properties`() { + withPropertiesFile("mdc-tags=userId,xxx") { + assertEquals(listOf("userId", "xxx"), it.mdcTags) + } + } + @Test fun `creates options with proguardUuid using external properties`() { withPropertiesFile("proguard-uuid=id") { diff --git a/sentry/src/test/java/io/sentry/SentryOptionsTest.kt b/sentry/src/test/java/io/sentry/SentryOptionsTest.kt index 79ab2b0b340..f8872e81eb8 100644 --- a/sentry/src/test/java/io/sentry/SentryOptionsTest.kt +++ b/sentry/src/test/java/io/sentry/SentryOptionsTest.kt @@ -199,6 +199,8 @@ class SentryOptionsTest { externalOptions.addInAppExclude("io.off") externalOptions.addTracingOrigin("localhost") externalOptions.addTracingOrigin("api.foo.com") + externalOptions.addMdcTag("userId") + externalOptions.addMdcTag("requestId") val options = SentryOptions() options.merge(externalOptions) @@ -217,6 +219,7 @@ class SentryOptionsTest { assertEquals(listOf("com.app"), options.inAppIncludes) assertEquals(listOf("io.off"), options.inAppExcludes) assertEquals(listOf("localhost", "api.foo.com"), options.tracingOrigins) + assertEquals(listOf("userId", "requestId"), options.mdcTags) } @Test From 3cffcfb33bff3c8c55596d6573a077f78c1f91ea Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Tue, 22 Mar 2022 12:52:40 +0100 Subject: [PATCH 4/9] Polish. --- sentry-log4j2/api/sentry-log4j2.api | 4 ++-- .../src/main/java/io/sentry/log4j2/SentryAppender.java | 3 +-- sentry/api/sentry.api | 4 ++++ sentry/src/main/java/io/sentry/SentryOptions.java | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sentry-log4j2/api/sentry-log4j2.api b/sentry-log4j2/api/sentry-log4j2.api index acf62cf1c3d..d94493083aa 100644 --- a/sentry-log4j2/api/sentry-log4j2.api +++ b/sentry-log4j2/api/sentry-log4j2.api @@ -4,9 +4,9 @@ public final class io/sentry/log4j2/BuildConfig { } public class io/sentry/log4j2/SentryAppender : org/apache/logging/log4j/core/appender/AbstractAppender { - public fun (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IHub;)V + public fun (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IHub;[Ljava/lang/String;)V public fun append (Lorg/apache/logging/log4j/core/LogEvent;)V - public static fun createAppender (Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/String;Ljava/lang/Boolean;Lorg/apache/logging/log4j/core/Filter;)Lio/sentry/log4j2/SentryAppender; + public static fun createAppender (Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/String;Ljava/lang/Boolean;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;)Lio/sentry/log4j2/SentryAppender; protected fun createBreadcrumb (Lorg/apache/logging/log4j/core/LogEvent;)Lio/sentry/Breadcrumb; protected fun createEvent (Lorg/apache/logging/log4j/core/LogEvent;)Lio/sentry/SentryEvent; public fun start ()V diff --git a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java index 7860b00d398..a2b8303834f 100644 --- a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java +++ b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java @@ -16,7 +16,6 @@ import io.sentry.protocol.Message; import io.sentry.protocol.SdkVersion; import io.sentry.util.CollectionUtils; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -107,7 +106,7 @@ public SentryAppender( debug, null, HubAdapter.getInstance(), - mdcTags != null ? mdcTags.split(",") : null); + mdcTags != null ? mdcTags.split(",") : null); } @Override diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 4f971c653d8..6e9d8cd0648 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -127,6 +127,7 @@ public final class io/sentry/ExternalOptions { public fun addIgnoredExceptionForType (Ljava/lang/Class;)V public fun addInAppExclude (Ljava/lang/String;)V public fun addInAppInclude (Ljava/lang/String;)V + public fun addMdcTag (Ljava/lang/String;)V public fun addTracingOrigin (Ljava/lang/String;)V public static fun from (Lio/sentry/config/PropertiesProvider;Lio/sentry/ILogger;)Lio/sentry/ExternalOptions; public fun getDebug ()Ljava/lang/Boolean; @@ -139,6 +140,7 @@ public final class io/sentry/ExternalOptions { public fun getInAppExcludes ()Ljava/util/List; public fun getInAppIncludes ()Ljava/util/List; public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize; + public fun getMdcTags ()Ljava/util/List; public fun getPrintUncaughtStackTrace ()Ljava/lang/Boolean; public fun getProguardUuid ()Ljava/lang/String; public fun getProxy ()Lio/sentry/SentryOptions$Proxy; @@ -998,6 +1000,7 @@ public class io/sentry/SentryOptions { public fun addInAppExclude (Ljava/lang/String;)V public fun addInAppInclude (Ljava/lang/String;)V public fun addIntegration (Lio/sentry/Integration;)V + public fun addMdcTag (Ljava/lang/String;)V public fun addScopeObserver (Lio/sentry/IScopeObserver;)V public fun addTracingOrigin (Ljava/lang/String;)V public fun getBeforeBreadcrumb ()Lio/sentry/SentryOptions$BeforeBreadcrumbCallback; @@ -1026,6 +1029,7 @@ public class io/sentry/SentryOptions { public fun getMaxQueueSize ()I public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize; public fun getMaxSpans ()I + public fun getMdcTags ()Ljava/util/List; public fun getOutboxPath ()Ljava/lang/String; public fun getPrintUncaughtStackTrace ()Ljava/lang/Boolean; public fun getProguardUuid ()Ljava/lang/String; diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index ace7ceb8609..c8e31fdc398 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -297,9 +297,7 @@ public class SentryOptions { /** Proguard UUID. */ private @Nullable String proguardUuid; - /** - * Contains a list of MDC tags names that are meant to be applied as Sentry tags to events. - */ + /** Contains a list of MDC tags names that are meant to be applied as Sentry tags to events. */ private final @NotNull List mdcTags = new CopyOnWriteArrayList<>(); /** @@ -1449,6 +1447,7 @@ public void setProguardUuid(final @Nullable String proguardUuid) { /** * Returns MDC tags names applied to Sentry events as Sentry tags. + * * @return mdc tags */ public @NotNull List getMdcTags() { @@ -1457,6 +1456,7 @@ public void setProguardUuid(final @Nullable String proguardUuid) { /** * Adds MDC tag name that is applied to Sentry events as Sentry tag. + * * @param mdcTag - the MDC tag */ public void addMdcTag(final @NotNull String mdcTag) { From 225c88b4d361352b125b611d85fea09e94d96c36 Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Tue, 22 Mar 2022 12:59:58 +0100 Subject: [PATCH 5/9] Pass MDC tags as Sentry tags in JUL integration. --- .../java/io/sentry/jul/SentryHandler.java | 17 ++++++++++++++++- .../kotlin/io/sentry/jul/SentryHandlerTest.kt | 19 ++++++++++++++++++- .../src/main/resources/sentry.properties | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java index bb8ee6672f8..ccf84d9b57d 100644 --- a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java +++ b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java @@ -42,6 +42,7 @@ public class SentryHandler extends Handler { private @NotNull Level minimumBreadcrumbLevel = Level.INFO; private @NotNull Level minimumEventLevel = Level.SEVERE; + private @NotNull SentryOptions options; /** Creates an instance of SentryHandler. */ public SentryHandler() { @@ -60,6 +61,7 @@ public SentryHandler(final @NotNull SentryOptions options) { /** Creates an instance of SentryHandler. */ @TestOnly SentryHandler(final @NotNull SentryOptions options, final boolean configureFromLogManager) { + this.options = options; setFilter(new DropSentryFilter()); if (configureFromLogManager) { retrieveProperties(); @@ -200,7 +202,20 @@ SentryEvent createEvent(final @NotNull LogRecord record) { mdcProperties = CollectionUtils.filterMapEntries(mdcProperties, entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - event.getContexts().put("MDC", mdcProperties); + if (!options.getMdcTags().isEmpty()) { + for (final String mdcTag : options.getMdcTags()) { + // if mdc tag is listed in SentryOptions, apply as event tag + if (mdcProperties.containsKey(mdcTag)) { + event.setTag(mdcTag, mdcProperties.get(mdcTag)); + // remove from all tags applied to logging event + mdcProperties.remove(mdcTag); + } + } + } + // put the rest of mdc tags in contexts + if (!mdcProperties.isEmpty()) { + event.getContexts().put("MDC", mdcProperties); + } } } event.setExtra(THREAD_ID, record.getThreadID()); diff --git a/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt b/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt index cee91eae4f9..a1f8b1eb6a1 100644 --- a/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt +++ b/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt @@ -24,7 +24,7 @@ import kotlin.test.assertNull import kotlin.test.assertTrue class SentryHandlerTest { - private class Fixture(minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, val configureWithLogManager: Boolean = false, val transport: ITransport = mock()) { + private class Fixture(minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, val configureWithLogManager: Boolean = false, val transport: ITransport = mock(), mdcTags: List? = null) { var logger: Logger var handler: SentryHandler @@ -32,6 +32,7 @@ class SentryHandlerTest { val options = SentryOptions() options.dsn = "http://key@localhost/proj" options.setTransportFactory { _, _ -> transport } + mdcTags?.forEach { options.addMdcTag(it) } logger = Logger.getLogger("jul.SentryHandlerTest") handler = SentryHandler(options, configureWithLogManager) handler.setMinimumBreadcrumbLevel(minimumBreadcrumbLevel) @@ -312,6 +313,22 @@ class SentryHandlerTest { ) } + @Test + fun `sets tags as Sentry tags from MDC`() { + fixture = Fixture(minimumEventLevel = Level.WARNING, mdcTags = listOf("mdcTag1")) + MDC.put("key", "value") + MDC.put("mdcTag1", "mdcTag1Value") + fixture.logger.warning("testing MDC tags") + + verify(fixture.transport).send( + checkEvent { event -> + assertEquals(mapOf("key" to "value"), event.contexts["MDC"]) + assertEquals(mapOf("mdcTag1" to "mdcTag1Value"), event.tags) + }, + anyOrNull() + ) + } + @Test fun `ignore set tags with null values from MDC`() { fixture = Fixture(minimumEventLevel = Level.WARNING) diff --git a/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties b/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties index 2e16561f95e..33aa8a09517 100644 --- a/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties +++ b/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties @@ -3,3 +3,4 @@ dsn=https://502f25099c204a2fbf4cb16edc5975d1@o447951.ingest.sentry.io/5428563 debug=true environment=staging in-app-includes=io.sentry.samples +mdc-tags=userId,requestId From 970e591a8f3fa79280501f2cfa2882fa3dc33a82 Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Tue, 22 Mar 2022 13:41:46 +0100 Subject: [PATCH 6/9] Changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac6987f147b..a35ffe04e52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Ref: Remove not needed interface abstractions on Android (#1953) +* Feat: Pass MDC tags as Sentry tags (#1954) ## 6.0.0-alpha.3 From de4067d5162ebb73fbe61f43185cf546cac4348d Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Wed, 23 Mar 2022 09:00:29 +0100 Subject: [PATCH 7/9] Update logback sample to include multiple tags. --- .../src/main/java/io/sentry/samples/logback/Main.java | 5 ++++- .../sentry-samples-logback/src/main/resources/logback.xml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sentry-samples/sentry-samples-logback/src/main/java/io/sentry/samples/logback/Main.java b/sentry-samples/sentry-samples-logback/src/main/java/io/sentry/samples/logback/Main.java index 6437c59f475..4aeae0038f0 100644 --- a/sentry-samples/sentry-samples-logback/src/main/java/io/sentry/samples/logback/Main.java +++ b/sentry-samples/sentry-samples-logback/src/main/java/io/sentry/samples/logback/Main.java @@ -11,8 +11,11 @@ public class Main { public static void main(String[] args) { LOGGER.debug("Hello Sentry!"); - // MDC parameters are converted to Sentry Event tags + // MDC tags listed in logback.xml are converted to Sentry Event tags MDC.put("userId", UUID.randomUUID().toString()); + MDC.put("requestId", UUID.randomUUID().toString()); + // MDC tag not listed in logback.xml + MDC.put("context-tag", "context-tag-value"); // logging arguments are converted to Sentry Event parameters LOGGER.info("User has made a purchase of product: {}", 445); diff --git a/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml b/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml index 33cc93951da..2e7b9f82c7c 100644 --- a/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml +++ b/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml @@ -12,6 +12,7 @@ https://502f25099c204a2fbf4cb16edc5975d1@o447951.ingest.sentry.io/5428563 userId + requestId From 747afcf41d7e2b2bbc54edc54c383a3acf6bef2a Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Wed, 23 Mar 2022 09:02:35 +0100 Subject: [PATCH 8/9] Update log4j2 sample to include multiple tags. --- .../src/main/java/io/sentry/samples/log4j2/Main.java | 5 ++++- .../sentry-samples-log4j2/src/main/resources/log4j2.xml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sentry-samples/sentry-samples-log4j2/src/main/java/io/sentry/samples/log4j2/Main.java b/sentry-samples/sentry-samples-log4j2/src/main/java/io/sentry/samples/log4j2/Main.java index 34ef7d86a17..9a7612354a6 100644 --- a/sentry-samples/sentry-samples-log4j2/src/main/java/io/sentry/samples/log4j2/Main.java +++ b/sentry-samples/sentry-samples-log4j2/src/main/java/io/sentry/samples/log4j2/Main.java @@ -13,8 +13,11 @@ public static void main(String[] args) { // Update the DSN in log4j2.xml to see these events in your Sentry dashboard. LOGGER.debug("Hello Sentry!"); - // ThreadContext parameters are converted to Sentry Event tags + // ThreadContext tags listed in log4j2.xml are converted to Sentry Event tags ThreadContext.put("userId", UUID.randomUUID().toString()); + ThreadContext.put("requestId", UUID.randomUUID().toString()); + // ThreadContext tag not listed in log4j2.xml + ThreadContext.put("context-tag", "context-tag-value"); // logging arguments are converted to Sentry Event parameters LOGGER.info("User has made a purchase of product: {}", 445); diff --git a/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml b/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml index 214833775c8..eb16e9a2a8b 100644 --- a/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml +++ b/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml @@ -12,7 +12,7 @@ minimumBreadcrumbLevel="DEBUG" minimumEventLevel="WARN" debug="true" - mdcTags="userId" + mdcTags="userId,requestId" /> From 01bac90573ea77c497484019c7432212ac8608da Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Fri, 25 Mar 2022 12:42:01 +0100 Subject: [PATCH 9/9] Rename `mdcTags` to `contextTags`. --- .../java/io/sentry/jul/SentryHandler.java | 10 +++---- .../kotlin/io/sentry/jul/SentryHandlerTest.kt | 10 +++---- .../java/io/sentry/log4j2/SentryAppender.java | 26 ++++++++--------- .../io/sentry/log4j2/SentryAppenderTest.kt | 10 +++---- .../io/sentry/logback/SentryAppender.java | 10 +++---- .../io/sentry/logback/SentryAppenderTest.kt | 10 +++---- .../src/main/resources/sentry.properties | 2 +- .../src/main/resources/log4j2.xml | 2 +- .../src/main/resources/logback.xml | 4 +-- sentry/api/sentry.api | 8 ++--- .../main/java/io/sentry/ExternalOptions.java | 14 ++++----- .../main/java/io/sentry/SentryOptions.java | 29 ++++++++++--------- .../java/io/sentry/ExternalOptionsTest.kt | 6 ++-- .../test/java/io/sentry/SentryOptionsTest.kt | 6 ++-- 14 files changed, 75 insertions(+), 72 deletions(-) diff --git a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java index ccf84d9b57d..b1b2be0dbad 100644 --- a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java +++ b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java @@ -202,13 +202,13 @@ SentryEvent createEvent(final @NotNull LogRecord record) { mdcProperties = CollectionUtils.filterMapEntries(mdcProperties, entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - if (!options.getMdcTags().isEmpty()) { - for (final String mdcTag : options.getMdcTags()) { + if (!options.getContextTags().isEmpty()) { + for (final String contextTag : options.getContextTags()) { // if mdc tag is listed in SentryOptions, apply as event tag - if (mdcProperties.containsKey(mdcTag)) { - event.setTag(mdcTag, mdcProperties.get(mdcTag)); + if (mdcProperties.containsKey(contextTag)) { + event.setTag(contextTag, mdcProperties.get(contextTag)); // remove from all tags applied to logging event - mdcProperties.remove(mdcTag); + mdcProperties.remove(contextTag); } } } diff --git a/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt b/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt index a1f8b1eb6a1..b365eacd104 100644 --- a/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt +++ b/sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt @@ -24,7 +24,7 @@ import kotlin.test.assertNull import kotlin.test.assertTrue class SentryHandlerTest { - private class Fixture(minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, val configureWithLogManager: Boolean = false, val transport: ITransport = mock(), mdcTags: List? = null) { + private class Fixture(minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, val configureWithLogManager: Boolean = false, val transport: ITransport = mock(), contextTags: List? = null) { var logger: Logger var handler: SentryHandler @@ -32,7 +32,7 @@ class SentryHandlerTest { val options = SentryOptions() options.dsn = "http://key@localhost/proj" options.setTransportFactory { _, _ -> transport } - mdcTags?.forEach { options.addMdcTag(it) } + contextTags?.forEach { options.addContextTag(it) } logger = Logger.getLogger("jul.SentryHandlerTest") handler = SentryHandler(options, configureWithLogManager) handler.setMinimumBreadcrumbLevel(minimumBreadcrumbLevel) @@ -315,15 +315,15 @@ class SentryHandlerTest { @Test fun `sets tags as Sentry tags from MDC`() { - fixture = Fixture(minimumEventLevel = Level.WARNING, mdcTags = listOf("mdcTag1")) + fixture = Fixture(minimumEventLevel = Level.WARNING, contextTags = listOf("contextTag1")) MDC.put("key", "value") - MDC.put("mdcTag1", "mdcTag1Value") + MDC.put("contextTag1", "contextTag1Value") fixture.logger.warning("testing MDC tags") verify(fixture.transport).send( checkEvent { event -> assertEquals(mapOf("key" to "value"), event.contexts["MDC"]) - assertEquals(mapOf("mdcTag1" to "mdcTag1Value"), event.tags) + assertEquals(mapOf("contextTag1" to "contextTag1Value"), event.tags) }, anyOrNull() ) diff --git a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java index a2b8303834f..9d04b401ce3 100644 --- a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java +++ b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java @@ -46,7 +46,7 @@ public class SentryAppender extends AbstractAppender { private @NotNull Level minimumEventLevel = Level.ERROR; private final @Nullable Boolean debug; private final @NotNull IHub hub; - private final @Nullable List mdcTags; + private final @Nullable List contextTags; public SentryAppender( final @NotNull String name, @@ -57,7 +57,7 @@ public SentryAppender( final @Nullable Boolean debug, final @Nullable ITransportFactory transportFactory, final @NotNull IHub hub, - final @Nullable String[] mdcTags) { + final @Nullable String[] contextTags) { super(name, filter, null, true, null); this.dsn = dsn; if (minimumBreadcrumbLevel != null) { @@ -69,7 +69,7 @@ public SentryAppender( this.debug = debug; this.transportFactory = transportFactory; this.hub = hub; - this.mdcTags = mdcTags != null ? Arrays.asList(mdcTags) : null; + this.contextTags = contextTags != null ? Arrays.asList(contextTags) : null; } /** @@ -91,7 +91,7 @@ public SentryAppender( @Nullable @PluginAttribute("dsn") final String dsn, @Nullable @PluginAttribute("debug") final Boolean debug, @Nullable @PluginElement("filter") final Filter filter, - @Nullable @PluginAttribute("mdcTags") final String mdcTags) { + @Nullable @PluginAttribute("contextTags") final String contextTags) { if (name == null) { LOGGER.error("No name provided for SentryAppender"); @@ -106,7 +106,7 @@ public SentryAppender( debug, null, HubAdapter.getInstance(), - mdcTags != null ? mdcTags.split(",") : null); + contextTags != null ? contextTags.split(",") : null); } @Override @@ -122,9 +122,9 @@ public void start() { } options.setSentryClientName(BuildConfig.SENTRY_LOG4J2_SDK_NAME); options.setSdkVersion(createSdkVersion(options)); - if (mdcTags != null) { - for (final String mdcTag : mdcTags) { - options.addMdcTag(mdcTag); + if (contextTags != null) { + for (final String contextTag : contextTags) { + options.addContextTag(contextTag); } } Optional.ofNullable(transportFactory).ifPresent(options::setTransportFactory); @@ -187,13 +187,13 @@ public void append(final @NotNull LogEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getContextData().toMap(), entry -> entry.getValue() != null); if (!contextData.isEmpty()) { - if (mdcTags != null && !mdcTags.isEmpty()) { - for (final String mdcTag : mdcTags) { + if (contextTags != null && !contextTags.isEmpty()) { + for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag - if (contextData.containsKey(mdcTag)) { - event.setTag(mdcTag, contextData.get(mdcTag)); + if (contextData.containsKey(contextTag)) { + event.setTag(contextTag, contextData.get(contextTag)); // remove from all tags applied to logging event - contextData.remove(mdcTag); + contextData.remove(contextTag); } } } diff --git a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt index 01c781f3af6..0a1ad7b1090 100644 --- a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt +++ b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt @@ -43,13 +43,13 @@ class SentryAppenderTest { whenever(transportFactory.create(any(), any())).thenReturn(transport) } - fun getSut(transportFactory: ITransportFactory? = null, minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, debug: Boolean? = null, mdcTags: List? = null): ExtendedLogger { + fun getSut(transportFactory: ITransportFactory? = null, minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, debug: Boolean? = null, contextTags: List? = null): ExtendedLogger { if (transportFactory != null) { this.transportFactory = transportFactory } loggerContext.start() val config: Configuration = loggerContext.configuration - val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, HubAdapter.getInstance(), mdcTags?.toTypedArray()) + val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, HubAdapter.getInstance(), contextTags?.toTypedArray()) config.addAppender(appender) val ref = AppenderRef.createAppenderRef("sentry", null, null) @@ -243,15 +243,15 @@ class SentryAppenderTest { @Test fun `sets tags from ThreadContext as Sentry tags`() { - val logger = fixture.getSut(minimumEventLevel = Level.WARN, mdcTags = listOf("mdcTag1")) + val logger = fixture.getSut(minimumEventLevel = Level.WARN, contextTags = listOf("contextTag1")) ThreadContext.put("key", "value") - ThreadContext.put("mdcTag1", "mdcTag1Value") + ThreadContext.put("contextTag1", "contextTag1Value") logger.warn("testing MDC tags") verify(fixture.transport).send( checkEvent { event -> assertEquals(mapOf("key" to "value"), event.contexts["Context Data"]) - assertEquals(mapOf("mdcTag1" to "mdcTag1Value"), event.tags) + assertEquals(mapOf("contextTag1" to "contextTag1Value"), event.tags) }, anyOrNull() ) diff --git a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java index 627a469ff5a..b6cf879620e 100644 --- a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java +++ b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java @@ -112,13 +112,13 @@ protected void append(@NotNull ILoggingEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getMDCPropertyMap(), entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - if (!options.getMdcTags().isEmpty()) { - for (final String mdcTag : options.getMdcTags()) { + if (!options.getContextTags().isEmpty()) { + for (final String contextTag : options.getContextTags()) { // if mdc tag is listed in SentryOptions, apply as event tag - if (mdcProperties.containsKey(mdcTag)) { - event.setTag(mdcTag, mdcProperties.get(mdcTag)); + if (mdcProperties.containsKey(contextTag)) { + event.setTag(contextTag, mdcProperties.get(contextTag)); // remove from all tags applied to logging event - mdcProperties.remove(mdcTag); + mdcProperties.remove(contextTag); } } } diff --git a/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt b/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt index 29424c19e71..11c2afba989 100644 --- a/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt +++ b/sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt @@ -31,7 +31,7 @@ import kotlin.test.assertNull import kotlin.test.assertTrue class SentryAppenderTest { - private class Fixture(dsn: String? = "http://key@localhost/proj", minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, mdcTags: List? = null) { + private class Fixture(dsn: String? = "http://key@localhost/proj", minimumBreadcrumbLevel: Level? = null, minimumEventLevel: Level? = null, contextTags: List? = null) { val logger: Logger = LoggerFactory.getLogger(SentryAppenderTest::class.java) val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext val transportFactory = mock() @@ -43,7 +43,7 @@ class SentryAppenderTest { val appender = SentryAppender() val options = SentryOptions() options.dsn = dsn - mdcTags?.forEach { options.addMdcTag(it) } + contextTags?.forEach { options.addContextTag(it) } appender.setOptions(options) appender.setMinimumBreadcrumbLevel(minimumBreadcrumbLevel) appender.setMinimumEventLevel(minimumEventLevel) @@ -220,15 +220,15 @@ class SentryAppenderTest { @Test fun `sets tags as sentry tags from MDC`() { - fixture = Fixture(minimumEventLevel = Level.WARN, mdcTags = listOf("mdcTag1")) + fixture = Fixture(minimumEventLevel = Level.WARN, contextTags = listOf("contextTag1")) MDC.put("key", "value") - MDC.put("mdcTag1", "mdcTag1Value") + MDC.put("contextTag1", "contextTag1Value") fixture.logger.warn("testing MDC tags") verify(fixture.transport).send( checkEvent { event -> assertEquals(mapOf("key" to "value"), event.contexts["MDC"]) - assertEquals(mapOf("mdcTag1" to "mdcTag1Value"), event.tags) + assertEquals(mapOf("contextTag1" to "contextTag1Value"), event.tags) }, anyOrNull() ) diff --git a/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties b/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties index 33aa8a09517..390771a4403 100644 --- a/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties +++ b/sentry-samples/sentry-samples-jul/src/main/resources/sentry.properties @@ -3,4 +3,4 @@ dsn=https://502f25099c204a2fbf4cb16edc5975d1@o447951.ingest.sentry.io/5428563 debug=true environment=staging in-app-includes=io.sentry.samples -mdc-tags=userId,requestId +context-tags=userId,requestId diff --git a/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml b/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml index eb16e9a2a8b..4df7b2beb0e 100644 --- a/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml +++ b/sentry-samples/sentry-samples-log4j2/src/main/resources/log4j2.xml @@ -12,7 +12,7 @@ minimumBreadcrumbLevel="DEBUG" minimumEventLevel="WARN" debug="true" - mdcTags="userId,requestId" + contextTags="userId,requestId" /> diff --git a/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml b/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml index 2e7b9f82c7c..02bee862a3e 100644 --- a/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml +++ b/sentry-samples/sentry-samples-logback/src/main/resources/logback.xml @@ -11,8 +11,8 @@ true https://502f25099c204a2fbf4cb16edc5975d1@o447951.ingest.sentry.io/5428563 - userId - requestId + userId + requestId diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 6e9d8cd0648..af3fc009bf1 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -124,12 +124,13 @@ public abstract interface class io/sentry/EventProcessor { public final class io/sentry/ExternalOptions { public fun ()V + public fun addContextTag (Ljava/lang/String;)V public fun addIgnoredExceptionForType (Ljava/lang/Class;)V public fun addInAppExclude (Ljava/lang/String;)V public fun addInAppInclude (Ljava/lang/String;)V - public fun addMdcTag (Ljava/lang/String;)V public fun addTracingOrigin (Ljava/lang/String;)V public static fun from (Lio/sentry/config/PropertiesProvider;Lio/sentry/ILogger;)Lio/sentry/ExternalOptions; + public fun getContextTags ()Ljava/util/List; public fun getDebug ()Ljava/lang/Boolean; public fun getDist ()Ljava/lang/String; public fun getDsn ()Ljava/lang/String; @@ -140,7 +141,6 @@ public final class io/sentry/ExternalOptions { public fun getInAppExcludes ()Ljava/util/List; public fun getInAppIncludes ()Ljava/util/List; public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize; - public fun getMdcTags ()Ljava/util/List; public fun getPrintUncaughtStackTrace ()Ljava/lang/Boolean; public fun getProguardUuid ()Ljava/lang/String; public fun getProxy ()Lio/sentry/SentryOptions$Proxy; @@ -995,18 +995,19 @@ public final class io/sentry/SentryLevel : java/lang/Enum, io/sentry/JsonSeriali public class io/sentry/SentryOptions { public fun ()V + public fun addContextTag (Ljava/lang/String;)V public fun addEventProcessor (Lio/sentry/EventProcessor;)V public fun addIgnoredExceptionForType (Ljava/lang/Class;)V public fun addInAppExclude (Ljava/lang/String;)V public fun addInAppInclude (Ljava/lang/String;)V public fun addIntegration (Lio/sentry/Integration;)V - public fun addMdcTag (Ljava/lang/String;)V public fun addScopeObserver (Lio/sentry/IScopeObserver;)V public fun addTracingOrigin (Ljava/lang/String;)V public fun getBeforeBreadcrumb ()Lio/sentry/SentryOptions$BeforeBreadcrumbCallback; public fun getBeforeSend ()Lio/sentry/SentryOptions$BeforeSendCallback; public fun getCacheDirPath ()Ljava/lang/String; public fun getConnectionTimeoutMillis ()I + public fun getContextTags ()Ljava/util/List; public fun getDiagnosticLevel ()Lio/sentry/SentryLevel; public fun getDist ()Ljava/lang/String; public fun getDistinctId ()Ljava/lang/String; @@ -1029,7 +1030,6 @@ public class io/sentry/SentryOptions { public fun getMaxQueueSize ()I public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize; public fun getMaxSpans ()I - public fun getMdcTags ()Ljava/util/List; public fun getOutboxPath ()Ljava/lang/String; public fun getPrintUncaughtStackTrace ()Ljava/lang/Boolean; public fun getProguardUuid ()Ljava/lang/String; diff --git a/sentry/src/main/java/io/sentry/ExternalOptions.java b/sentry/src/main/java/io/sentry/ExternalOptions.java index 3a8a62449a3..8f10ca8c402 100644 --- a/sentry/src/main/java/io/sentry/ExternalOptions.java +++ b/sentry/src/main/java/io/sentry/ExternalOptions.java @@ -32,7 +32,7 @@ public final class ExternalOptions { private final @NotNull List inAppExcludes = new CopyOnWriteArrayList<>(); private final @NotNull List inAppIncludes = new CopyOnWriteArrayList<>(); private final @NotNull List tracingOrigins = new CopyOnWriteArrayList<>(); - private final @NotNull List mdcTags = new CopyOnWriteArrayList<>(); + private final @NotNull List contextTags = new CopyOnWriteArrayList<>(); private @Nullable String proguardUuid; private final @NotNull Set> ignoredExceptionsForType = new CopyOnWriteArraySet<>(); @@ -82,8 +82,8 @@ public final class ExternalOptions { for (final String tracingOrigin : propertiesProvider.getList("tracing-origins")) { options.addTracingOrigin(tracingOrigin); } - for (final String mdcTag : propertiesProvider.getList("mdc-tags")) { - options.addMdcTag(mdcTag); + for (final String contextTag : propertiesProvider.getList("context-tags")) { + options.addContextTag(contextTag); } options.setProguardUuid(propertiesProvider.getProperty("proguard-uuid")); @@ -216,8 +216,8 @@ public void setProxy(final @Nullable SentryOptions.Proxy proxy) { return inAppIncludes; } - public @NotNull List getMdcTags() { - return mdcTags; + public @NotNull List getContextTags() { + return contextTags; } public @Nullable String getProguardUuid() { @@ -244,8 +244,8 @@ public void addTracingOrigin(final @NotNull String tracingOrigin) { this.tracingOrigins.add(tracingOrigin); } - public void addMdcTag(final @NotNull String mdcTag) { - this.mdcTags.add(mdcTag); + public void addContextTag(final @NotNull String contextTag) { + this.contextTags.add(contextTag); } public void addIgnoredExceptionForType(final @NotNull Class exceptionType) { diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index c8e31fdc398..bae1ea20377 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -297,8 +297,11 @@ public class SentryOptions { /** Proguard UUID. */ private @Nullable String proguardUuid; - /** Contains a list of MDC tags names that are meant to be applied as Sentry tags to events. */ - private final @NotNull List mdcTags = new CopyOnWriteArrayList<>(); + /** + * Contains a list of context tags names (for example from MDC) that are meant to be applied as + * Sentry tags to events. + */ + private final @NotNull List contextTags = new CopyOnWriteArrayList<>(); /** * Adds an event processor @@ -1446,21 +1449,21 @@ public void setProguardUuid(final @Nullable String proguardUuid) { } /** - * Returns MDC tags names applied to Sentry events as Sentry tags. + * Returns Context tags names applied to Sentry events as Sentry tags. * - * @return mdc tags + * @return context tags */ - public @NotNull List getMdcTags() { - return mdcTags; + public @NotNull List getContextTags() { + return contextTags; } /** - * Adds MDC tag name that is applied to Sentry events as Sentry tag. + * Adds context tag name that is applied to Sentry events as Sentry tag. * - * @param mdcTag - the MDC tag + * @param contextTag - the context tag */ - public void addMdcTag(final @NotNull String mdcTag) { - this.mdcTags.add(mdcTag); + public void addContextTag(final @NotNull String contextTag) { + this.contextTags.add(contextTag); } /** The BeforeSend callback */ @@ -1610,9 +1613,9 @@ void merge(final @NotNull ExternalOptions options) { for (final String tracingOrigin : tracingOrigins) { addTracingOrigin(tracingOrigin); } - final List mdcTags = new ArrayList<>(options.getMdcTags()); - for (final String mdcTag : mdcTags) { - addMdcTag(mdcTag); + final List contextTags = new ArrayList<>(options.getContextTags()); + for (final String contextTag : contextTags) { + addContextTag(contextTag); } if (options.getProguardUuid() != null) { setProguardUuid(options.getProguardUuid()); diff --git a/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt b/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt index 13d2b8120d9..0e7ea3d9316 100644 --- a/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt +++ b/sentry/src/test/java/io/sentry/ExternalOptionsTest.kt @@ -137,9 +137,9 @@ class ExternalOptionsTest { } @Test - fun `creates options with mdc tags using external properties`() { - withPropertiesFile("mdc-tags=userId,xxx") { - assertEquals(listOf("userId", "xxx"), it.mdcTags) + fun `creates options with context tags using external properties`() { + withPropertiesFile("context-tags=userId,xxx") { + assertEquals(listOf("userId", "xxx"), it.contextTags) } } diff --git a/sentry/src/test/java/io/sentry/SentryOptionsTest.kt b/sentry/src/test/java/io/sentry/SentryOptionsTest.kt index f8872e81eb8..d583276331b 100644 --- a/sentry/src/test/java/io/sentry/SentryOptionsTest.kt +++ b/sentry/src/test/java/io/sentry/SentryOptionsTest.kt @@ -199,8 +199,8 @@ class SentryOptionsTest { externalOptions.addInAppExclude("io.off") externalOptions.addTracingOrigin("localhost") externalOptions.addTracingOrigin("api.foo.com") - externalOptions.addMdcTag("userId") - externalOptions.addMdcTag("requestId") + externalOptions.addContextTag("userId") + externalOptions.addContextTag("requestId") val options = SentryOptions() options.merge(externalOptions) @@ -219,7 +219,7 @@ class SentryOptionsTest { assertEquals(listOf("com.app"), options.inAppIncludes) assertEquals(listOf("io.off"), options.inAppExcludes) assertEquals(listOf("localhost", "api.foo.com"), options.tracingOrigins) - assertEquals(listOf("userId", "requestId"), options.mdcTags) + assertEquals(listOf("userId", "requestId"), options.contextTags) } @Test