Skip to content

Commit

Permalink
Defaults for Cron - MonitorConfig (#3195)
Browse files Browse the repository at this point in the history
* add cron default option to SentryOptions and ExternalOptions

* add test

* add tests, rename defaults

* add changelog

* external options only override cron default properties that are actually set in external options

* code review
  • Loading branch information
lbloder authored Feb 29, 2024
1 parent 7275aa8 commit a816b3f
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Add support for measurements at span level ([#3219](https://github.com/getsentry/sentry-java/pull/3219))
- Add `enableScopePersistence` option to disable `PersistingScopeObserver` used for ANR reporting which may increase performance overhead. Defaults to `true` ([#3218](https://github.com/getsentry/sentry-java/pull/3218))
- When disabled, the SDK will not enrich ANRv2 events with scope data (e.g. breadcrumbs, user, tags, etc.)
- Configurable defaults for Cron - MonitorConfig ([#3195](https://github.com/getsentry/sentry-java/pull/3195))

### Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,12 @@ class SentryAutoConfigurationTest {
"sentry.enabled=false",
"sentry.send-modules=false",
"sentry.ignored-checkins=slug1,slugB",
"sentry.enable-backpressure-handling=true"
"sentry.enable-backpressure-handling=true",
"sentry.cron.default-checkin-margin=10",
"sentry.cron.default-max-runtime=30",
"sentry.cron.default-timezone=America/New_York",
"sentry.cron.default-failure-issue-threshold=40",
"sentry.cron.default-recovery-threshold=50"
).run {
val options = it.getBean(SentryProperties::class.java)
assertThat(options.readTimeoutMillis).isEqualTo(10)
Expand Down Expand Up @@ -201,6 +206,12 @@ class SentryAutoConfigurationTest {
assertThat(options.isSendModules).isEqualTo(false)
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.isEnableBackpressureHandling).isEqualTo(true)
assertThat(options.cron).isNotNull
assertThat(options.cron!!.defaultCheckinMargin).isEqualTo(10L)
assertThat(options.cron!!.defaultMaxRuntime).isEqualTo(30L)
assertThat(options.cron!!.defaultTimezone).isEqualTo("America/New_York")
assertThat(options.cron!!.defaultFailureIssueThreshold).isEqualTo(40L)
assertThat(options.cron!!.defaultRecoveryThreshold).isEqualTo(50L)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,12 @@ class SentryAutoConfigurationTest {
"sentry.enabled=false",
"sentry.send-modules=false",
"sentry.ignored-checkins=slug1,slugB",
"sentry.enable-backpressure-handling=true"
"sentry.enable-backpressure-handling=true",
"sentry.cron.default-checkin-margin=10",
"sentry.cron.default-max-runtime=30",
"sentry.cron.default-timezone=America/New_York",
"sentry.cron.default-failure-issue-threshold=40",
"sentry.cron.default-recovery-threshold=50"
).run {
val options = it.getBean(SentryProperties::class.java)
assertThat(options.readTimeoutMillis).isEqualTo(10)
Expand Down Expand Up @@ -201,6 +206,12 @@ class SentryAutoConfigurationTest {
assertThat(options.isSendModules).isEqualTo(false)
assertThat(options.ignoredCheckIns).containsOnly("slug1", "slugB")
assertThat(options.isEnableBackpressureHandling).isEqualTo(true)
assertThat(options.cron).isNotNull
assertThat(options.cron!!.defaultCheckinMargin).isEqualTo(10L)
assertThat(options.cron!!.defaultMaxRuntime).isEqualTo(30L)
assertThat(options.cron!!.defaultTimezone).isEqualTo("America/New_York")
assertThat(options.cron!!.defaultFailureIssueThreshold).isEqualTo(40L)
assertThat(options.cron!!.defaultRecoveryThreshold).isEqualTo(50L)
}
}

Expand Down
18 changes: 18 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ public final class io/sentry/ExternalOptions {
public static fun from (Lio/sentry/config/PropertiesProvider;Lio/sentry/ILogger;)Lio/sentry/ExternalOptions;
public fun getBundleIds ()Ljava/util/Set;
public fun getContextTags ()Ljava/util/List;
public fun getCron ()Lio/sentry/SentryOptions$Cron;
public fun getDebug ()Ljava/lang/Boolean;
public fun getDist ()Ljava/lang/String;
public fun getDsn ()Ljava/lang/String;
Expand Down Expand Up @@ -343,6 +344,7 @@ public final class io/sentry/ExternalOptions {
public fun isEnablePrettySerializationOutput ()Ljava/lang/Boolean;
public fun isEnabled ()Ljava/lang/Boolean;
public fun isSendModules ()Ljava/lang/Boolean;
public fun setCron (Lio/sentry/SentryOptions$Cron;)V
public fun setDebug (Ljava/lang/Boolean;)V
public fun setDist (Ljava/lang/String;)V
public fun setDsn (Ljava/lang/String;)V
Expand Down Expand Up @@ -2204,6 +2206,7 @@ public class io/sentry/SentryOptions {
public fun getConnectionStatusProvider ()Lio/sentry/IConnectionStatusProvider;
public fun getConnectionTimeoutMillis ()I
public fun getContextTags ()Ljava/util/List;
public fun getCron ()Lio/sentry/SentryOptions$Cron;
public fun getDateProvider ()Lio/sentry/SentryDateProvider;
public fun getDebugMetaLoader ()Lio/sentry/internal/debugmeta/IDebugMetaLoader;
public fun getDiagnosticLevel ()Lio/sentry/SentryLevel;
Expand Down Expand Up @@ -2309,6 +2312,7 @@ public class io/sentry/SentryOptions {
public fun setCacheDirPath (Ljava/lang/String;)V
public fun setConnectionStatusProvider (Lio/sentry/IConnectionStatusProvider;)V
public fun setConnectionTimeoutMillis (I)V
public fun setCron (Lio/sentry/SentryOptions$Cron;)V
public fun setDateProvider (Lio/sentry/SentryDateProvider;)V
public fun setDebug (Z)V
public fun setDebugMetaLoader (Lio/sentry/internal/debugmeta/IDebugMetaLoader;)V
Expand Down Expand Up @@ -2405,6 +2409,20 @@ public abstract interface class io/sentry/SentryOptions$BeforeSendTransactionCal
public abstract fun execute (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction;
}

public final class io/sentry/SentryOptions$Cron {
public fun <init> ()V
public fun getDefaultCheckinMargin ()Ljava/lang/Long;
public fun getDefaultFailureIssueThreshold ()Ljava/lang/Long;
public fun getDefaultMaxRuntime ()Ljava/lang/Long;
public fun getDefaultRecoveryThreshold ()Ljava/lang/Long;
public fun getDefaultTimezone ()Ljava/lang/String;
public fun setDefaultCheckinMargin (Ljava/lang/Long;)V
public fun setDefaultFailureIssueThreshold (Ljava/lang/Long;)V
public fun setDefaultMaxRuntime (Ljava/lang/Long;)V
public fun setDefaultRecoveryThreshold (Ljava/lang/Long;)V
public fun setDefaultTimezone (Ljava/lang/String;)V
}

public abstract interface class io/sentry/SentryOptions$ProfilesSamplerCallback {
public abstract fun sample (Lio/sentry/SamplingContext;)Ljava/lang/Double;
}
Expand Down
38 changes: 38 additions & 0 deletions sentry/src/main/java/io/sentry/ExternalOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public final class ExternalOptions {
private @Nullable Boolean sendModules;
private @Nullable Boolean enableBackpressureHandling;

private @Nullable SentryOptions.Cron cron;

@SuppressWarnings("unchecked")
public static @NotNull ExternalOptions from(
final @NotNull PropertiesProvider propertiesProvider, final @NotNull ILogger logger) {
Expand Down Expand Up @@ -156,6 +158,32 @@ public final class ExternalOptions {
ignoredExceptionType);
}
}

final Long cronDefaultCheckinMargin =
propertiesProvider.getLongProperty("cron.default-checkin-margin");
final Long cronDefaultMaxRuntime =
propertiesProvider.getLongProperty("cron.default-max-runtime");
final String cronDefaultTimezone = propertiesProvider.getProperty("cron.default-timezone");
final Long cronDefaultFailureIssueThreshold =
propertiesProvider.getLongProperty("cron.default-failure-issue-threshold");
final Long cronDefaultRecoveryThreshold =
propertiesProvider.getLongProperty("cron.default-recovery-threshold");

if (cronDefaultCheckinMargin != null
|| cronDefaultMaxRuntime != null
|| cronDefaultTimezone != null
|| cronDefaultFailureIssueThreshold != null
|| cronDefaultRecoveryThreshold != null) {
SentryOptions.Cron cron = new SentryOptions.Cron();
cron.setDefaultCheckinMargin(cronDefaultCheckinMargin);
cron.setDefaultMaxRuntime(cronDefaultMaxRuntime);
cron.setDefaultTimezone(cronDefaultTimezone);
cron.setDefaultFailureIssueThreshold(cronDefaultFailureIssueThreshold);
cron.setDefaultRecoveryThreshold(cronDefaultRecoveryThreshold);

options.setCron(cron);
}

return options;
}

Expand Down Expand Up @@ -412,4 +440,14 @@ public void setEnableBackpressureHandling(final @Nullable Boolean enableBackpres
public @Nullable Boolean isEnableBackpressureHandling() {
return enableBackpressureHandling;
}

@ApiStatus.Experimental
public @Nullable SentryOptions.Cron getCron() {
return cron;
}

@ApiStatus.Experimental
public void setCron(final @Nullable SentryOptions.Cron cron) {
this.cron = cron;
}
}
8 changes: 8 additions & 0 deletions sentry/src/main/java/io/sentry/MonitorConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ public final class MonitorConfig implements JsonUnknown, JsonSerializable {

public MonitorConfig(final @NotNull MonitorSchedule schedule) {
this.schedule = schedule;
final SentryOptions.Cron defaultCron = HubAdapter.getInstance().getOptions().getCron();
if (defaultCron != null) {
this.checkinMargin = defaultCron.getDefaultCheckinMargin();
this.maxRuntime = defaultCron.getDefaultMaxRuntime();
this.timezone = defaultCron.getDefaultTimezone();
this.failureIssueThreshold = defaultCron.getDefaultFailureIssueThreshold();
this.recoveryThreshold = defaultCron.getDefaultRecoveryThreshold();
}
}

public @NotNull MonitorSchedule getSchedule() {
Expand Down
83 changes: 83 additions & 0 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ public class SentryOptions {
*/
private int profilingTracesHz = 101;

@ApiStatus.Experimental private @Nullable Cron cron = null;

/**
* Adds an event processor
*
Expand Down Expand Up @@ -2336,6 +2338,16 @@ public void setEnableMetrics(boolean enableMetrics) {
this.enableMetrics = enableMetrics;
}

@ApiStatus.Experimental
public @Nullable Cron getCron() {
return cron;
}

@ApiStatus.Experimental
public void setCron(@Nullable Cron cron) {
this.cron = cron;
}

/** The BeforeSend callback */
public interface BeforeSendCallback {

Expand Down Expand Up @@ -2569,6 +2581,29 @@ public void merge(final @NotNull ExternalOptions options) {
if (options.isEnableBackpressureHandling() != null) {
setEnableBackpressureHandling(options.isEnableBackpressureHandling());
}

if (options.getCron() != null) {
if (getCron() == null) {
setCron(options.getCron());
} else {
if (options.getCron().getDefaultCheckinMargin() != null) {
getCron().setDefaultCheckinMargin(options.getCron().getDefaultCheckinMargin());
}
if (options.getCron().getDefaultMaxRuntime() != null) {
getCron().setDefaultMaxRuntime(options.getCron().getDefaultMaxRuntime());
}
if (options.getCron().getDefaultTimezone() != null) {
getCron().setDefaultTimezone(options.getCron().getDefaultTimezone());
}
if (options.getCron().getDefaultFailureIssueThreshold() != null) {
getCron()
.setDefaultFailureIssueThreshold(options.getCron().getDefaultFailureIssueThreshold());
}
if (options.getCron().getDefaultRecoveryThreshold() != null) {
getCron().setDefaultRecoveryThreshold(options.getCron().getDefaultRecoveryThreshold());
}
}
}
}

private @NotNull SdkVersion createSdkVersion() {
Expand Down Expand Up @@ -2643,6 +2678,54 @@ public void setPass(final @Nullable String pass) {
}
}

public static final class Cron {
private @Nullable Long defaultCheckinMargin;
private @Nullable Long defaultMaxRuntime;
private @Nullable String defaultTimezone;
private @Nullable Long defaultFailureIssueThreshold;
private @Nullable Long defaultRecoveryThreshold;

public @Nullable Long getDefaultCheckinMargin() {
return defaultCheckinMargin;
}

public void setDefaultCheckinMargin(@Nullable Long defaultCheckinMargin) {
this.defaultCheckinMargin = defaultCheckinMargin;
}

public @Nullable Long getDefaultMaxRuntime() {
return defaultMaxRuntime;
}

public void setDefaultMaxRuntime(@Nullable Long defaultMaxRuntime) {
this.defaultMaxRuntime = defaultMaxRuntime;
}

public @Nullable String getDefaultTimezone() {
return defaultTimezone;
}

public void setDefaultTimezone(@Nullable String defaultTimezone) {
this.defaultTimezone = defaultTimezone;
}

public @Nullable Long getDefaultFailureIssueThreshold() {
return defaultFailureIssueThreshold;
}

public void setDefaultFailureIssueThreshold(@Nullable Long defaultFailureIssueThreshold) {
this.defaultFailureIssueThreshold = defaultFailureIssueThreshold;
}

public @Nullable Long getDefaultRecoveryThreshold() {
return defaultRecoveryThreshold;
}

public void setDefaultRecoveryThreshold(@Nullable Long defaultRecoveryThreshold) {
this.defaultRecoveryThreshold = defaultRecoveryThreshold;
}
}

public enum RequestSize {
NONE,
SMALL,
Expand Down
11 changes: 11 additions & 0 deletions sentry/src/test/java/io/sentry/ExternalOptionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ class ExternalOptionsTest {
}
}

@Test
fun `creates options with cron defaults`() {
withPropertiesFile(listOf("cron.default-checkin-margin=1", "cron.default-max-runtime=30", "cron.default-timezone=America/New_York", "cron.default-failure-issue-threshold=40", "cron.default-recovery-threshold=50")) { options ->
assertEquals(1L, options.cron?.defaultCheckinMargin)
assertEquals(30L, options.cron?.defaultMaxRuntime)
assertEquals("America/New_York", options.cron?.defaultTimezone)
assertEquals(40L, options.cron?.defaultFailureIssueThreshold)
assertEquals(50L, options.cron?.defaultRecoveryThreshold)
}
}

private fun withPropertiesFile(textLines: List<String> = emptyList(), logger: ILogger = mock(), fn: (ExternalOptions) -> Unit) {
// create a sentry.properties file in temporary folder
val temporaryFolder = TemporaryFolder()
Expand Down
Loading

0 comments on commit a816b3f

Please sign in to comment.