Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ class SentryAutoConfigurationTest {
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-errors=Some error,Another .*",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.ignored-server-http-status-codes-for-tracing=404,500-599",
"sentry.enable-backpressure-handling=false",
"sentry.enable-database-transaction-tracing=true",
"sentry.enable-cache-tracing=true",
Expand Down Expand Up @@ -316,6 +317,10 @@ class SentryAutoConfigurationTest {
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.ignoredErrors).containsOnly("Some error", "Another .*")
assertThat(options.ignoredTransactions).containsOnly("transactionName1", "transactionNameB")
assertThat(options.ignoredServerHttpStatusCodesForTracing).hasSize(2)
assertThat(options.ignoredServerHttpStatusCodesForTracing!![0].isInRange(404)).isTrue()
assertThat(options.ignoredServerHttpStatusCodesForTracing!![1].isInRange(500)).isTrue()
assertThat(options.ignoredServerHttpStatusCodesForTracing!![1].isInRange(599)).isTrue()
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
assertThat(options.isEnableDatabaseTransactionTracing).isEqualTo(true)
assertThat(options.isEnableCacheTracing).isEqualTo(true)
Expand All @@ -336,6 +341,19 @@ class SentryAutoConfigurationTest {
}
}

@Test
fun `empty ignored server HTTP status codes disable the configuration`() {
contextRunner
.withPropertyValues(
"sentry.dsn=http://key@localhost/proj",
"sentry.ignored-server-http-status-codes-for-tracing=",
)
.run {
assertThat(it.getBean(SentryProperties::class.java).ignoredServerHttpStatusCodesForTracing)
.isEmpty()
}
}

@Test
fun `data collection properties are applied to SentryOptions`() {
contextRunner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ class SentryAutoConfigurationTest {
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-errors=Some error,Another .*",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.ignored-server-http-status-codes-for-tracing=404,500-599",
"sentry.enable-backpressure-handling=false",
"sentry.enable-database-transaction-tracing=true",
"sentry.enable-spotlight=true",
Expand Down Expand Up @@ -321,6 +322,10 @@ class SentryAutoConfigurationTest {
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.ignoredErrors).containsOnly("Some error", "Another .*")
assertThat(options.ignoredTransactions).containsOnly("transactionName1", "transactionNameB")
assertThat(options.ignoredServerHttpStatusCodesForTracing).hasSize(2)
assertThat(options.ignoredServerHttpStatusCodesForTracing!![0].isInRange(404)).isTrue()
assertThat(options.ignoredServerHttpStatusCodesForTracing!![1].isInRange(500)).isTrue()
assertThat(options.ignoredServerHttpStatusCodesForTracing!![1].isInRange(599)).isTrue()
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
assertThat(options.isEnableDatabaseTransactionTracing).isEqualTo(true)
assertThat(options.isForceInit).isEqualTo(true)
Expand All @@ -344,6 +349,19 @@ class SentryAutoConfigurationTest {
}
}

@Test
fun `empty ignored server HTTP status codes disable the configuration`() {
contextRunner
.withPropertyValues(
"sentry.dsn=http://key@localhost/proj",
"sentry.ignored-server-http-status-codes-for-tracing=",
)
.run {
assertThat(it.getBean(SentryProperties::class.java).ignoredServerHttpStatusCodesForTracing)
.isEmpty()
}
}

@Test
fun `data collection properties are applied to SentryOptions`() {
contextRunner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class SentryAutoConfigurationTest {
"sentry.ignored-checkins=slug1,slugB",
"sentry.ignored-errors=Some error,Another .*",
"sentry.ignored-transactions=transactionName1,transactionNameB",
"sentry.ignored-server-http-status-codes-for-tracing=404,500-599",
"sentry.enable-backpressure-handling=false",
"sentry.enable-database-transaction-tracing=true",
"sentry.enable-spotlight=true",
Expand Down Expand Up @@ -319,6 +320,10 @@ class SentryAutoConfigurationTest {
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.ignoredErrors).containsOnly("Some error", "Another .*")
assertThat(options.ignoredTransactions).containsOnly("transactionName1", "transactionNameB")
assertThat(options.ignoredServerHttpStatusCodesForTracing).hasSize(2)
assertThat(options.ignoredServerHttpStatusCodesForTracing!![0].isInRange(404)).isTrue()
assertThat(options.ignoredServerHttpStatusCodesForTracing!![1].isInRange(500)).isTrue()
assertThat(options.ignoredServerHttpStatusCodesForTracing!![1].isInRange(599)).isTrue()
assertThat(options.isEnableBackpressureHandling).isEqualTo(false)
assertThat(options.isEnableDatabaseTransactionTracing).isEqualTo(true)
assertThat(options.isForceInit).isEqualTo(true)
Expand All @@ -342,6 +347,19 @@ class SentryAutoConfigurationTest {
}
}

@Test
fun `empty ignored server HTTP status codes disable the configuration`() {
contextRunner
.withPropertyValues(
"sentry.dsn=http://key@localhost/proj",
"sentry.ignored-server-http-status-codes-for-tracing=",
)
.run {
assertThat(it.getBean(SentryProperties::class.java).ignoredServerHttpStatusCodesForTracing)
.isEmpty()
}
}

@Test
fun `data collection properties are applied to SentryOptions`() {
contextRunner
Expand Down
5 changes: 5 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ public final class io/sentry/ExternalOptions {
public fun getIgnoredCheckIns ()Ljava/util/List;
public fun getIgnoredErrors ()Ljava/util/List;
public fun getIgnoredExceptionsForType ()Ljava/util/Set;
public fun getIgnoredServerHttpStatusCodesForTracing ()Ljava/util/List;
public fun getIgnoredTransactions ()Ljava/util/List;
public fun getInAppExcludes ()Ljava/util/List;
public fun getInAppIncludes ()Ljava/util/List;
Expand Down Expand Up @@ -623,6 +624,7 @@ public final class io/sentry/ExternalOptions {
public fun setIdleTimeout (Ljava/lang/Long;)V
public fun setIgnoredCheckIns (Ljava/util/List;)V
public fun setIgnoredErrors (Ljava/util/List;)V
public fun setIgnoredServerHttpStatusCodesForTracing (Ljava/util/List;)V
public fun setIgnoredTransactions (Ljava/util/List;)V
public fun setMaxRequestBodySize (Lio/sentry/SentryOptions$RequestSize;)V
public fun setOrgId (Ljava/lang/String;)V
Expand Down Expand Up @@ -710,6 +712,7 @@ public final class io/sentry/HttpStatusCodeRange {
public fun <init> (I)V
public fun <init> (II)V
public fun isInRange (I)Z
public static fun valueOf (Ljava/lang/String;)Lio/sentry/HttpStatusCodeRange;
}

public abstract interface class io/sentry/IAppStartExtender {
Expand Down Expand Up @@ -3556,6 +3559,7 @@ public class io/sentry/SentryOptions : io/sentry/transport/RateLimiterConfig {
public fun getIgnoredErrorFilters ()Ljava/util/List;
public fun getIgnoredErrors ()Ljava/util/List;
public fun getIgnoredExceptionsForType ()Ljava/util/Set;
public fun getIgnoredServerHttpStatusCodesForTracing ()Ljava/util/List;
public fun getIgnoredSpanOriginFilters ()Ljava/util/List;
public fun getIgnoredSpanOrigins ()Ljava/util/List;
public fun getIgnoredTransactionFilters ()Ljava/util/List;
Expand Down Expand Up @@ -3729,6 +3733,7 @@ public class io/sentry/SentryOptions : io/sentry/transport/RateLimiterConfig {
public fun setIdleTimeout (Ljava/lang/Long;)V
public fun setIgnoredCheckIns (Ljava/util/List;)V
public fun setIgnoredErrors (Ljava/util/List;)V
public fun setIgnoredServerHttpStatusCodesForTracing (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
Expand Down
37 changes: 37 additions & 0 deletions sentry/src/main/java/io/sentry/ExternalOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public final class ExternalOptions {

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

private @Nullable Boolean sendModules;
private @Nullable Boolean sendDefaultPii;
Expand Down Expand Up @@ -160,6 +161,8 @@ public final class ExternalOptions {

options.setIgnoredCheckIns(propertiesProvider.getListOrNull("ignored-checkins"));
options.setIgnoredTransactions(propertiesProvider.getListOrNull("ignored-transactions"));
options.setIgnoredServerHttpStatusCodesForTracing(
parseIgnoredServerHttpStatusCodesForTracing(propertiesProvider, logger));

options.setEnableBackpressureHandling(
propertiesProvider.getBooleanProperty("enable-backpressure-handling"));
Expand Down Expand Up @@ -243,6 +246,31 @@ public final class ExternalOptions {
return options;
}

private static @Nullable List<HttpStatusCodeRange> parseIgnoredServerHttpStatusCodesForTracing(
final @NotNull PropertiesProvider propertiesProvider, final @NotNull ILogger logger) {
final String value =
propertiesProvider.getProperty("ignored-server-http-status-codes-for-tracing");
if (value == null) {
return null;
}
if (value.trim().isEmpty()) {
return new ArrayList<>();
}

final List<HttpStatusCodeRange> ranges = new ArrayList<>();
for (final String token : value.split(",", -1)) {
try {
ranges.add(HttpStatusCodeRange.valueOf(token));
} catch (IllegalArgumentException e) {
logger.log(
SentryLevel.WARNING,
"Ignoring invalid HTTP status code range in ignored-server-http-status-codes-for-tracing: %s",
token);
}
}
return ranges.isEmpty() ? null : ranges;
}

private static @Nullable DataCollection parseDataCollection(
final @NotNull PropertiesProvider propertiesProvider) {
final DataCollection dataCollection = new DataCollection();
Expand Down Expand Up @@ -622,6 +650,15 @@ public void setIgnoredTransactions(final @Nullable List<String> ignoredTransacti
return ignoredTransactions;
}

public void setIgnoredServerHttpStatusCodesForTracing(
final @Nullable List<HttpStatusCodeRange> ignoredServerHttpStatusCodesForTracing) {
this.ignoredServerHttpStatusCodesForTracing = ignoredServerHttpStatusCodesForTracing;
}

public @Nullable List<HttpStatusCodeRange> getIgnoredServerHttpStatusCodesForTracing() {
return ignoredServerHttpStatusCodesForTracing;
}

public void setEnableBackpressureHandling(final @Nullable Boolean enableBackpressureHandling) {
this.enableBackpressureHandling = enableBackpressureHandling;
}
Expand Down
58 changes: 58 additions & 0 deletions sentry/src/main/java/io/sentry/HttpStatusCodeRange.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package io.sentry;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

/**
* The Http status code range. Example for a range: 400 to 499, 500 to 599, 400 to 599 The range is
* inclusive so the min and max is considered part of the range.
Expand All @@ -10,6 +13,9 @@ public final class HttpStatusCodeRange {
public static final int DEFAULT_MIN = 500;
public static final int DEFAULT_MAX = 599;

private static final int MIN_HTTP_STATUS_CODE = 100;
private static final int MAX_HTTP_STATUS_CODE = 599;

private final int min;
private final int max;

Expand All @@ -23,6 +29,58 @@ public HttpStatusCodeRange(final int statusCode) {
this.max = statusCode;
}

/**
* Parses a single HTTP status code or an inclusive range such as {@code 404} or {@code 500-599}.
*
* @param value the status code or range
* @return the parsed range
* @throws IllegalArgumentException if the value is malformed, outside 100-599, or reversed
*/
@ApiStatus.Internal
public static @NotNull HttpStatusCodeRange valueOf(final @NotNull String value) {
final String trimmedValue = value.trim();
final int separatorIndex = trimmedValue.indexOf('-');
if (separatorIndex < 0) {
return new HttpStatusCodeRange(parseStatusCode(trimmedValue));
}
if (separatorIndex == 0
|| separatorIndex == trimmedValue.length() - 1
|| separatorIndex != trimmedValue.lastIndexOf('-')) {
throw invalidRange(value);
}

final int min = parseStatusCode(trimmedValue.substring(0, separatorIndex).trim());
final int max = parseStatusCode(trimmedValue.substring(separatorIndex + 1).trim());
if (min > max) {
throw invalidRange(value);
}
return new HttpStatusCodeRange(min, max);
}

private static int parseStatusCode(final @NotNull String value) {
for (int i = 0; i < value.length(); i++) {
if (!Character.isDigit(value.charAt(i))) {
throw invalidRange(value);
}
}

final int statusCode;
try {
statusCode = Integer.parseInt(value);
} catch (NumberFormatException e) {
throw invalidRange(value);
}
if (statusCode < MIN_HTTP_STATUS_CODE || statusCode > MAX_HTTP_STATUS_CODE) {
throw invalidRange(value);
}
return statusCode;
}

private static @NotNull IllegalArgumentException invalidRange(final @NotNull String value) {
return new IllegalArgumentException(
"HTTP status code range must contain values from 100 to 599: " + value);
}

public boolean isInRange(final int statusCode) {
return statusCode >= min && statusCode <= max;
}
Expand Down
34 changes: 34 additions & 0 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,8 @@ public class SentryOptions implements RateLimiterConfig {
*/
private @Nullable List<FilterString> ignoredTransactions = null;

private @Nullable List<HttpStatusCodeRange> ignoredServerHttpStatusCodesForTracing = null;

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

Expand Down Expand Up @@ -3147,6 +3149,34 @@ public void setIgnoredTransactions(final @Nullable List<String> ignoredTransacti
}
}

/**
* Returns the HTTP status codes and inclusive ranges for which incoming server transactions are
* not sent to Sentry. An empty list disables this filter.
*
* @return the configured HTTP status code ranges, or {@code null} if unset
*/
public @Nullable List<HttpStatusCodeRange> getIgnoredServerHttpStatusCodesForTracing() {
return ignoredServerHttpStatusCodesForTracing;
}

/**
* Sets the HTTP status codes and inclusive ranges for which incoming server transactions are not
* sent to Sentry. For example, configure {@code new HttpStatusCodeRange(404)} for one status or
* {@code new HttpStatusCodeRange(500, 599)} for an inclusive range. External configuration
* accepts comma-separated codes and ranges such as {@code 404,410,500-599}. An empty list
* disables this filter.
*
* @param ignoredServerHttpStatusCodesForTracing the HTTP status code ranges, or {@code null} to
* leave the option unset
*/
public void setIgnoredServerHttpStatusCodesForTracing(
final @Nullable List<HttpStatusCodeRange> ignoredServerHttpStatusCodesForTracing) {
this.ignoredServerHttpStatusCodesForTracing =
ignoredServerHttpStatusCodesForTracing == null
? null
: new ArrayList<>(ignoredServerHttpStatusCodesForTracing);
}

/** Returns the current {@link SentryDateProvider} that is used to retrieve the current date. */
@ApiStatus.Internal
public @NotNull SentryDateProvider getDateProvider() {
Expand Down Expand Up @@ -3823,6 +3853,10 @@ public void merge(final @NotNull ExternalOptions options) {
final List<String> ignoredTransactions = new ArrayList<>(options.getIgnoredTransactions());
setIgnoredTransactions(ignoredTransactions);
}
if (options.getIgnoredServerHttpStatusCodesForTracing() != null) {
setIgnoredServerHttpStatusCodesForTracing(
options.getIgnoredServerHttpStatusCodesForTracing());
}
if (options.getIgnoredErrors() != null) {
final List<String> ignoredExceptions = new ArrayList<>(options.getIgnoredErrors());
setIgnoredErrors(ignoredExceptions);
Expand Down
Loading
Loading