Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ignoredTransactions option to filter out transactions by name #3871

Merged
merged 14 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class SentryAutoConfigurationTest {
"sentry.enabled=false",
"sentry.send-modules=false",
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.enable-backpressure-handling=false",
"sentry.enable-spotlight=true",
"sentry.spotlight-connection-url=http://local.sentry.io:1234",
Expand Down Expand Up @@ -213,6 +214,7 @@ class SentryAutoConfigurationTest {
assertThat(options.isEnabled).isEqualTo(false)
assertThat(options.isSendModules).isEqualTo(false)
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.ignoredTransactions).containsOnly("transactionName1", "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 @@ -169,6 +169,7 @@ class SentryAutoConfigurationTest {
"sentry.enabled=false",
"sentry.send-modules=false",
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.enable-backpressure-handling=false",
"sentry.enable-spotlight=true",
"sentry.spotlight-connection-url=http://local.sentry.io:1234",
Expand Down Expand Up @@ -209,6 +210,7 @@ class SentryAutoConfigurationTest {
assertThat(options.isEnabled).isEqualTo(false)
assertThat(options.isSendModules).isEqualTo(false)
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.ignoredTransactions).containsOnly("transactionName1", "transactionNameB")
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
assertThat(options.isForceInit).isEqualTo(true)
assertThat(options.isGlobalHubMode).isEqualTo(true)
Expand Down
5 changes: 5 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ public final class io/sentry/ExternalOptions {
public fun getIdleTimeout ()Ljava/lang/Long;
public fun getIgnoredCheckIns ()Ljava/util/List;
public fun getIgnoredExceptionsForType ()Ljava/util/Set;
public fun getIgnoredTransactions ()Ljava/util/List;
public fun getInAppExcludes ()Ljava/util/List;
public fun getInAppIncludes ()Ljava/util/List;
public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize;
Expand Down Expand Up @@ -492,6 +493,7 @@ public final class io/sentry/ExternalOptions {
public fun setGlobalHubMode (Ljava/lang/Boolean;)V
public fun setIdleTimeout (Ljava/lang/Long;)V
public fun setIgnoredCheckIns (Ljava/util/List;)V
public fun setIgnoredTransactions (Ljava/util/List;)V
public fun setMaxRequestBodySize (Lio/sentry/SentryOptions$RequestSize;)V
public fun setPrintUncaughtStackTrace (Ljava/lang/Boolean;)V
public fun setProfilesSampleRate (Ljava/lang/Double;)V
Expand Down Expand Up @@ -2826,6 +2828,7 @@ public class io/sentry/SentryOptions {
public fun getIgnoredCheckIns ()Ljava/util/List;
public fun getIgnoredExceptionsForType ()Ljava/util/Set;
public fun getIgnoredSpanOrigins ()Ljava/util/List;
public fun getIgnoredTransactions ()Ljava/util/List;
public fun getInAppExcludes ()Ljava/util/List;
public fun getInAppIncludes ()Ljava/util/List;
public fun getInitPriority ()Lio/sentry/InitPriority;
Expand Down Expand Up @@ -2953,6 +2956,7 @@ public class io/sentry/SentryOptions {
public fun setIdleTimeout (Ljava/lang/Long;)V
public fun setIgnoredCheckIns (Ljava/util/List;)V
public fun setIgnoredSpanOrigins (Ljava/util/List;)V
public fun setIgnoredTransactions (Ljava/util/List;)V
public fun setInitPriority (Lio/sentry/InitPriority;)V
public fun setInstrumenter (Lio/sentry/Instrumenter;)V
public fun setLogger (Lio/sentry/ILogger;)V
Expand Down Expand Up @@ -6193,6 +6197,7 @@ public final class io/sentry/util/StringUtils {

public final class io/sentry/util/TracingUtils {
public fun <init> ()V
public static fun isIgnored (Ljava/util/List;Ljava/lang/String;)Z
public static fun maybeUpdateBaggage (Lio/sentry/IScope;Lio/sentry/SentryOptions;)Lio/sentry/PropagationContext;
public static fun startNewTrace (Lio/sentry/IScopes;)V
public static fun trace (Lio/sentry/IScopes;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders;
Expand Down
10 changes: 10 additions & 0 deletions sentry/src/main/java/io/sentry/ExternalOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public final class ExternalOptions {
private @Nullable String spotlightConnectionUrl;

private @Nullable List<String> ignoredCheckIns;
private @Nullable List<String> ignoredTransactions;

private @Nullable Boolean sendModules;
private @Nullable Boolean sendDefaultPii;
Expand Down Expand Up @@ -138,6 +139,7 @@ public final class ExternalOptions {
options.setSendDefaultPii(propertiesProvider.getBooleanProperty("send-default-pii"));

options.setIgnoredCheckIns(propertiesProvider.getList("ignored-checkins"));
options.setIgnoredTransactions(propertiesProvider.getList("ignored-transactions"));

options.setEnableBackpressureHandling(
propertiesProvider.getBooleanProperty("enable-backpressure-handling"));
Expand Down Expand Up @@ -430,6 +432,14 @@ public void setIgnoredCheckIns(final @Nullable List<String> ignoredCheckIns) {
return ignoredCheckIns;
}

public void setIgnoredTransactions(final @Nullable List<String> ignoredTransactions) {
this.ignoredTransactions = ignoredTransactions;
}

public @Nullable List<String> getIgnoredTransactions() {
return ignoredTransactions;
}

@ApiStatus.Experimental
public void setEnableBackpressureHandling(final @Nullable Boolean enableBackpressureHandling) {
this.enableBackpressureHandling = enableBackpressureHandling;
Expand Down
24 changes: 20 additions & 4 deletions sentry/src/main/java/io/sentry/SentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,23 @@ public void captureSession(final @NotNull Session session, final @Nullable Hint
.getLogger()
.log(SentryLevel.DEBUG, "Capturing transaction: %s", transaction.getEventId());

if (TracingUtils.isIgnored(options.getIgnoredTransactions(), transaction.getTransaction())) {
options
.getLogger()
.log(
SentryLevel.DEBUG,
"Transaction was dropped as transaction name %s is ignored",
transaction.getTransaction());
options
.getClientReportRecorder()
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Transaction);
options
.getClientReportRecorder()
.recordLostEvent(
DiscardReason.EVENT_PROCESSOR, DataCategory.Span, transaction.getSpans().size() + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the +1 here do? Is that to account for the transaction?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, same as further down.

return SentryId.EMPTY_ID;
}

SentryId sentryId = SentryId.EMPTY_ID;
if (transaction.getEventId() != null) {
sentryId = transaction.getEventId();
Expand Down Expand Up @@ -880,10 +897,9 @@ public void captureSession(final @NotNull Session session, final @Nullable Hint
SentryLevel.DEBUG,
"Check-in was dropped as slug %s is ignored",
checkIn.getMonitorSlug());
// TODO in a follow up PR with DataCategory.Monitor
// options
// .getClientReportRecorder()
// .recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Error);
options
.getClientReportRecorder()
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.Monitor);
return SentryId.EMPTY_ID;
}

Expand Down
26 changes: 26 additions & 0 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ public class SentryOptions {
/** Contains a list of span origins for which spans / transactions should not be created. */
@ApiStatus.Experimental private @Nullable List<String> ignoredSpanOrigins = null;

private @Nullable List<String> ignoredTransactions = null;

@ApiStatus.Experimental
private @NotNull IBackpressureMonitor backpressureMonitor = NoOpBackpressureMonitor.getInstance();

Expand Down Expand Up @@ -2186,6 +2188,26 @@ public void setIgnoredSpanOrigins(final @Nullable List<String> ignoredSpanOrigin
return ignoredCheckIns;
}

public @Nullable List<String> getIgnoredTransactions() {
return ignoredTransactions;
}

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

this.ignoredTransactions = filtered;
}
}

/** Returns the current {@link SentryDateProvider} that is used to retrieve the current date. */
@ApiStatus.Internal
public @NotNull SentryDateProvider getDateProvider() {
Expand Down Expand Up @@ -2667,6 +2689,10 @@ public void merge(final @NotNull ExternalOptions options) {
final List<String> ignoredCheckIns = new ArrayList<>(options.getIgnoredCheckIns());
setIgnoredCheckIns(ignoredCheckIns);
}
if (options.getIgnoredTransactions() != null) {
final List<String> ignoredTransactions = new ArrayList<>(options.getIgnoredTransactions());
setIgnoredTransactions(ignoredTransactions);
}
if (options.isEnableBackpressureHandling() != null) {
setEnableBackpressureHandling(options.isEnableBackpressureHandling());
}
Expand Down
29 changes: 29 additions & 0 deletions sentry/src/main/java/io/sentry/util/TracingUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.sentry.SentryOptions;
import io.sentry.SentryTraceHeader;
import java.util.List;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -116,4 +117,32 @@ public TracingHeaders(
return baggageHeader;
}
}

/** Checks if a transaction has been ignored. */
adinauer marked this conversation as resolved.
Show resolved Hide resolved
@ApiStatus.Internal
public static boolean isIgnored(
final @Nullable List<String> ignoredTransactions, final @Nullable String transactionName) {
if (transactionName == null) {
return false;
}
if (ignoredTransactions == null || ignoredTransactions.isEmpty()) {
return false;
}

for (final String ignoredSlug : ignoredTransactions) {
if (ignoredSlug.equalsIgnoreCase(transactionName)) {
return true;
}

try {
if (transactionName.matches(ignoredSlug)) {
return true;
}
} catch (Throwable t) {
// ignore invalid regex
}
}

return false;
}
}
7 changes: 7 additions & 0 deletions sentry/src/test/java/io/sentry/ExternalOptionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ class ExternalOptionsTest {
}
}

@Test
fun `creates options with ignoredTransactions`() {
withPropertiesFile("ignored-transactions=transactionName1,transactionName2") { options ->
assertTrue(options.ignoredTransactions!!.containsAll(listOf("transactionName1", "transactionName2")))
}
}

@Test
fun `creates options with enableBackpressureHandling set to false`() {
withPropertiesFile("enable-backpressure-handling=false") { options ->
Expand Down
22 changes: 22 additions & 0 deletions sentry/src/test/java/io/sentry/SentryClientTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,28 @@ class SentryClientTest {
)
}

@Test
fun `transaction dropped by ignoredTransactions is recorded`() {
adinauer marked this conversation as resolved.
Show resolved Hide resolved
fixture.sentryOptions.ignoredTransactions = listOf("a-transaction")

val transaction = SentryTransaction(fixture.sentryTracer)

val eventId =
fixture.getSut().captureTransaction(transaction, fixture.sentryTracer.traceContext())

verify(fixture.transport, never()).send(any(), anyOrNull())

assertClientReport(
fixture.sentryOptions.clientReportRecorder,
listOf(
DiscardedEvent(DiscardReason.EVENT_PROCESSOR.reason, DataCategory.Transaction.category, 1),
DiscardedEvent(DiscardReason.EVENT_PROCESSOR.reason, DataCategory.Span.category, 2)
)
)

assertEquals(SentryId.EMPTY_ID, eventId)
}

@Test
fun `backfillable events are only wired through backfilling processors`() {
val backfillingProcessor = mock<BackfillingEventProcessor>()
Expand Down
2 changes: 2 additions & 0 deletions sentry/src/test/java/io/sentry/SentryOptionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ class SentryOptionsTest {
externalOptions.isEnablePrettySerializationOutput = false
externalOptions.isSendModules = false
externalOptions.ignoredCheckIns = listOf("slug1", "slug-B")
externalOptions.ignoredTransactions = listOf("transactionName1", "transaction-name-B")
externalOptions.isEnableBackpressureHandling = false
externalOptions.maxRequestBodySize = SentryOptions.RequestSize.MEDIUM
externalOptions.isSendDefaultPii = true
Expand Down Expand Up @@ -368,6 +369,7 @@ class SentryOptionsTest {
assertFalse(options.isEnablePrettySerializationOutput)
assertFalse(options.isSendModules)
assertEquals(listOf("slug1", "slug-B"), options.ignoredCheckIns)
assertEquals(listOf("transactionName1", "transaction-name-B"), options.ignoredTransactions)
assertFalse(options.isEnableBackpressureHandling)
assertTrue(options.isForceInit)
assertNotNull(options.cron)
Expand Down
Loading