Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
- This keeps it from being garbage collected too early
- Close backpressure monitor on SDK shutdown ([#3998](https://github.com/getsentry/sentry-java/pull/3998))
- Due to the backpressure monitor rescheduling a task to run every 10s, it very likely caused shutdown to wait the full `shutdownTimeoutMillis` (defaulting to 2s) instead of being able to terminate immediately
- 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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class SentryFeignClientTest {
@Test
fun `does not add sentry trace header when span origin is ignored`() {
fixture.sentryOptions.dsn = "https://[email protected]/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)!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Unit>(headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Unit>(headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 10 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,14 @@ public final class io/sentry/ExternalOptions {
public fun setTracesSampleRate (Ljava/lang/Double;)V
}

public final class io/sentry/FilterString {
public fun <init> (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
}

public final class io/sentry/FullyDisplayedReporter {
public static fun getInstance ()Lio/sentry/FullyDisplayedReporter;
public fun registerFullyDrawnListener (Lio/sentry/FullyDisplayedReporter$FullyDisplayedReporterListener;)V
Expand Down Expand Up @@ -2806,8 +2814,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
Expand Down
35 changes: 35 additions & 0 deletions sentry/src/main/java/io/sentry/FilterString.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.sentry;

import java.util.Objects;
import java.util.regex.Pattern;
import org.jetbrains.annotations.NotNull;

public final 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();
}

@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.hash(filterString);
}
}
77 changes: 47 additions & 30 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -466,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<String> ignoredCheckIns = null;
@ApiStatus.Experimental private @Nullable List<FilterString> ignoredCheckIns = null;

/** Contains a list of span origins for which spans / transactions should not be created. */
@ApiStatus.Experimental private @Nullable List<String> ignoredSpanOrigins = null;
@ApiStatus.Experimental private @Nullable List<FilterString> ignoredSpanOrigins = null;

private @Nullable List<String> ignoredTransactions = null;
private @Nullable List<FilterString> ignoredTransactions = null;

@ApiStatus.Experimental
private @NotNull IBackpressureMonitor backpressureMonitor = NoOpBackpressureMonitor.getInstance();
Expand Down Expand Up @@ -2175,42 +2175,27 @@ public void setSendModules(boolean sendModules) {
}

@ApiStatus.Experimental
public void setIgnoredCheckIns(final @Nullable List<String> ignoredCheckIns) {
if (ignoredCheckIns == null) {
this.ignoredCheckIns = null;
} else {
@NotNull final List<String> filteredIgnoredCheckIns = new ArrayList<>();
for (String slug : ignoredCheckIns) {
if (!slug.isEmpty()) {
filteredIgnoredCheckIns.add(slug);
}
}

this.ignoredCheckIns = filteredIgnoredCheckIns;
}
}

@ApiStatus.Experimental
public @Nullable List<String> getIgnoredSpanOrigins() {
public @Nullable List<FilterString> getIgnoredSpanOrigins() {
return ignoredSpanOrigins;
}

public void addIgnoredSpanOrigin(final @NotNull String origin) {
if (this.ignoredSpanOrigins == null) {
this.ignoredSpanOrigins = new ArrayList<>();
@ApiStatus.Experimental
public void addIgnoredSpanOrigin(String ignoredSpanOrigin) {
if (ignoredSpanOrigins == null) {
ignoredSpanOrigins = new ArrayList<>();
}
this.ignoredSpanOrigins.add(origin);
ignoredSpanOrigins.add(new FilterString(ignoredSpanOrigin));
}

@ApiStatus.Experimental
public void setIgnoredSpanOrigins(final @Nullable List<String> ignoredSpanOrigins) {
if (ignoredSpanOrigins == null) {
this.ignoredSpanOrigins = null;
} else {
@NotNull final List<String> filtered = new ArrayList<>();
@NotNull final List<FilterString> filtered = new ArrayList<>();
for (String origin : ignoredSpanOrigins) {
if (origin != null && !origin.isEmpty()) {
filtered.add(origin);
filtered.add(new FilterString(origin));
}
}

Expand All @@ -2219,23 +2204,55 @@ public void setIgnoredSpanOrigins(final @Nullable List<String> ignoredSpanOrigin
}

@ApiStatus.Experimental
public @Nullable List<String> getIgnoredCheckIns() {
public @Nullable List<FilterString> getIgnoredCheckIns() {
return ignoredCheckIns;
}

public @Nullable List<String> 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<String> ignoredCheckIns) {
if (ignoredCheckIns == null) {
this.ignoredCheckIns = null;
} else {
@NotNull final List<FilterString> filteredIgnoredCheckIns = new ArrayList<>();
for (String slug : ignoredCheckIns) {
if (!slug.isEmpty()) {
filteredIgnoredCheckIns.add(new FilterString(slug));
}
}

this.ignoredCheckIns = filteredIgnoredCheckIns;
}
}

public @Nullable List<FilterString> 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<String> ignoredTransactions) {
if (ignoredTransactions == null) {
this.ignoredTransactions = null;
} else {
@NotNull final List<String> filtered = new ArrayList<>();
@NotNull final List<FilterString> filtered = new ArrayList<>();
for (String transactionName : ignoredTransactions) {
if (transactionName != null && !transactionName.isEmpty()) {
filtered.add(transactionName);
filtered.add(new FilterString(transactionName));
}
}

Expand Down
11 changes: 7 additions & 4 deletions sentry/src/main/java/io/sentry/util/CheckInUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -116,18 +117,20 @@ public static <U> U withCheckIn(
/** Checks if a check-in for a monitor (CRON) has been ignored. */
@ApiStatus.Internal
public static boolean isIgnored(
final @Nullable List<String> ignoredSlugs, final @NotNull String slug) {
final @Nullable List<FilterString> 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) {
Expand Down
Loading
Loading