From fcb80405fbf0cb3dd748af1a50eae9693eed8e52 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 12 Aug 2026 16:55:10 +0200 Subject: [PATCH 1/3] 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 --- .../android/core/ManifestMetadataReader.java | 17 ++++++ .../core/ManifestMetadataReaderTest.kt | 60 ++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java index 3161db3720e..2aa10e98abc 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java @@ -706,6 +706,23 @@ static void applyMetadata( } } + if (metadata.containsKey(ENABLE_LOGS)) { + final boolean enableLogs = readBool(metadata, logger, ENABLE_LOGS, false); + if (enableLogs) { + logger.log( + SentryLevel.WARNING, + "The Android manifest option 'io.sentry.logs.enabled' is no longer supported. " + + "Manual Sentry.logger() calls no longer require it, and automatic logging " + + "integrations now require their own opt-ins."); + } else { + logger.log( + SentryLevel.WARNING, + "The Android manifest option 'io.sentry.logs.enabled' no longer disables manual " + + "Sentry.logger() calls. Automatic logging integrations remain disabled " + + "unless enabled through their own opt-ins."); + } + } + options.setEnableTimberLogs( readBool(metadata, logger, ENABLE_TIMBER_LOGS, options.isEnableTimberLogs())); diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt index b7ea7b962af..6a0b17cff70 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt @@ -29,7 +29,7 @@ import org.mockito.kotlin.verify class ManifestMetadataReaderTest { private class Fixture { val logger = mock() - val options = SentryAndroidOptions().apply { setLogger(logger) } + val options = SentryAndroidOptions().apply { setLogger(this@Fixture.logger) } val buildInfoProvider = mock() fun getContext(metaData: Bundle = Bundle()): Context = @@ -1943,6 +1943,64 @@ class ManifestMetadataReaderTest { assertTrue(fixture.options.inAppExcludes.isEmpty()) } + @Test + fun `applyMetadata does not warn when legacy logs enabled metadata is absent`() { + fixture.options.isDebug = true + val context = fixture.getContext() + + ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider) + + verify(fixture.logger, never()).log(eq(SentryLevel.WARNING), any()) + } + + @Test + fun `applyMetadata warns when legacy logs enabled metadata is true`() { + val bundle = + bundleOf( + ManifestMetadataReader.DEBUG to true, + ManifestMetadataReader.ENABLE_LOGS to true, + ) + val context = fixture.getContext(metaData = bundle) + + ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider) + + verify(fixture.logger) + .log( + SentryLevel.WARNING, + "The Android manifest option 'io.sentry.logs.enabled' is no longer supported. " + + "Manual Sentry.logger() calls no longer require it, and automatic logging " + + "integrations now require their own opt-ins.", + *emptyArray(), + ) + assertThat(fixture.options.isEnableTimberLogs).isFalse() + assertThat(fixture.options.isEnableLogcatLogs).isFalse() + } + + @Test + fun `applyMetadata warns when legacy logs enabled metadata is false`() { + fixture.options.isEnableTimberLogs = true + fixture.options.isEnableLogcatLogs = true + val bundle = + bundleOf( + ManifestMetadataReader.DEBUG to true, + ManifestMetadataReader.ENABLE_LOGS to false, + ) + val context = fixture.getContext(metaData = bundle) + + ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider) + + verify(fixture.logger) + .log( + SentryLevel.WARNING, + "The Android manifest option 'io.sentry.logs.enabled' no longer disables manual " + + "Sentry.logger() calls. Automatic logging integrations remain disabled unless " + + "enabled through their own opt-ins.", + *emptyArray(), + ) + assertThat(fixture.options.isEnableTimberLogs).isTrue() + assertThat(fixture.options.isEnableLogcatLogs).isTrue() + } + @Test fun `applyMetadata keeps Timber logs disabled if not found`() { val context = fixture.getContext() From 56278c84cea565046bc33b50d633c101bd499524 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 29 Sep 2026 16:09:07 +0200 Subject: [PATCH 2/3] 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. --- .../java/io/sentry/android/core/ManifestMetadataReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java index 1b7acc5f8e1..654a40c5c92 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java @@ -754,7 +754,7 @@ static void applyMetadata( } } - if (metadata.containsKey(ENABLE_LOGS)) { + if (containsKey(metadata, ENABLE_LOGS)) { final boolean enableLogs = readBool(metadata, logger, ENABLE_LOGS, false); if (enableLogs) { logger.log( From 3f987ba59bf08d7470c4ecc49765626c57e377a5 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 30 Sep 2026 10:39:02 +0200 Subject: [PATCH 3/3] 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 --- .../android/core/ManifestMetadataReader.java | 17 ------ .../core/ManifestMetadataReaderTest.kt | 60 +------------------ 2 files changed, 1 insertion(+), 76 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java index 36b00f91e6a..2bf1f1827a8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java @@ -752,23 +752,6 @@ static void applyMetadata( } } - if (containsKey(metadata, ENABLE_LOGS)) { - final boolean enableLogs = readBool(metadata, logger, ENABLE_LOGS, false); - if (enableLogs) { - logger.log( - SentryLevel.WARNING, - "The Android manifest option 'io.sentry.logs.enabled' is no longer supported. " - + "Manual Sentry.logger() calls no longer require it, and automatic logging " - + "integrations now require their own opt-ins."); - } else { - logger.log( - SentryLevel.WARNING, - "The Android manifest option 'io.sentry.logs.enabled' no longer disables manual " - + "Sentry.logger() calls. Automatic logging integrations remain disabled " - + "unless enabled through their own opt-ins."); - } - } - options.setEnableTimberLogs( readBool(metadata, logger, ENABLE_TIMBER_LOGS, options.isEnableTimberLogs())); diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt index 0d5ad2b2c62..91a1469702f 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt @@ -33,7 +33,7 @@ import org.mockito.kotlin.verifyNoInteractions class ManifestMetadataReaderTest { private class Fixture { val logger = mock() - val options = SentryAndroidOptions().apply { setLogger(this@Fixture.logger) } + val options = SentryAndroidOptions().apply { setLogger(logger) } val buildInfoProvider = mock() fun getContext(metaData: Bundle = Bundle()): Context = @@ -2175,64 +2175,6 @@ class ManifestMetadataReaderTest { assertTrue(fixture.options.inAppExcludes.isEmpty()) } - @Test - fun `applyMetadata does not warn when legacy logs enabled metadata is absent`() { - fixture.options.isDebug = true - val context = fixture.getContext() - - ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider) - - verify(fixture.logger, never()).log(eq(SentryLevel.WARNING), any()) - } - - @Test - fun `applyMetadata warns when legacy logs enabled metadata is true`() { - val bundle = - bundleOf( - ManifestMetadataReader.DEBUG to true, - ManifestMetadataReader.ENABLE_LOGS to true, - ) - val context = fixture.getContext(metaData = bundle) - - ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider) - - verify(fixture.logger) - .log( - SentryLevel.WARNING, - "The Android manifest option 'io.sentry.logs.enabled' is no longer supported. " + - "Manual Sentry.logger() calls no longer require it, and automatic logging " + - "integrations now require their own opt-ins.", - *emptyArray(), - ) - assertThat(fixture.options.isEnableTimberLogs).isFalse() - assertThat(fixture.options.isEnableLogcatLogs).isFalse() - } - - @Test - fun `applyMetadata warns when legacy logs enabled metadata is false`() { - fixture.options.isEnableTimberLogs = true - fixture.options.isEnableLogcatLogs = true - val bundle = - bundleOf( - ManifestMetadataReader.DEBUG to true, - ManifestMetadataReader.ENABLE_LOGS to false, - ) - val context = fixture.getContext(metaData = bundle) - - ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider) - - verify(fixture.logger) - .log( - SentryLevel.WARNING, - "The Android manifest option 'io.sentry.logs.enabled' no longer disables manual " + - "Sentry.logger() calls. Automatic logging integrations remain disabled unless " + - "enabled through their own opt-ins.", - *emptyArray(), - ) - assertThat(fixture.options.isEnableTimberLogs).isTrue() - assertThat(fixture.options.isEnableLogcatLogs).isTrue() - } - @Test fun `applyMetadata keeps Timber logs disabled if not found`() { val context = fixture.getContext()