Skip to content

Commit 48e97fb

Browse files
adinauerclaude
andauthored
feat(core): Remove Logs and Metrics enable flags (#5939)
* collection: logs and metrics enable flags * feat(logback): Add Logs opt-in Require an explicit Logback appender opt-in before forwarding records as Sentry Logs. Keep event and breadcrumb capture independent while the aggregate core Logs flag remains in place. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(log4j2): Add Logs opt-in Require an explicit Log4j2 appender opt-in before forwarding records as Sentry Logs. Preserve existing constructors and factory methods with Logs disabled by default while keeping events and breadcrumbs unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(jul): Add Logs opt-in Require an explicit JUL handler opt-in before forwarding records as Sentry Logs. Support Java and LogManager configuration while keeping event and breadcrumb capture unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(android): Add Timber Logs opt-in Require an explicit Timber-local opt-in before forwarding Timber messages as Sentry Logs. Add Android options and manifest configuration for auto-installed integrations while preserving event and breadcrumb capture. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(android): Add Logcat Logs opt-in Require an explicit Android option before forwarding Logcat calls as Sentry Logs. Support Java and manifest configuration while keeping breadcrumbs and Android Log calls unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(spring): Add logging Logs opt-in Add a Spring Boot logging property that controls Sentry Logs forwarding from auto-configured Logback appenders. Keep appender installation, events, and breadcrumbs independent from the new opt-in. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(core): Remove Logs enable flag Capture manual Sentry Logs without an aggregate enable option and always create the configured logger batch processor. Keep automatic logging integrations controlled by their local opt-ins and remove legacy Logs configuration from active samples and fixtures. Co-Authored-By: Claude <noreply@anthropic.com> * changelog * feat(android): Warn for legacy Logs metadata Detect explicit io.sentry.logs.enabled Android manifest metadata and emit tailored migration warnings without changing the integration-local Logs options. Co-Authored-By: Claude <noreply@anthropic.com> * feat(core): Warn for legacy Logs configuration Keep parsing the nullable logs.enabled external option and emit tailored migration warnings for explicit true and false values without changing manual Logs capture. Co-Authored-By: Claude <noreply@anthropic.com> * feat(spring): Warn for legacy Logs property Inspect the Spring Environment before SDK initialization and emit tailored migration warnings for explicit sentry.logs.enabled values without binding or applying the obsolete property. Co-Authored-By: Claude <noreply@anthropic.com> * perf(core): Avoid unused Logs worker thread Track whether the logger batch processor has accepted an item and skip empty flush and restart-close scheduling until then. This prevents SDK initialization and Android background callbacks from starting a worker thread when Logs are unused. Co-Authored-By: Claude <noreply@anthropic.com> * feat(core): Remove Metrics enable flag Capture manual Metrics without an aggregate option and always create the configured batch processor. Keep legacy external and Android keys only for subsequent migration warnings. Co-Authored-By: Claude <noreply@anthropic.com> * feat(android): Warn for legacy Metrics metadata Detect explicit io.sentry.metrics.enabled manifest values and emit tailored migration warnings without applying the obsolete option. Co-Authored-By: Claude <noreply@anthropic.com> * feat(core): Warn for legacy Metrics configuration Emit tailored migration warnings for explicit metrics.enabled values while preserving manual Metrics capture regardless of the obsolete setting. Co-Authored-By: Claude <noreply@anthropic.com> * feat(spring): Warn for legacy Metrics property Inspect the Spring Environment before SDK initialization and emit tailored migration warnings for explicit sentry.metrics.enabled values without binding or applying the obsolete property. Co-Authored-By: Claude <noreply@anthropic.com> * perf(core): Start Metrics batch worker on first use Avoid scheduling Metrics processor work for empty flush and close operations until the processor accepts its first item. Preserve existing batching, restart, and Android background behavior after first use. Co-Authored-By: Claude <noreply@anthropic.com> * fix(jul): Preserve null-message events and breadcrumbs Skip only Sentry Logs conversion when a valid JUL record has no message, allowing its event and breadcrumb capture paths to continue. Co-Authored-By: Claude <noreply@anthropic.com> * fix(samples): Remove obsolete Logback Logs option Keep the integration-local enableLogs setting while removing the aggregate Logs configuration that no longer exists. Co-Authored-By: Claude <noreply@anthropic.com> * fix(core): Keep Metrics test constructor internal Use package visibility for executor injection so the test-only constructor does not expand the published API. Co-Authored-By: Claude <noreply@anthropic.com> * docs: Update options guidance for Logs and Metrics Document always-available deliberate APIs, source-local automatic Logs opt-ins, and warning-only handling of obsolete aggregate settings. Co-Authored-By: Claude <noreply@anthropic.com> * fix(android): Read Timber Logs option after configuration Resolve the auto-installed Timber integration's Logs opt-in lazily when the integration registers. This honors programmatic configuration and manifest overrides applied after default integrations are constructed. Co-Authored-By: Claude <noreply@anthropic.com> * fix(spring): Warn after SDK initialization Emit legacy Logs property diagnostics after Sentry.init so the configured diagnostic logger is available. Co-Authored-By: Claude <noreply@anthropic.com> * fix(core): Make enable-flag warnings visible Initialize the fatal logger before external configuration is merged and route legacy Logs and Metrics migration warnings through the always-visible startup logger across core, Android, and Spring Boot. Co-Authored-By: Claude <noreply@anthropic.com> * ref(logging): Rename Logs opt-ins Use state-oriented names for the new Logback, Log4j2, JUL, Timber, Logcat, and Spring Boot Logs controls. Expose get...Enabled accessors so Java-defined options map to natural Kotlin properties before these APIs are released. Co-Authored-By: Claude <noreply@anthropic.com> * fix(android): Use manifest metadata lookup helper Keep legacy Logs metadata detection compatible with both Android bundles and injected metadata maps after merging the v9 branch. * fix(android): Use metadata helper for legacy Metrics option Keep legacy Metrics metadata detection compatible with both Android bundles and injected metadata maps after merging the v9 branch. * ref(core): Remove legacy Logs warning inputs Remove obsolete external and Android manifest parsing retained only for migration warnings that will not ship in v9. Co-Authored-By: Claude <noreply@anthropic.com> * ref(android): Remove legacy Logs metadata warnings Drop the warning-only behavior so the PR is neutral before removal from the v9 stack. Co-Authored-By: Claude <noreply@anthropic.com> * ref(core): Remove legacy Logs configuration warnings Drop the warning-only behavior so the PR is neutral before removal from the v9 stack. Co-Authored-By: Claude <noreply@anthropic.com> * ref(spring): Remove legacy Logs property warnings Drop the warning-only behavior so the PR is neutral before removal from the v9 stack. Co-Authored-By: Claude <noreply@anthropic.com> * ref(core): Remove legacy Metrics warning inputs Remove obsolete external and Android manifest parsing retained only for migration warnings that will not ship in v9. Co-Authored-By: Claude <noreply@anthropic.com> * docs: Remove legacy enable-flag warning guidance Document the removed aggregate options without retaining warning-only migration behavior. Co-Authored-By: Claude <noreply@anthropic.com> * test(logback): Use renamed Logs option Update the remaining fixture call to use logsEnabled so the renamed API compiles. Co-Authored-By: Claude <noreply@anthropic.com> * fix(spring): Forward Logs option to Log4j2 appender Pass the Spring logging Logs opt-in to auto-configured Log4j2 appenders in the Jakarta and Spring Boot 4 integrations. Keep automatic Logs disabled unless the property is explicitly enabled. Co-Authored-By: Claude <noreply@anthropic.com> * fix(spring): Use renamed Logs option in Log4j2 wiring Keep the newly added Log4j2 auto-configuration wiring aligned with the logsEnabled accessor and Spring property introduced by this branch. Co-Authored-By: Claude <noreply@anthropic.com> * fix(jul): Handle null messages with resource bundles Skip resource-bundle lookup and message formatting when a JUL record has no message. Preserve event and breadcrumb capture instead of aborting with a null-pointer exception. Co-Authored-By: Claude <noreply@anthropic.com> * test(jul): Use renamed Logs option in regression test Keep the null-message resource-bundle regression test aligned with the logsEnabled fixture option introduced by this branch. Co-Authored-By: Claude <noreply@anthropic.com> * docs(options): Clarify conditional signal options State that options such as sampling should only be added when the signal supports them. Avoid implying that Logs and Metrics currently expose sampling controls. Co-Authored-By: Claude <noreply@anthropic.com> * fix(timber): Keep lazy logs constructor internal Hide the lazy evaluator constructor from the supported Kotlin API while retaining Java access for Android integration wiring. Use a lambda instead of a method reference for compatibility with older Android Gradle plugins. Co-Authored-By: Claude <noreply@anthropic.com> * ref(android): Clarify automatic log capture option names Rename the Timber and Logcat options to make it explicit that they control capture into Sentry rather than output to those logging systems. Keep natural property syntax for Kotlin callers and align tests and guidance with the new names. Co-Authored-By: Claude <noreply@anthropic.com> * ref(logging)!: Add opt-in flags to existing constructors Add the Logs opt-in directly to the existing Log4j2 and Timber constructor signatures instead of retaining compatibility overloads. Document the intentional v9 API changes in the changelog. BREAKING CHANGE: Log4j2 and Timber callers using explicit constructor signatures must pass the new Logs opt-in argument. Co-Authored-By: Claude <noreply@anthropic.com> * fix(samples): Use Spring logging Logs option Keep structured Logs enabled in the Spring Boot Log4j2 samples after removing the aggregate Logs configuration. Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): Clarify Logs and Metrics migration Classify removal of the aggregate options as breaking changes and list the source-specific opt-ins for automatic Logs capture. Co-Authored-By: Claude <noreply@anthropic.com> * ref(timber)!: Require explicit Logs opt-in Replace the no-argument SentryTimberIntegration constructor with a boolean overload so manually installed integrations must choose whether to forward Sentry Logs. Keep the lazy evaluator path for auto-installed integrations and clarify the separate Android option and constructor configuration paths. BREAKING CHANGE: SentryTimberIntegration() now requires a logsEnabled argument. Co-Authored-By: Claude <noreply@anthropic.com> * ref(logging): Remove unused no-op Logs processor Remove the internal no-op batch processor now that SentryClient always creates the configured Logs processor and no SDK path selects the stub. Co-Authored-By: Claude <noreply@anthropic.com> * ref(metrics): Remove unused no-op batch processor Remove the internal no-op batch processor now that SentryClient always creates the configured Metrics processor and no SDK path selects the stub. Co-Authored-By: Claude <noreply@anthropic.com> * ref(log4j2)!: Remove deprecated appender constructor Remove the constructor superseded by the minimumLevel overload in 8.16.0 at the v9 breaking-change boundary. Co-Authored-By: Claude <noreply@anthropic.com> * ref(android): Align log capture manifest option names Rename the Timber and Logcat manifest options to describe Sentry's log capture direction consistently with their Android option accessors. Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): Name Logs integration opt-ins List the exact option, property, attribute, and manifest names for every logging integration so users can enable the intended source after upgrading. Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): Consolidate Logs migration guidance Lead with removal of the aggregate Logs and Metrics flags, list every source-local Logs opt-in, and keep constructor migrations as secondary details. Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): Prioritize Spring Boot Logs opt-in List the Spring Boot logging property first among the source-local Logs controls. Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): Link Logs flags collection PR Reference the collection PR from the consolidated breaking-change entry. Co-Authored-By: Claude <noreply@anthropic.com> * docs(changelog): Clarify removed telemetry options List every configuration surface affected by the aggregate Logs and Metrics option removal and structure the migration guidance clearly. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent ff64ada commit 48e97fb

86 files changed

Lines changed: 1226 additions & 520 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.cursor/rules/options.mdc‎

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@ description: Adding and modifying SDK options
44
---
55
# Adding Options to the SDK
66

7-
New features must be **opt-in by default**. Options control whether a feature is enabled and how it behaves.
7+
New automatic capture features must be **opt-in by default**. Deliberate API calls such as
8+
`Sentry.logger()` and `Sentry.metrics()` capture whenever the SDK is enabled and do not have
9+
aggregate signal enable flags. Options control signal behavior and whether individual automatic
10+
sources are enabled.
811

912
## Namespaced Options
1013

1114
Newer features use namespaced option classes nested inside `SentryOptions`, e.g.:
1215
- `SentryOptions.getLogs()` → `SentryOptions.Logs`
1316
- `SentryOptions.getMetrics()` → `SentryOptions.Metrics`
1417

15-
Each namespaced options class is a `public static final class` inside `SentryOptions` with its own fields, getters/setters, and callbacks (e.g. `BeforeSendLogCallback`, `BeforeSendMetricCallback`).
18+
Each namespaced options class is a `public static final class` inside `SentryOptions` with its own fields, getters/setters, factories, and callbacks (e.g. `BeforeSendLogCallback`, `BeforeSendMetricCallback`).
1619

17-
A typical namespaced options class contains:
18-
- `enabled` boolean (default `false` for opt-in)
19-
- `sampleRate` double (if the feature supports sampling)
20-
- `beforeSend` callback interface (nested inside the options class)
20+
Do not assume that a namespaced signal needs an aggregate `enabled` field. In particular, Logs and
21+
Metrics are available through deliberate API calls whenever the SDK is enabled. Their namespaced
22+
options contain signal-specific behavior such as `beforeSend`, limits, and processor factories. Add
23+
options such as sampling only when the signal supports them. Automatic capture integrations use
24+
source-local enable options that default to `false`.
2125

2226
To add a new namespaced options class:
2327
1. Create the `public static final class` inside `SentryOptions` with fields, getters/setters, and any callback interfaces
@@ -47,21 +51,18 @@ The core options class. Add the field (or nested class) with getter/setter here.
4751
Allows setting options via `sentry.properties` file or system properties. Fields use nullable wrapper types (`@Nullable Boolean`, `@Nullable Double`) since unset means "don't override the default."
4852

4953
**File:** `sentry/src/main/java/io/sentry/ExternalOptions.java`
50-
- Add `@Nullable` fields with getter/setter for each externally configurable option (e.g. `enableMetrics`, `logsSampleRate`)
51-
- Wire them in the static `from(PropertiesProvider)` method:
52-
- Boolean: `propertiesProvider.getBooleanProperty("metrics.enabled")`
53-
- Double: `propertiesProvider.getDoubleProperty("logs.sample-rate")`
54+
- Add `@Nullable` fields with getter/setter for each externally configurable option (e.g. `logsSampleRate`)
55+
- Wire them in the static `from(PropertiesProvider)` method, for example:
56+
`propertiesProvider.getDoubleProperty("logs.sample-rate")`
5457

5558
**File:** `sentry/src/main/java/io/sentry/SentryOptions.java` — `merge()` method
5659
- Add null-check blocks to apply each external option onto the namespaced options class:
5760
```java
58-
if (options.isEnableMetrics() != null) {
59-
getMetrics().setEnabled(options.isEnableMetrics());
60-
}
6161
if (options.getLogsSampleRate() != null) {
6262
getLogs().setSampleRate(options.getLogsSampleRate());
6363
}
6464
```
65+
- Do not add or restore `logs.enabled` or `metrics.enabled`; these aggregate options are obsolete.
6566

6667
**Tests:**
6768
- `sentry/src/test/java/io/sentry/ExternalOptionsTest.kt` — test true/false/null for booleans, valid values and null for doubles
@@ -72,9 +73,12 @@ Allows setting options via `sentry.properties` file or system properties. Fields
7273
Allows setting options via `AndroidManifest.xml` `<meta-data>` tags.
7374

7475
**File:** `sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java`
75-
- Add a `static final String` constant for the key (e.g. `"io.sentry.metrics.enabled"`)
76+
- Add a `static final String` constant for the key
7677
- Read it in `applyMetadata()` using `readBool(metadata, logger, CONSTANT, defaultValue)`
77-
- Apply to the namespaced options, e.g. `options.getMetrics().setEnabled(...)`
78+
- Apply automatic-source options directly, for example
79+
`options.setLogcatLogCaptureEnabled(...)` for `io.sentry.logcat.log-capture.enabled`
80+
- Do not add or restore `io.sentry.logs.enabled` or `io.sentry.metrics.enabled`; those aggregate
81+
keys are obsolete.
7882

7983
**Tests:** `sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt`
8084
- Test default value preserved when not in manifest
@@ -83,21 +87,37 @@ Allows setting options via `AndroidManifest.xml` `<meta-data>` tags.
8387

8488
### 4. Spring Boot Properties (Spring Boot only)
8589

86-
`SentryProperties` extends `SentryOptions`, so namespaced options (nested classes) are automatically available as Spring Boot properties without extra code. For example, `SentryOptions.Logs` is automatically mapped to `sentry.logs.enabled` in `application.properties`.
90+
`SentryProperties` extends `SentryOptions`, so bindable namespaced behavior options are available
91+
through the `SentryOptions` class hierarchy. Spring-owned integration controls belong to a Spring
92+
namespace instead. For example, `SentryProperties.Logging.logsEnabled` binds to
93+
`sentry.logging.logs-enabled` and controls Logs forwarding from the auto-configured Logback
94+
appender. `sentry.logging.enabled` separately controls whether that appender is installed.
8795

88-
No additional code is needed for namespaced options — Spring Boot auto-configuration handles this via property binding on the `SentryOptions` class hierarchy.
96+
Do not add or restore `sentry.logs.enabled` or `sentry.metrics.enabled`; those aggregate properties
97+
are obsolete.
8998

9099
**Tests:** `sentry-spring-boot*/src/test/kotlin/.../SentryAutoConfigurationTest.kt`
91-
- Add the property (e.g. `"sentry.logs.enabled=true"`) to the existing `resolves all properties` test
100+
- Add the new property to the existing binding test
92101
- Assert the value is set on the resolved `SentryProperties` bean
102+
- Test default, explicit `true`, explicit `false`, and propagation into the owning integration
93103
- There are three Spring Boot modules with separate test files: `sentry-spring-boot`, `sentry-spring-boot-jakarta`, `sentry-spring-boot-4`
94104

95105
### 5. Reading Options at Runtime
96106

97-
Features check their options at usage time. For namespaced features the check typically happens in the feature's API class (e.g. `LoggerApi`, `MetricsApi`):
98-
- Check `options.getLogs().isEnabled()` early and return if disabled
99-
- Apply sampling via `options.getLogs().getSampleRate()` if applicable
100-
- Apply `beforeSend` callback in `SentryClient` before sending
107+
Deliberate APIs such as `LoggerApi` and `MetricsApi` do not check aggregate signal enable flags.
108+
They capture whenever their scopes are enabled, then apply signal behavior such as sampling and
109+
`beforeSend`.
110+
111+
Automatic integrations must check their source-local opt-in without affecting their existing event
112+
or breadcrumb paths. Current Logs controls are:
113+
- Logback: appender `logsEnabled`
114+
- Log4j2: appender `logsEnabled`
115+
- JUL: handler `logsEnabled`
116+
- Spring Boot Logback: `sentry.logging.logs-enabled`
117+
- Timber: `timberLogCaptureEnabled` / `io.sentry.timber.log-capture.enabled`
118+
- Logcat: `logcatLogCaptureEnabled` / `io.sentry.logcat.log-capture.enabled`
119+
120+
All source-local options default to `false` and gate only Sentry Logs forwarding.
101121

102122
When a feature has its own capture path (e.g. `captureLog`), the relevant classes are:
103123
- `ISentryClient` — add the capture method signature
@@ -106,10 +126,11 @@ When a feature has its own capture path (e.g. `captureLog`), the relevant classe
106126

107127
## Checklist for Adding a New Namespaced Option
108128

109-
1. `SentryOptions.java` — nested options class + getter/setter on `SentryOptions`
110-
2. `ExternalOptions.java` — `@Nullable` fields + wiring in `from()`
111-
3. `SentryOptions.java` `merge()` — apply external options to namespaced class
112-
4. `ManifestMetadataReader.java` — Android manifest support (if Android-relevant)
113-
5. `SentryAutoConfigurationTest.kt` — Spring Boot property binding tests (all three Spring Boot modules)
114-
6. Tests for all of the above (`SentryOptionsTest`, `ExternalOptionsTest`, `ManifestMetadataReaderTest`)
115-
7. Run `./gradlew apiDump` — the nested class and its methods appear in `sentry.api`
129+
1. Decide whether the option controls deliberate API behavior or an automatic capture source
130+
2. `SentryOptions.java` — nested behavior option + getter/setter where core ownership is appropriate
131+
3. `ExternalOptions.java` and `SentryOptions.merge()` — add external support if applicable
132+
4. `ManifestMetadataReader.java` — add Android support if applicable
133+
5. Spring properties — use the owning integration namespace and test all three Spring Boot modules
134+
6. Test defaults and every supported configuration layer
135+
7. Verify automatic-source opt-ins default to `false` and do not gate events or breadcrumbs
136+
8. Run `./gradlew spotlessApply apiDump`

‎CHANGELOG.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@
44

55
### Breaking Changes
66

7+
- Remove the aggregate Sentry Logs and Metrics enable options from all configuration surfaces:
8+
- Java API: `options.getLogs().setEnabled(...)` and `options.getMetrics().setEnabled(...)`
9+
- Properties files: `logs.enabled` and `metrics.enabled`
10+
- Environment variables: `SENTRY_LOGS_ENABLED` and `SENTRY_METRICS_ENABLED`
11+
- JVM system properties and Spring Boot: `sentry.logs.enabled` and `sentry.metrics.enabled`
12+
- Android manifest metadata: `io.sentry.logs.enabled` and `io.sentry.metrics.enabled`
13+
14+
The Java accessors are removed. Values supplied through the other configuration surfaces no
15+
longer affect capture.
16+
([#5939](https://github.com/getsentry/sentry-java/pull/5939),
17+
[#5947](https://github.com/getsentry/sentry-java/pull/5947),
18+
[#5953](https://github.com/getsentry/sentry-java/pull/5953))
19+
- **Automatic Logs capture:** Disabled by default. Enable it separately for each integration:
20+
- Spring Boot logging auto-configuration: `sentry.logging.logs-enabled`
21+
([#5946](https://github.com/getsentry/sentry-java/pull/5946))
22+
- Logback appender: `logsEnabled` ([#5940](https://github.com/getsentry/sentry-java/pull/5940))
23+
- Log4j2 appender: `logsEnabled` ([#5941](https://github.com/getsentry/sentry-java/pull/5941))
24+
- JUL handler: `logsEnabled` or `io.sentry.jul.SentryHandler.logsEnabled`
25+
([#5942](https://github.com/getsentry/sentry-java/pull/5942))
26+
- Auto-installed Timber integration: `timberLogCaptureEnabled` or
27+
`io.sentry.timber.log-capture.enabled` manifest metadata
28+
([#5943](https://github.com/getsentry/sentry-java/pull/5943))
29+
- Manually installed Timber integration or tree: `logsEnabled`
30+
([#5943](https://github.com/getsentry/sentry-java/pull/5943))
31+
- Logcat: `logcatLogCaptureEnabled` or `io.sentry.logcat.log-capture.enabled` manifest metadata
32+
([#5945](https://github.com/getsentry/sentry-java/pull/5945))
33+
- **Constructor migrations:**
34+
- The remaining Log4j2 `SentryAppender` constructor and `createAppender` factory require a
35+
`logsEnabled` argument. The deprecated constructor without `minimumLevel` is removed.
36+
- Manually constructed `SentryTimberIntegration` and `SentryTimberTree` instances require a
37+
`logsEnabled` argument. Pass `false` to keep Sentry Logs disabled.
738
- Remove the Apache HttpClient transport and stop publishing `sentry-apache-http-client-5` ([#6214](https://github.com/getsentry/sentry-java/pull/6214))
839

940
### Features

‎sentry-android-core/api/sentry-android-core.api‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,14 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
429429
public fun getBeforeViewHierarchyCaptureCallback ()Lio/sentry/android/core/SentryAndroidOptions$BeforeCaptureCallback;
430430
public fun getDebugImagesLoader ()Lio/sentry/android/core/IDebugImagesLoader;
431431
public fun getFrameMetricsCollector ()Lio/sentry/android/core/internal/util/SentryFrameMetricsCollector;
432+
public fun getLogcatLogCaptureEnabled ()Z
432433
public fun getMonotonicTicker ()Lio/sentry/time/MonotonicTicker;
433434
public fun getNativeSdkName ()Ljava/lang/String;
434435
public fun getNdkAppHangTimeoutIntervalMillis ()J
435436
public fun getNdkHandlerStrategy ()I
436437
public fun getScreenshot ()Lio/sentry/android/core/SentryScreenshotOptions;
437438
public fun getStartupCrashDurationThresholdMillis ()J
439+
public fun getTimberLogCaptureEnabled ()Z
438440
public fun getTombstoneMergeTimeThresholdMillis ()J
439441
public fun isAnrEnabled ()Z
440442
public fun isAnrProfilingEnabled ()Z
@@ -498,13 +500,15 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
498500
public fun setEnableSystemEventBreadcrumbs (Z)V
499501
public fun setEnableSystemEventBreadcrumbsExtras (Z)V
500502
public fun setFrameMetricsCollector (Lio/sentry/android/core/internal/util/SentryFrameMetricsCollector;)V
503+
public fun setLogcatLogCaptureEnabled (Z)V
501504
public fun setMemoryLimiterEnabled (Z)V
502505
public fun setNativeHandlerStrategy (Lio/sentry/android/core/NdkHandlerStrategy;)V
503506
public fun setNativeSdkName (Ljava/lang/String;)V
504507
public fun setNdkAppHangTimeoutIntervalMillis (J)V
505508
public fun setReportHistoricalAnrs (Z)V
506509
public fun setReportHistoricalMemoryLimiterExits (Z)V
507510
public fun setReportHistoricalTombstones (Z)V
511+
public fun setTimberLogCaptureEnabled (Z)V
508512
public fun setTombstoneEnabled (Z)V
509513
public fun setTombstoneMergeTimeThresholdMillis (J)V
510514
}

‎sentry-android-core/build.gradle.kts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ dependencies {
123123
testImplementation(projects.sentrySpotlight)
124124
testImplementation(projects.sentryAndroidFragment)
125125
testImplementation(projects.sentryAndroidTimber)
126+
testImplementation(libs.timber)
126127
testImplementation(projects.sentryAndroidReplay)
127128
testImplementation(projects.sentryCompose)
128129
testImplementation(projects.sentryAndroidNdk)
@@ -133,5 +134,4 @@ dependencies {
133134
testImplementation(libs.androidx.compose.foundation.layout)
134135
testImplementation(libs.androidx.compose.material3)
135136
testRuntimeOnly(libs.androidx.fragment.ktx)
136-
testRuntimeOnly(libs.timber)
137137
}

‎sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ static void installDefaultIntegrations(
479479
}
480480

481481
if (isTimberAvailable) {
482-
options.addIntegration(new SentryTimberIntegration());
482+
options.addIntegration(
483+
new SentryTimberIntegration(() -> options.getTimberLogCaptureEnabled()));
483484
}
484485
options.addIntegration(new AppComponentsBreadcrumbsIntegration(context));
485486
options.addIntegration(new SystemEventsBreadcrumbsIntegration(context));

‎sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ final class ManifestMetadataReader {
192192

193193
static final String IN_APP_EXCLUDES = "io.sentry.in-app-excludes";
194194

195-
static final String ENABLE_LOGS = "io.sentry.logs.enabled";
195+
static final String TIMBER_LOG_CAPTURE_ENABLED = "io.sentry.timber.log-capture.enabled";
196196

197-
static final String ENABLE_METRICS = "io.sentry.metrics.enabled";
197+
static final String LOGCAT_LOG_CAPTURE_ENABLED = "io.sentry.logcat.log-capture.enabled";
198198

199199
static final String ENABLE_AUTO_TRACE_ID_GENERATION =
200200
"io.sentry.traces.enable-auto-id-generation";
@@ -750,14 +750,19 @@ static void applyMetadata(
750750
}
751751
}
752752

753-
options
754-
.getLogs()
755-
.setEnabled(readBool(metadata, logger, ENABLE_LOGS, options.getLogs().isEnabled()));
753+
options.setTimberLogCaptureEnabled(
754+
readBool(
755+
metadata,
756+
logger,
757+
TIMBER_LOG_CAPTURE_ENABLED,
758+
options.getTimberLogCaptureEnabled()));
756759

757-
options
758-
.getMetrics()
759-
.setEnabled(
760-
readBool(metadata, logger, ENABLE_METRICS, options.getMetrics().isEnabled()));
760+
options.setLogcatLogCaptureEnabled(
761+
readBool(
762+
metadata,
763+
logger,
764+
LOGCAT_LOG_CAPTURE_ENABLED,
765+
options.getLogcatLogCaptureEnabled()));
761766

762767
final @NotNull SentryFeedbackOptions feedbackOptions = options.getFeedbackOptions();
763768
feedbackOptions.setNameRequired(

‎sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroidOptions.java‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ public final class SentryAndroidOptions extends SentryOptions {
7575
/** Enable or disable automatic breadcrumbs for Network Events Using NetworkCallback */
7676
private boolean enableNetworkEventBreadcrumbs = true;
7777

78+
/** Enable or disable automatic Sentry Logs capture from Timber. Default is disabled. */
79+
private boolean timberLogCaptureEnabled = false;
80+
81+
/** Enable or disable automatic Sentry Logs capture from Logcat. Default is disabled. */
82+
private boolean logcatLogCaptureEnabled = false;
83+
7884
/**
7985
* Enables the Auto instrumentation for Activity lifecycle tracing.
8086
*
@@ -505,6 +511,22 @@ public void setEnableNetworkEventBreadcrumbs(boolean enableNetworkEventBreadcrum
505511
this.enableNetworkEventBreadcrumbs = enableNetworkEventBreadcrumbs;
506512
}
507513

514+
public boolean getTimberLogCaptureEnabled() {
515+
return timberLogCaptureEnabled;
516+
}
517+
518+
public void setTimberLogCaptureEnabled(boolean timberLogCaptureEnabled) {
519+
this.timberLogCaptureEnabled = timberLogCaptureEnabled;
520+
}
521+
522+
public boolean getLogcatLogCaptureEnabled() {
523+
return logcatLogCaptureEnabled;
524+
}
525+
526+
public void setLogcatLogCaptureEnabled(boolean logcatLogCaptureEnabled) {
527+
this.logcatLogCaptureEnabled = logcatLogCaptureEnabled;
528+
}
529+
508530
/**
509531
* Enable or disable all the automatic breadcrumbs
510532
*

‎sentry-android-core/src/main/java/io/sentry/android/core/SentryLogcatAdapter.java‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io.sentry.Sentry;
77
import io.sentry.SentryLevel;
88
import io.sentry.SentryLogLevel;
9+
import io.sentry.SentryOptions;
910
import io.sentry.logger.SentryLogParameters;
1011
import org.jetbrains.annotations.ApiStatus;
1112
import org.jetbrains.annotations.NotNull;
@@ -52,8 +53,9 @@ private static void addAsLog(
5253
@Nullable final String msg,
5354
@Nullable final Throwable tr) {
5455
final @NotNull ScopesAdapter scopes = ScopesAdapter.getInstance();
55-
// Check if logs are enabled before doing expensive operations
56-
if (!scopes.getOptions().getLogs().isEnabled()) {
56+
final @NotNull SentryOptions options = scopes.getOptions();
57+
if (!(options instanceof SentryAndroidOptions)
58+
|| !((SentryAndroidOptions) options).getLogcatLogCaptureEnabled()) {
5759
return;
5860
}
5961
final @Nullable String trMessage = tr != null ? tr.getMessage() : null;

‎sentry-android-core/src/test/java/io/sentry/android/core/AndroidLoggerBatchProcessorTest.kt‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package io.sentry.android.core
22

33
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import com.google.common.truth.Truth.assertThat
45
import io.sentry.ISentryClient
56
import io.sentry.ISentryExecutorService
67
import io.sentry.SentryLogEvent
78
import io.sentry.SentryLogLevel
89
import io.sentry.SentryOptions
910
import io.sentry.protocol.SentryId
1011
import io.sentry.test.ImmediateExecutorService
12+
import io.sentry.test.getProperty
13+
import java.util.concurrent.atomic.AtomicBoolean
1114
import kotlin.test.AfterTest
1215
import kotlin.test.BeforeTest
1316
import kotlin.test.Test
@@ -16,6 +19,7 @@ import kotlin.test.assertTrue
1619
import org.junit.runner.RunWith
1720
import org.mockito.kotlin.any
1821
import org.mockito.kotlin.mock
22+
import org.mockito.kotlin.never
1923
import org.mockito.kotlin.verify
2024
import org.mockito.kotlin.verifyNoInteractions
2125
import org.mockito.kotlin.whenever
@@ -57,6 +61,16 @@ class AndroidLoggerBatchProcessorTest {
5761
assertNotNull(AppState.getInstance().lifecycleObserver)
5862
}
5963

64+
@Test
65+
fun `onBackground does not flush before first accepted item`() {
66+
val sut = fixture.getSut(useImmediateExecutor = true)
67+
68+
sut.onBackground()
69+
70+
assertThat(sut.getProperty<AtomicBoolean>("hasScheduled").get()).isFalse()
71+
verify(fixture.client, never()).captureBatchedLogEvents(any())
72+
}
73+
6074
@Test
6175
fun `onBackground schedules flush`() {
6276
val sut = fixture.getSut(useImmediateExecutor = true)

0 commit comments

Comments
 (0)