diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ee1734f3c..765ef6907b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -### Fixes +### Features - Send Timber logs through Sentry Logs ([#4490](https://github.com/getsentry/sentry-java/pull/4490)) - Enable the Logs feature in your `SentryOptions` or with the `io.sentry.logs.enabled` manifest option and the SDK will automatically send Timber logs to Sentry, if the TimberIntegration is enabled. @@ -10,6 +10,7 @@ - Send logcat through Sentry Logs ([#4487](https://github.com/getsentry/sentry-java/pull/4487)) - Enable the Logs feature in your `SentryOptions` or with the `io.sentry.logs.enabled` manifest option and the SDK will automatically send logcat logs to Sentry, if the Sentry Android Gradle plugin is applied. - To set the logcat level check the [Logcat integration documentation](https://docs.sentry.io/platforms/android/integrations/logcat/#configure). +- Read build tool info from `sentry-debug-meta.properties` and attach it to events ([#4314](https://github.com/getsentry/sentry-java/pull/4314)) ### Dependencies diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 72d0bc1d62..171cd7eaa8 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -6743,7 +6743,10 @@ public abstract interface class io/sentry/util/CollectionUtils$Predicate { public final class io/sentry/util/DebugMetaPropertiesApplier { public static field DEBUG_META_PROPERTIES_FILENAME Ljava/lang/String; public fun ()V + public static fun apply (Lio/sentry/SentryOptions;Ljava/util/List;)V public static fun applyToOptions (Lio/sentry/SentryOptions;Ljava/util/List;)V + public static fun getBuildTool (Ljava/util/Properties;)Ljava/lang/String; + public static fun getBuildToolVersion (Ljava/util/Properties;)Ljava/lang/String; public static fun getProguardUuid (Ljava/util/Properties;)Ljava/lang/String; } diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 1aa03ff304..0596f8f2ff 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -645,7 +645,7 @@ private static void initConfigurations(final @NotNull SentryOptions options) { options.setDebugMetaLoader(new ResourcesDebugMetaLoader(options.getLogger())); } final @Nullable List propertiesList = options.getDebugMetaLoader().loadDebugMeta(); - DebugMetaPropertiesApplier.applyToOptions(options, propertiesList); + DebugMetaPropertiesApplier.apply(options, propertiesList); final IThreadChecker threadChecker = options.getThreadChecker(); // only override the ThreadChecker if it's not already set by Android diff --git a/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java b/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java index 8627845967..236e962682 100644 --- a/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java +++ b/sentry/src/main/java/io/sentry/util/DebugMetaPropertiesApplier.java @@ -1,5 +1,6 @@ package io.sentry.util; +import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryLevel; import io.sentry.SentryOptions; import java.util.List; @@ -11,6 +12,14 @@ public final class DebugMetaPropertiesApplier { public static @NotNull String DEBUG_META_PROPERTIES_FILENAME = "sentry-debug-meta.properties"; + public static void apply( + final @NotNull SentryOptions options, final @Nullable List debugMetaProperties) { + if (debugMetaProperties != null) { + applyToOptions(options, debugMetaProperties); + applyBuildTool(options, debugMetaProperties); + } + } + public static void applyToOptions( final @NotNull SentryOptions options, final @Nullable List debugMetaProperties) { if (debugMetaProperties != null) { @@ -49,7 +58,35 @@ private static void applyProguardUuid( } } + private static void applyBuildTool( + final @NotNull SentryOptions options, @NotNull List debugMetaProperties) { + for (Properties properties : debugMetaProperties) { + final @Nullable String buildTool = getBuildTool(properties); + if (buildTool != null) { + @Nullable String buildToolVersion = getBuildToolVersion(properties); + if (buildToolVersion == null) { + buildToolVersion = "unknown"; + } + options + .getLogger() + .log( + SentryLevel.DEBUG, "Build tool found: %s, version %s", buildTool, buildToolVersion); + SentryIntegrationPackageStorage.getInstance().addPackage(buildTool, buildToolVersion); + break; + } + } + } + public static @Nullable String getProguardUuid(final @NotNull Properties debugMetaProperties) { return debugMetaProperties.getProperty("io.sentry.ProguardUuids"); } + + public static @Nullable String getBuildTool(final @NotNull Properties debugMetaProperties) { + return debugMetaProperties.getProperty("io.sentry.build-tool"); + } + + public static @Nullable String getBuildToolVersion( + final @NotNull Properties debugMetaProperties) { + return debugMetaProperties.getProperty("io.sentry.build-tool-version"); + } } diff --git a/sentry/src/test/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoaderTest.kt b/sentry/src/test/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoaderTest.kt index 22e21c653a..0e77671743 100644 --- a/sentry/src/test/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoaderTest.kt +++ b/sentry/src/test/java/io/sentry/internal/debugmeta/ResourcesDebugMetaLoaderTest.kt @@ -1,13 +1,17 @@ package io.sentry.internal.debugmeta import io.sentry.ILogger +import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions +import io.sentry.protocol.SentryPackage import io.sentry.util.DebugMetaPropertiesApplier import java.net.URL import java.nio.charset.Charset import java.util.Collections import kotlin.test.Test +import kotlin.test.assertContains import kotlin.test.assertEquals +import kotlin.test.assertFalse import kotlin.test.assertNotNull import kotlin.test.assertNull import org.mockito.kotlin.mock @@ -59,7 +63,7 @@ class ResourcesDebugMetaLoaderTest { val options = SentryOptions() - assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.applyToOptions(options, it) } + assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.apply(options, it) } assertEquals(options.bundleIds, setOf("88ba82db-cd26-4c09-8b31-21461d286b68")) assertEquals(options.proguardUuid, "34077988-a0e5-4839-9618-7400e1616d1b") @@ -84,7 +88,7 @@ class ResourcesDebugMetaLoaderTest { val options = SentryOptions() - assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.applyToOptions(options, it) } + assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.apply(options, it) } assertEquals( options.bundleIds, @@ -120,7 +124,7 @@ class ResourcesDebugMetaLoaderTest { val options = SentryOptions() - assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.applyToOptions(options, it) } + assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.apply(options, it) } assertEquals( options.bundleIds, @@ -139,4 +143,79 @@ class ResourcesDebugMetaLoaderTest { assertNull(sut.loadDebugMeta()) } + + @Test + fun `reads build-tool and build-version and adds them to packages`() { + val sut = + fixture.getSut( + content = + listOf( + """ + #Generated by sentry-maven-plugin + #Wed May 17 15:33:34 CEST 2023 + io.sentry.ProguardUuids=34077988-a0e5-4839-9618-7400e1616d1b + io.sentry.bundle-ids=88ba82db-cd26-4c09-8b31-21461d286b68 + io.sentry.build-tool=maven + io.sentry.build-tool-version=1.0 + """ + .trimIndent() + ) + ) + + val options = SentryOptions() + assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.apply(options, it) } + + val expected = SentryPackage("maven", "1.0") + assertContains(SentryIntegrationPackageStorage.getInstance().packages, expected) + } + + @Test + fun `reads build-tool and adds it to packages with unknown version if build-tool-version is absent`() { + val sut = + fixture.getSut( + content = + listOf( + """ + #Generated by sentry-maven-plugin + #Wed May 17 15:33:34 CEST 2023 + io.sentry.ProguardUuids=34077988-a0e5-4839-9618-7400e1616d1b + io.sentry.bundle-ids=88ba82db-cd26-4c09-8b31-21461d286b68 + io.sentry.build-tool=maven + """ + .trimIndent() + ) + ) + + val options = SentryOptions() + assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.apply(options, it) } + + val expected = SentryPackage("maven", "unknown") + assertContains(SentryIntegrationPackageStorage.getInstance().packages, expected) + } + + @Test + fun `does not add build-tool to packages if absent`() { + val sut = + fixture.getSut( + content = + listOf( + """ + #Generated manually + #Wed May 17 15:33:34 CEST 2023 + io.sentry.ProguardUuids=34077988-a0e5-4839-9618-7400e1616d1b + io.sentry.bundle-ids=88ba82db-cd26-4c09-8b31-21461d286b68 + """ + .trimIndent() + ) + ) + + val options = SentryOptions() + assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.apply(options, it) } + + assertFalse { + SentryIntegrationPackageStorage.getInstance().packages.any { + it.name.equals("io.sentry.build-tool") + } + } + } }