From 602d1cb0aa2c65d5f82b071f100d73aae610b38e Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Mon, 16 Dec 2024 08:37:21 +0100 Subject: [PATCH 1/9] add FilterString, use FilterString when adding ignoredSpanOrigins --- .../main/java/io/sentry/SentryOptions.java | 17 +++-- .../main/java/io/sentry/util/SpanUtils.java | 64 +++++++++++++------ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index 2ea882b3dc2..da60ed3ca20 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -24,6 +24,7 @@ import io.sentry.util.LoadClass; import io.sentry.util.Platform; import io.sentry.util.SampleRateUtils; +import io.sentry.util.SpanUtils; import io.sentry.util.StringUtils; import io.sentry.util.thread.IThreadChecker; import io.sentry.util.thread.NoOpThreadChecker; @@ -469,7 +470,7 @@ public class SentryOptions { @ApiStatus.Experimental private @Nullable List ignoredCheckIns = null; /** Contains a list of span origins for which spans / transactions should not be created. */ - @ApiStatus.Experimental private @Nullable List ignoredSpanOrigins = null; + @ApiStatus.Experimental private @Nullable List ignoredSpanOrigins = null; private @Nullable List ignoredTransactions = null; @@ -2189,19 +2190,27 @@ public void setIgnoredCheckIns(final @Nullable List ignoredCheckIns) { } @ApiStatus.Experimental - public @Nullable List getIgnoredSpanOrigins() { + public @Nullable List getIgnoredSpanOrigins() { return ignoredSpanOrigins; } + @ApiStatus.Experimental + public void addIgnoredSpanOrigin(String ignoredSpanOrigin) { + if (ignoredSpanOrigins == null) { + ignoredSpanOrigins = new ArrayList<>(); + } + ignoredSpanOrigins.add(new SpanUtils.FilterString(ignoredSpanOrigin)); + } + @ApiStatus.Experimental public void setIgnoredSpanOrigins(final @Nullable List ignoredSpanOrigins) { if (ignoredSpanOrigins == null) { this.ignoredSpanOrigins = null; } else { - @NotNull final List filtered = new ArrayList<>(); + @NotNull final List filtered = new ArrayList<>(); for (String origin : ignoredSpanOrigins) { if (origin != null && !origin.isEmpty()) { - filtered.add(origin); + filtered.add(new SpanUtils.FilterString(origin)); } } diff --git a/sentry/src/main/java/io/sentry/util/SpanUtils.java b/sentry/src/main/java/io/sentry/util/SpanUtils.java index a657186744b..4b4ad38f244 100644 --- a/sentry/src/main/java/io/sentry/util/SpanUtils.java +++ b/sentry/src/main/java/io/sentry/util/SpanUtils.java @@ -2,36 +2,56 @@ import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; + import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public final class SpanUtils { + public static class FilterString { + private final String filterString; + private final Pattern pattern; + + public FilterString(String filterString) { + this.filterString = filterString; + this.pattern = Pattern.compile(filterString); + } + + public String getFilterString() { + return filterString; + } + + public boolean matches(String input) { + return pattern.matcher(input).matches(); + } + } + /** * A list of span origins that are ignored by default when using OpenTelemetry. * * @return a list of span origins to be ignored */ - public static @NotNull List ignoredSpanOriginsForOpenTelemetry(final boolean isAgent) { - final @NotNull List origins = new ArrayList<>(); + public static @NotNull List ignoredSpanOriginsForOpenTelemetry(final boolean isAgent) { + final @NotNull List origins = new ArrayList<>(); - origins.add("auto.http.spring_jakarta.webmvc"); - origins.add("auto.http.spring.webmvc"); - origins.add("auto.spring_jakarta.webflux"); - origins.add("auto.spring.webflux"); - origins.add("auto.db.jdbc"); - origins.add("auto.http.spring_jakarta.webclient"); - origins.add("auto.http.spring.webclient"); - origins.add("auto.http.spring_jakarta.restclient"); - origins.add("auto.http.spring.restclient"); - origins.add("auto.http.spring_jakarta.resttemplate"); - origins.add("auto.http.spring.resttemplate"); - origins.add("auto.http.openfeign"); + origins.add(new FilterString("auto.http.spring_jakarta.webmvc")); + origins.add(new FilterString("auto.http.spring.webmvc")); + origins.add(new FilterString("auto.spring_jakarta.webflux")); + origins.add(new FilterString("auto.spring.webflux")); + origins.add(new FilterString("auto.db.jdbc")); + origins.add(new FilterString("auto.http.spring_jakarta.webclient")); + origins.add(new FilterString("auto.http.spring.webclient")); + origins.add(new FilterString("auto.http.spring_jakarta.restclient")); + origins.add(new FilterString("auto.http.spring.restclient")); + origins.add(new FilterString("auto.http.spring_jakarta.resttemplate")); + origins.add(new FilterString("auto.http.spring.resttemplate")); + origins.add(new FilterString("auto.http.openfeign")); if (isAgent) { - origins.add("auto.graphql.graphql"); - origins.add("auto.graphql.graphql22"); + origins.add(new FilterString("auto.graphql.graphql")); + origins.add(new FilterString("auto.graphql.graphql22")); } return origins; @@ -40,18 +60,20 @@ public final class SpanUtils { /** Checks if a span origin has been ignored. */ @ApiStatus.Internal public static boolean isIgnored( - final @Nullable List ignoredOrigins, final @Nullable String origin) { + final @Nullable List ignoredOrigins, final @Nullable String origin) { if (origin == null || ignoredOrigins == null || ignoredOrigins.isEmpty()) { return false; } - - for (final String ignoredOrigin : ignoredOrigins) { - if (ignoredOrigin.equalsIgnoreCase(origin)) { + + for (final FilterString ignoredOrigin : ignoredOrigins) { + if (ignoredOrigin.getFilterString().equalsIgnoreCase(origin)) { return true; } + } + for (final FilterString ignoredOrigin : ignoredOrigins) { try { - if (origin.matches(ignoredOrigin)) { + if (ignoredOrigin.matches(origin)) { return true; } } catch (Throwable t) { From 50ed02fef277a345c89c6d91be24a426c0475362 Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Mon, 16 Dec 2024 12:40:16 +0100 Subject: [PATCH 2/9] add test, setIgnoredSpanOrigins as List of String --- .../src/main/java/io/sentry/FilterString.java | 23 ++++++++ .../main/java/io/sentry/SentryOptions.java | 10 ++-- .../main/java/io/sentry/util/SpanUtils.java | 54 +++++++------------ sentry/src/test/java/io/sentry/ScopesTest.kt | 4 +- .../test/java/io/sentry/SentryTracerTest.kt | 2 +- .../test/java/io/sentry/util/SpanUtilsTest.kt | 43 +++++++++++++++ 6 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/FilterString.java create mode 100644 sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt diff --git a/sentry/src/main/java/io/sentry/FilterString.java b/sentry/src/main/java/io/sentry/FilterString.java new file mode 100644 index 00000000000..b02646fdc1b --- /dev/null +++ b/sentry/src/main/java/io/sentry/FilterString.java @@ -0,0 +1,23 @@ +package io.sentry; + +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +final public class FilterString { + private final @NotNull String filterString; + private final @NotNull Pattern pattern; + + public FilterString(@NotNull String filterString) { + this.filterString = filterString; + this.pattern = Pattern.compile(filterString); + } + + public @NotNull String getFilterString() { + return filterString; + } + + public boolean matches(String input) { + return pattern.matcher(input).matches(); + } +} diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index da60ed3ca20..e8305b13aba 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -470,7 +470,7 @@ public class SentryOptions { @ApiStatus.Experimental private @Nullable List ignoredCheckIns = null; /** Contains a list of span origins for which spans / transactions should not be created. */ - @ApiStatus.Experimental private @Nullable List ignoredSpanOrigins = null; + @ApiStatus.Experimental private @Nullable List ignoredSpanOrigins = null; private @Nullable List ignoredTransactions = null; @@ -2190,7 +2190,7 @@ public void setIgnoredCheckIns(final @Nullable List ignoredCheckIns) { } @ApiStatus.Experimental - public @Nullable List getIgnoredSpanOrigins() { + public @Nullable List getIgnoredSpanOrigins() { return ignoredSpanOrigins; } @@ -2199,7 +2199,7 @@ public void addIgnoredSpanOrigin(String ignoredSpanOrigin) { if (ignoredSpanOrigins == null) { ignoredSpanOrigins = new ArrayList<>(); } - ignoredSpanOrigins.add(new SpanUtils.FilterString(ignoredSpanOrigin)); + ignoredSpanOrigins.add(new FilterString(ignoredSpanOrigin)); } @ApiStatus.Experimental @@ -2207,10 +2207,10 @@ public void setIgnoredSpanOrigins(final @Nullable List ignoredSpanOrigin if (ignoredSpanOrigins == null) { this.ignoredSpanOrigins = null; } else { - @NotNull final List filtered = new ArrayList<>(); + @NotNull final List filtered = new ArrayList<>(); for (String origin : ignoredSpanOrigins) { if (origin != null && !origin.isEmpty()) { - filtered.add(new SpanUtils.FilterString(origin)); + filtered.add(new FilterString(origin)); } } diff --git a/sentry/src/main/java/io/sentry/util/SpanUtils.java b/sentry/src/main/java/io/sentry/util/SpanUtils.java index 4b4ad38f244..504192cf116 100644 --- a/sentry/src/main/java/io/sentry/util/SpanUtils.java +++ b/sentry/src/main/java/io/sentry/util/SpanUtils.java @@ -2,56 +2,38 @@ import java.util.ArrayList; import java.util.List; -import java.util.regex.Pattern; +import io.sentry.FilterString; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public final class SpanUtils { - public static class FilterString { - private final String filterString; - private final Pattern pattern; - - public FilterString(String filterString) { - this.filterString = filterString; - this.pattern = Pattern.compile(filterString); - } - - public String getFilterString() { - return filterString; - } - - public boolean matches(String input) { - return pattern.matcher(input).matches(); - } - } - /** * A list of span origins that are ignored by default when using OpenTelemetry. * * @return a list of span origins to be ignored */ - public static @NotNull List ignoredSpanOriginsForOpenTelemetry(final boolean isAgent) { - final @NotNull List origins = new ArrayList<>(); + public static @NotNull List ignoredSpanOriginsForOpenTelemetry(final boolean isAgent) { + final @NotNull List origins = new ArrayList<>(); - origins.add(new FilterString("auto.http.spring_jakarta.webmvc")); - origins.add(new FilterString("auto.http.spring.webmvc")); - origins.add(new FilterString("auto.spring_jakarta.webflux")); - origins.add(new FilterString("auto.spring.webflux")); - origins.add(new FilterString("auto.db.jdbc")); - origins.add(new FilterString("auto.http.spring_jakarta.webclient")); - origins.add(new FilterString("auto.http.spring.webclient")); - origins.add(new FilterString("auto.http.spring_jakarta.restclient")); - origins.add(new FilterString("auto.http.spring.restclient")); - origins.add(new FilterString("auto.http.spring_jakarta.resttemplate")); - origins.add(new FilterString("auto.http.spring.resttemplate")); - origins.add(new FilterString("auto.http.openfeign")); + origins.add("auto.http.spring_jakarta.webmvc"); + origins.add("auto.http.spring.webmvc"); + origins.add("auto.spring_jakarta.webflux"); + origins.add("auto.spring.webflux"); + origins.add("auto.db.jdbc"); + origins.add("auto.http.spring_jakarta.webclient"); + origins.add("auto.http.spring.webclient"); + origins.add("auto.http.spring_jakarta.restclient"); + origins.add("auto.http.spring.restclient"); + origins.add("auto.http.spring_jakarta.resttemplate"); + origins.add("auto.http.spring.resttemplate"); + origins.add("auto.http.openfeign"); if (isAgent) { - origins.add(new FilterString("auto.graphql.graphql")); - origins.add(new FilterString("auto.graphql.graphql22")); + origins.add("auto.graphql.graphql"); + origins.add("auto.graphql.graphql22"); } return origins; @@ -64,7 +46,7 @@ public static boolean isIgnored( if (origin == null || ignoredOrigins == null || ignoredOrigins.isEmpty()) { return false; } - + for (final FilterString ignoredOrigin : ignoredOrigins) { if (ignoredOrigin.getFilterString().equalsIgnoreCase(origin)) { return true; diff --git a/sentry/src/test/java/io/sentry/ScopesTest.kt b/sentry/src/test/java/io/sentry/ScopesTest.kt index f0e9833cb88..6a5cbdf1a45 100644 --- a/sentry/src/test/java/io/sentry/ScopesTest.kt +++ b/sentry/src/test/java/io/sentry/ScopesTest.kt @@ -2084,7 +2084,7 @@ class ScopesTest { @Test fun `creating a transaction with an ignored origin noops`() { val scopes = generateScopes { - it.ignoredSpanOrigins = listOf("ignored.span.origin") + it.setIgnoredSpanOrigins(listOf("ignored.span.origin")) } val transactionContext = TransactionContext("transaction-name", "transaction-op") @@ -2101,7 +2101,7 @@ class ScopesTest { @Test fun `creating a transaction with a non ignored origin creates the transaction`() { val scopes = generateScopes { - it.ignoredSpanOrigins = listOf("ignored.span.origin") + it.setIgnoredSpanOrigins(listOf("ignored.span.origin")) } val transactionContext = TransactionContext("transaction-name", "transaction-op") diff --git a/sentry/src/test/java/io/sentry/SentryTracerTest.kt b/sentry/src/test/java/io/sentry/SentryTracerTest.kt index 3d5eca7f485..eb333187b29 100644 --- a/sentry/src/test/java/io/sentry/SentryTracerTest.kt +++ b/sentry/src/test/java/io/sentry/SentryTracerTest.kt @@ -87,7 +87,7 @@ class SentryTracerTest { val tracer = fixture.getSut({ it.setDebug(true) it.setLogger(SystemOutLogger()) - it.ignoredSpanOrigins = listOf("ignored") + it.setIgnoredSpanOrigins(listOf("ignored")) }) tracer.startChild("child1", null, SpanOptions().also { it.origin = "ignored" }) tracer.startChild("child2") diff --git a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt new file mode 100644 index 00000000000..f30389f5231 --- /dev/null +++ b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt @@ -0,0 +1,43 @@ +package io.sentry.util + +import io.sentry.FilterString +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class SpanUtilsTest { + + @Test + fun `isIgnored returns true for exact match`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) + assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) + } + + @Test + fun `isIgnored returns true for regex match`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring.*")) + assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) + } + + @Test + fun `isIgnored returns false for no match`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) + assertFalse(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring.webflux")) + } + + @Test + fun `isIgnored returns false for null origin`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) + assertFalse(SpanUtils.isIgnored(ignoredOrigins, null)) + } + + @Test + fun `isIgnored returns false for null ignoredOrigins`() { + assertFalse(SpanUtils.isIgnored(null, "auto.http.spring_jakarta.webmvc")) + } + + @Test + fun `isIgnored returns false for empty ignoredOrigins`() { + assertFalse(SpanUtils.isIgnored(emptyList(), "auto.http.spring_jakarta.webmvc")) + } +} From db965a6b83a16212bec69c01c376ab097bf4c3c9 Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Tue, 17 Dec 2024 00:24:45 +0100 Subject: [PATCH 3/9] add cache map for SpanUtils, use precompiled pattern and equals first approach for CheckInUtils and TracingUtils --- sentry/api/sentry.api | 9 +++ .../src/main/java/io/sentry/FilterString.java | 18 +++++- .../main/java/io/sentry/SentryOptions.java | 61 ++++++++++++------- .../java/io/sentry/util/CheckInUtils.java | 11 ++-- .../main/java/io/sentry/util/SpanUtils.java | 14 ++++- .../java/io/sentry/util/TracingUtils.java | 13 ++-- .../test/java/io/sentry/SentryClientTest.kt | 8 +-- .../test/java/io/sentry/SentryOptionsTest.kt | 4 +- .../java/io/sentry/util/CheckInUtilsTest.kt | 9 +-- .../test/java/io/sentry/util/SpanUtilsTest.kt | 6 ++ 10 files changed, 107 insertions(+), 46 deletions(-) diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 7cf213a03cf..68f8b3a17b2 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -509,6 +509,12 @@ public final class io/sentry/ExternalOptions { public fun setTracesSampleRate (Ljava/lang/Double;)V } +public final class io/sentry/FilterString { + public fun (Ljava/lang/String;)V + public fun getFilterString ()Ljava/lang/String; + public fun matches (Ljava/lang/String;)Z +} + public final class io/sentry/FullyDisplayedReporter { public static fun getInstance ()Lio/sentry/FullyDisplayedReporter; public fun registerFullyDrawnListener (Lio/sentry/FullyDisplayedReporter$FullyDisplayedReporterListener;)V @@ -2788,7 +2794,10 @@ public class io/sentry/SentryOptions { public fun addBundleId (Ljava/lang/String;)V public fun addContextTag (Ljava/lang/String;)V public fun addEventProcessor (Lio/sentry/EventProcessor;)V + public fun addIgnoredCheckIn (Ljava/lang/String;)V public fun addIgnoredExceptionForType (Ljava/lang/Class;)V + public fun addIgnoredSpanOrigin (Ljava/lang/String;)V + public fun addIgnoredTransaction (Ljava/lang/String;)V public fun addInAppExclude (Ljava/lang/String;)V public fun addInAppInclude (Ljava/lang/String;)V public fun addIntegration (Lio/sentry/Integration;)V diff --git a/sentry/src/main/java/io/sentry/FilterString.java b/sentry/src/main/java/io/sentry/FilterString.java index b02646fdc1b..0e2813773eb 100644 --- a/sentry/src/main/java/io/sentry/FilterString.java +++ b/sentry/src/main/java/io/sentry/FilterString.java @@ -1,10 +1,10 @@ package io.sentry; -import org.jetbrains.annotations.NotNull; - +import java.util.Objects; import java.util.regex.Pattern; +import org.jetbrains.annotations.NotNull; -final public class FilterString { +public final class FilterString { private final @NotNull String filterString; private final @NotNull Pattern pattern; @@ -20,4 +20,16 @@ public FilterString(@NotNull String filterString) { public boolean matches(String input) { return pattern.matcher(input).matches(); } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + FilterString that = (FilterString) o; + return Objects.equals(filterString, that.filterString); + } + + @Override + public int hashCode() { + return Objects.hashCode(filterString); + } } diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index e8305b13aba..a449db63d11 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -24,7 +24,6 @@ import io.sentry.util.LoadClass; import io.sentry.util.Platform; import io.sentry.util.SampleRateUtils; -import io.sentry.util.SpanUtils; import io.sentry.util.StringUtils; import io.sentry.util.thread.IThreadChecker; import io.sentry.util.thread.NoOpThreadChecker; @@ -467,12 +466,12 @@ public class SentryOptions { private boolean enableScopePersistence = true; /** Contains a list of monitor slugs for which check-ins should not be sent. */ - @ApiStatus.Experimental private @Nullable List ignoredCheckIns = null; + @ApiStatus.Experimental private @Nullable List ignoredCheckIns = null; /** Contains a list of span origins for which spans / transactions should not be created. */ @ApiStatus.Experimental private @Nullable List ignoredSpanOrigins = null; - private @Nullable List ignoredTransactions = null; + private @Nullable List ignoredTransactions = null; @ApiStatus.Experimental private @NotNull IBackpressureMonitor backpressureMonitor = NoOpBackpressureMonitor.getInstance(); @@ -2173,22 +2172,6 @@ public void setSendModules(boolean sendModules) { this.sendModules = sendModules; } - @ApiStatus.Experimental - public void setIgnoredCheckIns(final @Nullable List ignoredCheckIns) { - if (ignoredCheckIns == null) { - this.ignoredCheckIns = null; - } else { - @NotNull final List filteredIgnoredCheckIns = new ArrayList<>(); - for (String slug : ignoredCheckIns) { - if (!slug.isEmpty()) { - filteredIgnoredCheckIns.add(slug); - } - } - - this.ignoredCheckIns = filteredIgnoredCheckIns; - } - } - @ApiStatus.Experimental public @Nullable List getIgnoredSpanOrigins() { return ignoredSpanOrigins; @@ -2219,23 +2202,55 @@ public void setIgnoredSpanOrigins(final @Nullable List ignoredSpanOrigin } @ApiStatus.Experimental - public @Nullable List getIgnoredCheckIns() { + public @Nullable List getIgnoredCheckIns() { return ignoredCheckIns; } - public @Nullable List getIgnoredTransactions() { + @ApiStatus.Experimental + public void addIgnoredCheckIn(String ignoredCheckIn) { + if (ignoredCheckIns == null) { + ignoredCheckIns = new ArrayList<>(); + } + ignoredCheckIns.add(new FilterString(ignoredCheckIn)); + } + + @ApiStatus.Experimental + public void setIgnoredCheckIns(final @Nullable List ignoredCheckIns) { + if (ignoredCheckIns == null) { + this.ignoredCheckIns = null; + } else { + @NotNull final List filteredIgnoredCheckIns = new ArrayList<>(); + for (String slug : ignoredCheckIns) { + if (!slug.isEmpty()) { + filteredIgnoredCheckIns.add(new FilterString(slug)); + } + } + + this.ignoredCheckIns = filteredIgnoredCheckIns; + } + } + + public @Nullable List getIgnoredTransactions() { return ignoredTransactions; } + @ApiStatus.Experimental + public void addIgnoredTransaction(String ignoredTransaction) { + if (ignoredTransactions == null) { + ignoredTransactions = new ArrayList<>(); + } + ignoredTransactions.add(new FilterString(ignoredTransaction)); + } + @ApiStatus.Experimental public void setIgnoredTransactions(final @Nullable List ignoredTransactions) { if (ignoredTransactions == null) { this.ignoredTransactions = null; } else { - @NotNull final List filtered = new ArrayList<>(); + @NotNull final List filtered = new ArrayList<>(); for (String transactionName : ignoredTransactions) { if (transactionName != null && !transactionName.isEmpty()) { - filtered.add(transactionName); + filtered.add(new FilterString(transactionName)); } } diff --git a/sentry/src/main/java/io/sentry/util/CheckInUtils.java b/sentry/src/main/java/io/sentry/util/CheckInUtils.java index 49846ac1392..7b44fffbc35 100644 --- a/sentry/src/main/java/io/sentry/util/CheckInUtils.java +++ b/sentry/src/main/java/io/sentry/util/CheckInUtils.java @@ -3,6 +3,7 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; +import io.sentry.FilterString; import io.sentry.IScopes; import io.sentry.ISentryLifecycleToken; import io.sentry.MonitorConfig; @@ -116,18 +117,20 @@ public static U withCheckIn( /** Checks if a check-in for a monitor (CRON) has been ignored. */ @ApiStatus.Internal public static boolean isIgnored( - final @Nullable List ignoredSlugs, final @NotNull String slug) { + final @Nullable List ignoredSlugs, final @NotNull String slug) { if (ignoredSlugs == null || ignoredSlugs.isEmpty()) { return false; } - for (final String ignoredSlug : ignoredSlugs) { - if (ignoredSlug.equalsIgnoreCase(slug)) { + for (final FilterString ignoredSlug : ignoredSlugs) { + if (ignoredSlug.getFilterString().equalsIgnoreCase(slug)) { return true; } + } + for (final FilterString ignoredSlug : ignoredSlugs) { try { - if (slug.matches(ignoredSlug)) { + if (ignoredSlug.matches(slug)) { return true; } } catch (Throwable t) { diff --git a/sentry/src/main/java/io/sentry/util/SpanUtils.java b/sentry/src/main/java/io/sentry/util/SpanUtils.java index 504192cf116..1e2c910a18b 100644 --- a/sentry/src/main/java/io/sentry/util/SpanUtils.java +++ b/sentry/src/main/java/io/sentry/util/SpanUtils.java @@ -1,9 +1,10 @@ package io.sentry.util; +import io.sentry.FilterString; import java.util.ArrayList; import java.util.List; - -import io.sentry.FilterString; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +40,8 @@ public final class SpanUtils { return origins; } + private static final Map ignoredSpanDecisionsCache = new ConcurrentHashMap<>(); + /** Checks if a span origin has been ignored. */ @ApiStatus.Internal public static boolean isIgnored( @@ -47,8 +50,13 @@ public static boolean isIgnored( return false; } + if (ignoredSpanDecisionsCache.containsKey(origin)) { + return ignoredSpanDecisionsCache.get(origin); + } + for (final FilterString ignoredOrigin : ignoredOrigins) { if (ignoredOrigin.getFilterString().equalsIgnoreCase(origin)) { + ignoredSpanDecisionsCache.put(origin, true); return true; } } @@ -56,6 +64,7 @@ public static boolean isIgnored( for (final FilterString ignoredOrigin : ignoredOrigins) { try { if (ignoredOrigin.matches(origin)) { + ignoredSpanDecisionsCache.put(origin, true); return true; } } catch (Throwable t) { @@ -63,6 +72,7 @@ public static boolean isIgnored( } } + ignoredSpanDecisionsCache.put(origin, false); return false; } } diff --git a/sentry/src/main/java/io/sentry/util/TracingUtils.java b/sentry/src/main/java/io/sentry/util/TracingUtils.java index 2f0cc4a98ec..16655be634c 100644 --- a/sentry/src/main/java/io/sentry/util/TracingUtils.java +++ b/sentry/src/main/java/io/sentry/util/TracingUtils.java @@ -2,6 +2,7 @@ import io.sentry.Baggage; import io.sentry.BaggageHeader; +import io.sentry.FilterString; import io.sentry.IScope; import io.sentry.IScopes; import io.sentry.ISpan; @@ -123,7 +124,8 @@ public TracingHeaders( /** Checks if a transaction is to be ignored. */ @ApiStatus.Internal public static boolean isIgnored( - final @Nullable List ignoredTransactions, final @Nullable String transactionName) { + final @Nullable List ignoredTransactions, + final @Nullable String transactionName) { if (transactionName == null) { return false; } @@ -131,13 +133,16 @@ public static boolean isIgnored( return false; } - for (final String ignoredSlug : ignoredTransactions) { - if (ignoredSlug.equalsIgnoreCase(transactionName)) { + for (final FilterString ignoredTransaction : ignoredTransactions) { + if (ignoredTransaction.getFilterString().equalsIgnoreCase(transactionName)) { return true; } + } + + for (final FilterString ignoredTransaction : ignoredTransactions) { try { - if (transactionName.matches(ignoredSlug)) { + if (ignoredTransaction.matches(transactionName)) { return true; } } catch (Throwable t) { diff --git a/sentry/src/test/java/io/sentry/SentryClientTest.kt b/sentry/src/test/java/io/sentry/SentryClientTest.kt index e1b13a87734..da57f5376e6 100644 --- a/sentry/src/test/java/io/sentry/SentryClientTest.kt +++ b/sentry/src/test/java/io/sentry/SentryClientTest.kt @@ -587,7 +587,7 @@ class SentryClientTest { @Test fun `when captureCheckIn, envelope is sent if ignored slug does not match`() { val sut = fixture.getSut { options -> - options.ignoredCheckIns = listOf("non_matching_slug") + options.setIgnoredCheckIns(listOf("non_matching_slug")) } sut.captureCheckIn(checkIn, null, null) @@ -611,7 +611,7 @@ class SentryClientTest { @Test fun `when captureCheckIn, envelope is not sent if slug is ignored`() { val sut = fixture.getSut { options -> - options.ignoredCheckIns = listOf("some_slug") + options.setIgnoredCheckIns(listOf("some_slug")) } sut.captureCheckIn(checkIn, null, null) @@ -821,7 +821,7 @@ class SentryClientTest { @Test fun `transaction dropped by ignoredTransactions is recorded`() { - fixture.sentryOptions.ignoredTransactions = listOf("a-transaction") + fixture.sentryOptions.setIgnoredTransactions(listOf("a-transaction")) val transaction = SentryTransaction(fixture.sentryTracer) @@ -843,7 +843,7 @@ class SentryClientTest { @Test fun `transaction dropped by ignoredTransactions with regex is recorded`() { - fixture.sentryOptions.ignoredTransactions = listOf("a.*action") + fixture.sentryOptions.setIgnoredTransactions(listOf("a.*action")) val transaction = SentryTransaction(fixture.sentryTracer) diff --git a/sentry/src/test/java/io/sentry/SentryOptionsTest.kt b/sentry/src/test/java/io/sentry/SentryOptionsTest.kt index 3db264c7c6b..46482a10833 100644 --- a/sentry/src/test/java/io/sentry/SentryOptionsTest.kt +++ b/sentry/src/test/java/io/sentry/SentryOptionsTest.kt @@ -368,8 +368,8 @@ class SentryOptionsTest { assertFalse(options.isEnabled) assertFalse(options.isEnablePrettySerializationOutput) assertFalse(options.isSendModules) - assertEquals(listOf("slug1", "slug-B"), options.ignoredCheckIns) - assertEquals(listOf("transactionName1", "transaction-name-B"), options.ignoredTransactions) + assertEquals(listOf(FilterString("slug1"), FilterString("slug-B")), options.ignoredCheckIns) + assertEquals(listOf(FilterString("transactionName1"), FilterString("transaction-name-B")), options.ignoredTransactions) assertFalse(options.isEnableBackpressureHandling) assertTrue(options.isForceInit) assertNotNull(options.cron) diff --git a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt index 53c5dd7de6e..cc15da93c31 100644 --- a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt @@ -1,6 +1,7 @@ package io.sentry.util import io.sentry.CheckInStatus +import io.sentry.FilterString import io.sentry.IScopes import io.sentry.ISentryLifecycleToken import io.sentry.MonitorConfig @@ -26,12 +27,12 @@ class CheckInUtilsTest { @Test fun `ignores exact match`() { - assertTrue(CheckInUtils.isIgnored(listOf("slugA"), "slugA")) + assertTrue(CheckInUtils.isIgnored(listOf(FilterString("slugA")), "slugA")) } @Test fun `ignores regex match`() { - assertTrue(CheckInUtils.isIgnored(listOf("slug-.*"), "slug-A")) + assertTrue(CheckInUtils.isIgnored(listOf(FilterString("slug-.*")), "slug-A")) } @Test @@ -46,12 +47,12 @@ class CheckInUtilsTest { @Test fun `does not ignore if slug is not in ignored list`() { - assertFalse(CheckInUtils.isIgnored(listOf("slugB"), "slugA")) + assertFalse(CheckInUtils.isIgnored(listOf(FilterString("slugB")), "slugA")) } @Test fun `does not ignore if slug is does not match ignored list`() { - assertFalse(CheckInUtils.isIgnored(listOf("slug-.*"), "slugA")) + assertFalse(CheckInUtils.isIgnored(listOf(FilterString("slug-.*")), "slugA")) } @Test diff --git a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt index f30389f5231..6049f89f4a8 100644 --- a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt @@ -25,6 +25,12 @@ class SpanUtilsTest { assertFalse(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring.webflux")) } + @Test + fun `isIgnored returns false for no regex match`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring.*")) + assertFalse(SpanUtils.isIgnored(ignoredOrigins, "auto.http.servlet")) + } + @Test fun `isIgnored returns false for null origin`() { val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) From 31a8c9089ed2cc2ff70c1cad9374a37640c6287e Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Tue, 17 Dec 2024 11:12:00 +0100 Subject: [PATCH 4/9] adapt tests to use the new setIgnored* methods --- .../java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt | 2 +- .../java/io/sentry/apollo/SentryApolloInterceptorTest.kt | 2 +- .../java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt | 2 +- .../test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt | 2 +- .../spring/boot/jakarta/SentryAutoConfigurationTest.kt | 5 +++-- .../boot/jakarta/SentrySpanRestClientCustomizerTest.kt | 2 +- .../boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt | 2 +- .../spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt | 2 +- .../io/sentry/spring/boot/SentryAutoConfigurationTest.kt | 5 +++-- .../spring/boot/SentrySpanRestTemplateCustomizerTest.kt | 2 +- .../sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt | 2 +- .../sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt | 2 +- .../spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt | 2 +- .../io/sentry/spring/tracing/SentryTracingFilterTest.kt | 2 +- .../sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt | 2 +- sentry/api/sentry.api | 2 ++ 16 files changed, 21 insertions(+), 17 deletions(-) diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt index 30689f0b3b5..03072ae8b5a 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt @@ -210,7 +210,7 @@ class SentryApollo3InterceptorTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { - fixture.options.ignoredSpanOrigins = listOf("auto.graphql.apollo3") + fixture.options.setIgnoredSpanOrigins(listOf("auto.graphql.apollo3")) executeQuery(isSpanActive = false) val recorderRequest = fixture.server.takeRequest(mockServerRequestTimeoutMillis, TimeUnit.MILLISECONDS)!! diff --git a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt index 97d13555f0a..937aae53404 100644 --- a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt +++ b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt @@ -163,7 +163,7 @@ class SentryApolloInterceptorTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { - fixture.options.ignoredSpanOrigins = listOf("auto.graphql.apollo") + fixture.options.setIgnoredSpanOrigins(listOf("auto.graphql.apollo")) executeQuery(isSpanActive = false) val recorderRequest = fixture.server.takeRequest(mockServerRequestTimeoutMillis, TimeUnit.MILLISECONDS)!! diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt index 53b4cca93a9..f18b9673337 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt @@ -213,7 +213,7 @@ class SentryOkHttpInterceptorTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { val sut = fixture.getSut(isSpanActive = false) { options -> - options.ignoredSpanOrigins = listOf("auto.http.okhttp") + options.setIgnoredSpanOrigins(listOf("auto.http.okhttp")) } sut.newCall(getRequest()).execute() val recorderRequest = fixture.server.takeRequest(mockServerRequestTimeoutMillis, TimeUnit.MILLISECONDS)!! diff --git a/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt b/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt index e34feed7ff9..539abbf70bd 100644 --- a/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt +++ b/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt @@ -133,7 +133,7 @@ class SentryFeignClientTest { @Test fun `does not add sentry trace header when span origin is ignored`() { fixture.sentryOptions.dsn = "https://key@sentry.io/proj" - fixture.sentryOptions.ignoredSpanOrigins = listOf("auto.http.openfeign") + fixture.sentryOptions.setIgnoredSpanOrigins(listOf("auto.http.openfeign")) val sut = fixture.getSut(isSpanActive = false) sut.getOk() val recorderRequest = fixture.server.takeRequest(mockServerRequestTimeoutMillis, TimeUnit.MILLISECONDS)!! diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt index 1263c79df7f..e559502e626 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt @@ -5,6 +5,7 @@ import io.opentelemetry.api.OpenTelemetry import io.sentry.AsyncHttpTransportFactory import io.sentry.Breadcrumb import io.sentry.EventProcessor +import io.sentry.FilterString import io.sentry.Hint import io.sentry.IScopes import io.sentry.ITransportFactory @@ -213,8 +214,8 @@ class SentryAutoConfigurationTest { assertThat(options.tracePropagationTargets).containsOnly("localhost", "^(http|https)://api\\..*\$") assertThat(options.isEnabled).isEqualTo(false) assertThat(options.isSendModules).isEqualTo(false) - assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB") - assertThat(options.ignoredTransactions).containsOnly("transactionName1", "transactionNameB") + assertThat(options.ignoredCheckIns).containsOnly(FilterString("slug1"), FilterString("slugB")) + assertThat(options.ignoredTransactions).containsOnly(FilterString("transactionName1"), FilterString("transactionNameB")) assertThat(options.isEnableBackpressureHandling).isEqualTo(false) assertThat(options.isForceInit).isEqualTo(true) assertThat(options.isGlobalHubMode).isEqualTo(true) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt index 2f98188eef2..a69059482de 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt @@ -251,7 +251,7 @@ class SentrySpanRestClientCustomizerTest { @Test fun `does not add sentry-trace header if span origin is ignored`() { - fixture.sentryOptions.ignoredSpanOrigins = listOf("auto.http.spring_jakarta.restclient") + fixture.sentryOptions.setIgnoredSpanOrigins(listOf("auto.http.spring_jakarta.restclient")) val sut = fixture.getSut(isTransactionActive = false) val headers = HttpHeaders() diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt index b928fd62892..7f4a4c4fbbe 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt @@ -201,7 +201,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { - fixture.sentryOptions.ignoredSpanOrigins = listOf("auto.http.spring_jakarta.resttemplate") + fixture.sentryOptions.setIgnoredSpanOrigins(listOf("auto.http.spring_jakarta.resttemplate")) val sut = fixture.getSut(isTransactionActive = false) val headers = HttpHeaders() val requestEntity = HttpEntity(headers) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt index 55f43c8121e..71b949adcd4 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt @@ -168,7 +168,7 @@ class SentrySpanWebClientCustomizerTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { val sut = fixture.getSut(isTransactionActive = false, includeMockServerInTracingOrigins = true) { options -> - options.ignoredSpanOrigins = listOf("auto.http.spring_jakarta.webclient") + options.setIgnoredSpanOrigins(listOf("auto.http.spring_jakarta.webclient")) } sut .get() diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt index 2ec9c763fce..2512fe1f11e 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt @@ -5,6 +5,7 @@ import io.opentelemetry.api.OpenTelemetry import io.sentry.AsyncHttpTransportFactory import io.sentry.Breadcrumb import io.sentry.EventProcessor +import io.sentry.FilterString import io.sentry.Hint import io.sentry.IScopes import io.sentry.ITransportFactory @@ -212,8 +213,8 @@ class SentryAutoConfigurationTest { assertThat(options.tracePropagationTargets).containsOnly("localhost", "^(http|https)://api\\..*\$") assertThat(options.isEnabled).isEqualTo(false) assertThat(options.isSendModules).isEqualTo(false) - assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB") - assertThat(options.ignoredTransactions).containsOnly("transactionName1", "transactionNameB") + assertThat(options.ignoredCheckIns).containsOnly(FilterString("slug1"), FilterString("slugB")) + assertThat(options.ignoredTransactions).containsOnly(FilterString("transactionName1"), FilterString("transactionNameB")) assertThat(options.isEnableBackpressureHandling).isEqualTo(false) assertThat(options.isForceInit).isEqualTo(true) assertThat(options.isGlobalHubMode).isEqualTo(true) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt index e20ebed3fb9..bd2e98a99bb 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt @@ -203,7 +203,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { - fixture.sentryOptions.ignoredSpanOrigins = listOf("auto.http.spring.resttemplate") + fixture.sentryOptions.setIgnoredSpanOrigins(listOf("auto.http.spring.resttemplate")) val sut = fixture.getSut(isTransactionActive = false) val headers = HttpHeaders() val requestEntity = HttpEntity(headers) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt index f72232da2f1..f0c17333ae9 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt @@ -170,7 +170,7 @@ class SentrySpanWebClientCustomizerTest { @Test fun `does not add sentry-trace header when span origin is ignored`() { val sut = fixture.getSut(isTransactionActive = false, includeMockServerInTracingOrigins = true) { options -> - options.ignoredSpanOrigins = listOf("auto.http.spring.webclient") + options.setIgnoredSpanOrigins(listOf("auto.http.spring.webclient")) } sut .get() diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt index 864c5a57115..ff0020ddfeb 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt @@ -291,7 +291,7 @@ class SentryTracingFilterTest { val sentryTraceHeaderString = "2722d9f6ec019ade60c776169d9a8904-$parentSpanId-1" val baggageHeaderStrings = listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=2722d9f6ec019ade60c776169d9a8904,sentry-transaction=HTTP%20GET") fixture.options.tracesSampleRate = null - fixture.options.ignoredSpanOrigins = listOf("auto.http.spring_jakarta.webmvc") + fixture.options.setIgnoredSpanOrigins(listOf("auto.http.spring_jakarta.webmvc")) val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) filter.doFilter(fixture.request, fixture.response, fixture.chain) diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt index bfd2d9e1adb..c7b732f4602 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt @@ -330,7 +330,7 @@ class SentryWebFluxTracingFilterTest { val sentryTraceHeaderString = "2722d9f6ec019ade60c776169d9a8904-$parentSpanId-1" val baggageHeaderStrings = listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=2722d9f6ec019ade60c776169d9a8904,sentry-transaction=HTTP%20GET") fixture.options.tracesSampleRate = null - fixture.options.ignoredSpanOrigins = listOf("auto.spring_jakarta.webflux") + fixture.options.setIgnoredSpanOrigins(listOf("auto.spring_jakarta.webflux")) val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) withMockScopes { diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt index c6eac05a146..538ac7c8cc6 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt @@ -291,7 +291,7 @@ class SentryTracingFilterTest { val sentryTraceHeaderString = "2722d9f6ec019ade60c776169d9a8904-$parentSpanId-1" val baggageHeaderStrings = listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=2722d9f6ec019ade60c776169d9a8904,sentry-transaction=HTTP%20GET") fixture.options.tracesSampleRate = null - fixture.options.ignoredSpanOrigins = listOf("auto.http.spring.webmvc") + fixture.options.setIgnoredSpanOrigins(listOf("auto.http.spring.webmvc")) val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) filter.doFilter(fixture.request, fixture.response, fixture.chain) diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt index 56e925ab3fd..6eba98d1d2e 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt @@ -331,7 +331,7 @@ class SentryWebFluxTracingFilterTest { val sentryTraceHeaderString = "2722d9f6ec019ade60c776169d9a8904-$parentSpanId-1" val baggageHeaderStrings = listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=2722d9f6ec019ade60c776169d9a8904,sentry-transaction=HTTP%20GET") fixture.options.tracesSampleRate = null - fixture.options.ignoredSpanOrigins = listOf("auto.spring.webflux") + fixture.options.setIgnoredSpanOrigins(listOf("auto.spring.webflux")) val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) withMockScopes { diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 68f8b3a17b2..c06fd0c3cb0 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -511,7 +511,9 @@ public final class io/sentry/ExternalOptions { public final class io/sentry/FilterString { public fun (Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z public fun getFilterString ()Ljava/lang/String; + public fun hashCode ()I public fun matches (Ljava/lang/String;)Z } From 419ef5b5753d60d4718e59b69734a30ea4a2319b Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Tue, 17 Dec 2024 11:16:22 +0100 Subject: [PATCH 5/9] add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c463729b041..917cf014383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ - Replace deprecated `SimpleInstrumentation` with `SimplePerformantInstrumentation` for graphql 22 ([#3974](https://github.com/getsentry/sentry-java/pull/3974)) - Cache requests for Spring using Springs `ContentCachingRequestWrapper` instead of our own Wrapper to also cache parameters ([#3641](https://github.com/getsentry/sentry-java/pull/3641)) - Previously only the body was cached which could lead to problems in the FilterChain as Request parameters were not available +- Improve ignored check performance ([#3992](https://github.com/getsentry/sentry-java/pull/3992)) + - Checking if a span origin, a transaction or a checkIn should be ignored is now faster ## 8.0.0-rc.2 From fe304442a6b117df94996c819343fb336b32b87d Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Tue, 17 Dec 2024 10:19:51 +0000 Subject: [PATCH 6/9] Format code --- sentry/src/main/java/io/sentry/util/SpanUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry/src/main/java/io/sentry/util/SpanUtils.java b/sentry/src/main/java/io/sentry/util/SpanUtils.java index da98ce9afff..ed846271713 100644 --- a/sentry/src/main/java/io/sentry/util/SpanUtils.java +++ b/sentry/src/main/java/io/sentry/util/SpanUtils.java @@ -1,7 +1,7 @@ package io.sentry.util; -import io.sentry.SentryOpenTelemetryMode; import io.sentry.FilterString; +import io.sentry.SentryOpenTelemetryMode; import java.util.ArrayList; import java.util.List; import java.util.Map; From 791e09d8719715917d3fed2e1a52f9d238a7439e Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Fri, 20 Dec 2024 13:23:11 +0100 Subject: [PATCH 7/9] Update sentry/src/main/java/io/sentry/FilterString.java Co-authored-by: Alexander Dinauer --- sentry/src/main/java/io/sentry/FilterString.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry/src/main/java/io/sentry/FilterString.java b/sentry/src/main/java/io/sentry/FilterString.java index 0e2813773eb..8dd5f479492 100644 --- a/sentry/src/main/java/io/sentry/FilterString.java +++ b/sentry/src/main/java/io/sentry/FilterString.java @@ -30,6 +30,6 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hashCode(filterString); + return Objects.hash(filterString); } } From f1c0bb6435766c68f6bef28cfd7fc1ac57291fdd Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Fri, 20 Dec 2024 13:31:50 +0100 Subject: [PATCH 8/9] add tests for multiple invocations --- .../test/java/io/sentry/util/SpanUtilsTest.kt | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt index 6049f89f4a8..03972d6c819 100644 --- a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt @@ -13,12 +13,26 @@ class SpanUtilsTest { assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) } + @Test + fun `isIgnored returns true for exact match with multiple invocations`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) + assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) + assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) + } + @Test fun `isIgnored returns true for regex match`() { val ignoredOrigins = listOf(FilterString("auto.http.spring.*")) assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) } + @Test + fun `isIgnored returns true for regex match with multiple invocations`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring.*")) + assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) + assertTrue(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring_jakarta.webmvc")) + } + @Test fun `isIgnored returns false for no match`() { val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) @@ -26,9 +40,9 @@ class SpanUtilsTest { } @Test - fun `isIgnored returns false for no regex match`() { - val ignoredOrigins = listOf(FilterString("auto.http.spring.*")) - assertFalse(SpanUtils.isIgnored(ignoredOrigins, "auto.http.servlet")) + fun `isIgnored returns false for no match with multiple invocations`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) + assertFalse(SpanUtils.isIgnored(ignoredOrigins, "auto.http.spring.webflux")) } @Test @@ -37,13 +51,32 @@ class SpanUtilsTest { assertFalse(SpanUtils.isIgnored(ignoredOrigins, null)) } + @Test + fun `isIgnored returns false for null origin with multiple invocations`() { + val ignoredOrigins = listOf(FilterString("auto.http.spring_jakarta.webmvc")) + assertFalse(SpanUtils.isIgnored(ignoredOrigins, null)) + } + + @Test fun `isIgnored returns false for null ignoredOrigins`() { assertFalse(SpanUtils.isIgnored(null, "auto.http.spring_jakarta.webmvc")) } + @Test + fun `isIgnored returns false for null ignoredOrigins with multiple invocations`() { + assertFalse(SpanUtils.isIgnored(null, "auto.http.spring_jakarta.webmvc")) + assertFalse(SpanUtils.isIgnored(null, "auto.http.spring_jakarta.webmvc")) + } + @Test fun `isIgnored returns false for empty ignoredOrigins`() { assertFalse(SpanUtils.isIgnored(emptyList(), "auto.http.spring_jakarta.webmvc")) } + + @Test + fun `isIgnored returns false for empty ignoredOrigins with multiple invocations`() { + assertFalse(SpanUtils.isIgnored(emptyList(), "auto.http.spring_jakarta.webmvc")) + assertFalse(SpanUtils.isIgnored(emptyList(), "auto.http.spring_jakarta.webmvc")) + } } From 2b80ccdc93ef9675218c9e2cccaa7ba93af20e97 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Fri, 20 Dec 2024 12:37:10 +0000 Subject: [PATCH 9/9] Format code --- sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt index 03972d6c819..90f721432c3 100644 --- a/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/SpanUtilsTest.kt @@ -57,7 +57,6 @@ class SpanUtilsTest { assertFalse(SpanUtils.isIgnored(ignoredOrigins, null)) } - @Test fun `isIgnored returns false for null ignoredOrigins`() { assertFalse(SpanUtils.isIgnored(null, "auto.http.spring_jakarta.webmvc"))