From e7d5a48de80600d4ead2e8da260c5aaaaf0624cc Mon Sep 17 00:00:00 2001 From: stefanosiano Date: Wed, 16 Nov 2022 18:07:23 +0100 Subject: [PATCH 1/4] updated profile schema: - replaced versionCode with an empty string - replaced versionName with release string --- .../core/AndroidTransactionProfiler.java | 11 +---- .../java/io/sentry/ProfilingTraceData.java | 48 ++++++------------- .../test/java/io/sentry/JsonSerializerTest.kt | 14 +++--- 3 files changed, 22 insertions(+), 51 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java index 6b3dc74baa..d17d295ef3 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java @@ -55,7 +55,6 @@ final class AndroidTransactionProfiler implements ITransactionProfiler { private final @NotNull SentryAndroidOptions options; private final @NotNull IHub hub; private final @NotNull BuildInfoProvider buildInfoProvider; - private final @Nullable PackageInfo packageInfo; private long transactionStartNanos = 0; private long profileStartCpuMillis = 0; private boolean isInitialized = false; @@ -79,7 +78,6 @@ public AndroidTransactionProfiler( this.hub = Objects.requireNonNull(hub, "Hub is required"); this.buildInfoProvider = Objects.requireNonNull(buildInfoProvider, "The BuildInfoProvider is required."); - this.packageInfo = ContextUtils.getPackageInfo(context, options.getLogger(), buildInfoProvider); } private void init() { @@ -247,14 +245,8 @@ private synchronized void onTransactionFinish( return; } - String versionName = ""; - String versionCode = ""; String totalMem = "0"; ActivityManager.MemoryInfo memInfo = getMemInfo(); - if (packageInfo != null) { - versionName = ContextUtils.getVersionName(packageInfo); - versionCode = ContextUtils.getVersionCode(packageInfo, buildInfoProvider); - } if (memInfo != null) { totalMem = Long.toString(memInfo.totalMem); } @@ -287,8 +279,7 @@ private synchronized void onTransactionFinish( buildInfoProvider.isEmulator(), totalMem, options.getProguardUuid(), - versionName, - versionCode, + options.getRelease(), options.getEnvironment(), isTimeout ? ProfilingTraceData.TRUNCATION_REASON_TIMEOUT diff --git a/sentry/src/main/java/io/sentry/ProfilingTraceData.java b/sentry/src/main/java/io/sentry/ProfilingTraceData.java index 764bb005bc..6c8412f2cd 100644 --- a/sentry/src/main/java/io/sentry/ProfilingTraceData.java +++ b/sentry/src/main/java/io/sentry/ProfilingTraceData.java @@ -28,8 +28,8 @@ public final class ProfilingTraceData implements JsonUnknown, JsonSerializable { // Backgrounded reason is not used, yet, but it's one of the possible values @ApiStatus.Internal public static final String TRUNCATION_REASON_BACKGROUNDED = "backgrounded"; - private @NotNull File traceFile; - private @Nullable Callable> deviceCpuFrequenciesReader; + private final @NotNull File traceFile; + private final @Nullable Callable> deviceCpuFrequenciesReader; // Device metadata private int androidApiLevel; @@ -47,14 +47,13 @@ public final class ProfilingTraceData implements JsonUnknown, JsonSerializable { private @NotNull String buildId; // Transaction info - private @NotNull List transactions; + private final @NotNull List transactions; private @NotNull String transactionName; // duration_ns is a String to avoid issues with numbers and json private @NotNull String durationNs; // App info - private @NotNull String versionName; - private @NotNull String versionCode; + private @NotNull String release; // Stacktrace context private @NotNull String transactionId; @@ -89,7 +88,6 @@ public ProfilingTraceData(@NotNull File traceFile, @NotNull ITransaction transac null, null, null, - null, TRUNCATION_REASON_NORMAL); } @@ -107,8 +105,7 @@ public ProfilingTraceData( @Nullable Boolean deviceIsEmulator, @Nullable String devicePhysicalMemoryBytes, @Nullable String buildId, - @Nullable String versionName, - @Nullable String versionCode, + @Nullable String release, @Nullable String environment, @NotNull String truncationReason) { this.traceFile = traceFile; @@ -135,8 +132,7 @@ public ProfilingTraceData( this.durationNs = durationNanos; // App info - this.versionName = versionName != null ? versionName : ""; - this.versionCode = versionCode != null ? versionCode : ""; + this.release = release != null ? release : ""; // Stacktrace context this.transactionId = transaction.getEventId().toString(); @@ -209,12 +205,8 @@ public boolean isDeviceIsEmulator() { return transactionName; } - public @NotNull String getVersionName() { - return versionName; - } - - public @NotNull String getVersionCode() { - return versionCode; + public @NotNull String getRelease() { + return release; } public @NotNull String getTransactionId() { @@ -309,12 +301,8 @@ public void setDurationNs(@NotNull String durationNs) { this.durationNs = durationNs; } - public void setVersionName(@NotNull String versionName) { - this.versionName = versionName; - } - - public void setVersionCode(@NotNull String versionCode) { - this.versionCode = versionCode; + public void setRelease(@NotNull String release) { + this.release = release; } public void setTransactionId(@NotNull String transactionId) { @@ -365,7 +353,7 @@ public static final class JsonKeys { public static final String BUILD_ID = "build_id"; public static final String TRANSACTION_NAME = "transaction_name"; public static final String DURATION_NS = "duration_ns"; - public static final String VERSION_NAME = "version_name"; + public static final String RELEASE = "version_name"; public static final String VERSION_CODE = "version_code"; public static final String TRANSACTION_LIST = "transactions"; public static final String TRANSACTION_ID = "transaction_id"; @@ -396,8 +384,8 @@ public void serialize(@NotNull JsonObjectWriter writer, @NotNull ILogger logger) writer.name(JsonKeys.BUILD_ID).value(buildId); writer.name(JsonKeys.TRANSACTION_NAME).value(transactionName); writer.name(JsonKeys.DURATION_NS).value(durationNs); - writer.name(JsonKeys.VERSION_NAME).value(versionName); - writer.name(JsonKeys.VERSION_CODE).value(versionCode); + writer.name(JsonKeys.RELEASE).value(release); + writer.name(JsonKeys.VERSION_CODE).value(""); if (!transactions.isEmpty()) { writer.name(JsonKeys.TRANSACTION_LIST).value(logger, transactions); } @@ -533,16 +521,10 @@ public static final class Deserializer implements JsonDeserializer Date: Wed, 16 Nov 2022 18:12:00 +0100 Subject: [PATCH 2/4] added test --- .../core/AndroidTransactionProfilerTest.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt index bbdc8dc525..93211fb232 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt @@ -328,4 +328,19 @@ class AndroidTransactionProfilerTest { } ) } + + @Test + fun `profiling trace data contains release field`() { + val profiler = fixture.getSut(context) + profiler.onTransactionStart(fixture.transaction1) + profiler.onTransactionFinish(fixture.transaction1) + verify(fixture.hub).captureEnvelope( + check { + assertEnvelopeItem(it.items.toList()) { _, item -> + assertEquals(fixture.options.release, item.release) + assertNotNull(item.release) + } + } + ) + } } From 3db4965001b8d0cec85be12813a55f6c23518644 Mon Sep 17 00:00:00 2001 From: stefanosiano Date: Wed, 16 Nov 2022 18:30:46 +0100 Subject: [PATCH 3/4] added test --- .../android/core/AndroidTransactionProfiler.java | 1 - sentry/api/sentry.api | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java index d17d295ef3..a96ed16780 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java @@ -6,7 +6,6 @@ import android.annotation.SuppressLint; import android.app.ActivityManager; import android.content.Context; -import android.content.pm.PackageInfo; import android.os.Build; import android.os.Debug; import android.os.Process; diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 857fa457af..afff5cf0b4 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -812,7 +812,7 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public static final field TRUNCATION_REASON_NORMAL Ljava/lang/String; public static final field TRUNCATION_REASON_TIMEOUT Ljava/lang/String; public fun (Ljava/io/File;Lio/sentry/ITransaction;)V - public fun (Ljava/io/File;Ljava/util/List;Lio/sentry/ITransaction;Ljava/lang/String;ILjava/lang/String;Ljava/util/concurrent/Callable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public fun (Ljava/io/File;Ljava/util/List;Lio/sentry/ITransaction;Ljava/lang/String;ILjava/lang/String;Ljava/util/concurrent/Callable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V public fun getAndroidApiLevel ()I public fun getBuildId ()Ljava/lang/String; public fun getCpuArchitecture ()Ljava/lang/String; @@ -828,6 +828,7 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public fun getEnvironment ()Ljava/lang/String; public fun getPlatform ()Ljava/lang/String; public fun getProfileId ()Ljava/lang/String; + public fun getRelease ()Ljava/lang/String; public fun getSampledProfile ()Ljava/lang/String; public fun getTraceFile ()Ljava/io/File; public fun getTraceId ()Ljava/lang/String; @@ -836,8 +837,6 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public fun getTransactions ()Ljava/util/List; public fun getTruncationReason ()Ljava/lang/String; public fun getUnknown ()Ljava/util/Map; - public fun getVersionCode ()Ljava/lang/String; - public fun getVersionName ()Ljava/lang/String; public fun isDeviceIsEmulator ()Z public fun readDeviceCpuFrequencies ()V public fun serialize (Lio/sentry/JsonObjectWriter;Lio/sentry/ILogger;)V @@ -855,13 +854,12 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public fun setDurationNs (Ljava/lang/String;)V public fun setEnvironment (Ljava/lang/String;)V public fun setProfileId (Ljava/lang/String;)V + public fun setRelease (Ljava/lang/String;)V public fun setSampledProfile (Ljava/lang/String;)V public fun setTraceId (Ljava/lang/String;)V public fun setTransactionId (Ljava/lang/String;)V public fun setTransactionName (Ljava/lang/String;)V public fun setUnknown (Ljava/util/Map;)V - public fun setVersionCode (Ljava/lang/String;)V - public fun setVersionName (Ljava/lang/String;)V } public final class io/sentry/ProfilingTraceData$Deserializer : io/sentry/JsonDeserializer { @@ -887,6 +885,7 @@ public final class io/sentry/ProfilingTraceData$JsonKeys { public static final field ENVIRONMENT Ljava/lang/String; public static final field PLATFORM Ljava/lang/String; public static final field PROFILE_ID Ljava/lang/String; + public static final field RELEASE Ljava/lang/String; public static final field SAMPLED_PROFILE Ljava/lang/String; public static final field TRACE_ID Ljava/lang/String; public static final field TRANSACTION_ID Ljava/lang/String; @@ -894,7 +893,6 @@ public final class io/sentry/ProfilingTraceData$JsonKeys { public static final field TRANSACTION_NAME Ljava/lang/String; public static final field TRUNCATION_REASON Ljava/lang/String; public static final field VERSION_CODE Ljava/lang/String; - public static final field VERSION_NAME Ljava/lang/String; public fun ()V } From b631b1789f4de0b85f9f20c84e562d7c0929b771 Mon Sep 17 00:00:00 2001 From: stefanosiano Date: Thu, 1 Dec 2022 11:21:48 -0800 Subject: [PATCH 4/4] added back the version code into serializer/deserializer of ProfilingTraceData for better backward compatibility --- .../android/core/AndroidTransactionProfilerTest.kt | 3 ++- sentry/api/sentry.api | 3 +-- .../src/main/java/io/sentry/ProfilingTraceData.java | 13 +++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt index e065e05916..1a3eec8588 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt @@ -380,7 +380,8 @@ class AndroidTransactionProfilerTest { } } ) - + } + fun `profiler starts collecting frame metrics when the first transaction starts`() { val profiler = fixture.getSut(context) profiler.onTransactionStart(fixture.transaction1) diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index a329ceeb21..6993f1f6b2 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -836,8 +836,7 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public static final field TRUNCATION_REASON_NORMAL Ljava/lang/String; public static final field TRUNCATION_REASON_TIMEOUT Ljava/lang/String; public fun (Ljava/io/File;Lio/sentry/ITransaction;)V - public fun (Ljava/io/File;Ljava/util/List;Lio/sentry/ITransaction;Ljava/lang/String;ILjava/lang/String;Ljava/util/concurrent/Callable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - public fun (Ljava/io/File;Ljava/util/List;Lio/sentry/ITransaction;Ljava/lang/String;ILjava/lang/String;Ljava/util/concurrent/Callable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V + public fun (Ljava/io/File;Ljava/util/List;Lio/sentry/ITransaction;Ljava/lang/String;ILjava/lang/String;Ljava/util/concurrent/Callable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V public fun getAndroidApiLevel ()I public fun getBuildId ()Ljava/lang/String; public fun getCpuArchitecture ()Ljava/lang/String; diff --git a/sentry/src/main/java/io/sentry/ProfilingTraceData.java b/sentry/src/main/java/io/sentry/ProfilingTraceData.java index f8c184dfc5..09582a6f4f 100644 --- a/sentry/src/main/java/io/sentry/ProfilingTraceData.java +++ b/sentry/src/main/java/io/sentry/ProfilingTraceData.java @@ -49,12 +49,13 @@ public final class ProfilingTraceData implements JsonUnknown, JsonSerializable { private @NotNull String buildId; // Transaction info - private final @NotNull List transactions; + private @NotNull List transactions; private @NotNull String transactionName; // duration_ns is a String to avoid issues with numbers and json private @NotNull String durationNs; // App info + private @NotNull String versionCode; private @NotNull String release; // Stacktrace context @@ -138,6 +139,7 @@ public ProfilingTraceData( this.durationNs = durationNanos; // App info + this.versionCode = ""; this.release = release != null ? release : ""; // Stacktrace context @@ -322,6 +324,7 @@ public void setDurationNs(final @NotNull String durationNs) { public void setRelease(@NotNull String release) { this.release = release; + } public void setTransactionId(final @NotNull String transactionId) { this.transactionId = transactionId; @@ -402,7 +405,7 @@ public void serialize(final @NotNull JsonObjectWriter writer, final @NotNull ILo writer.name(JsonKeys.TRANSACTION_NAME).value(transactionName); writer.name(JsonKeys.DURATION_NS).value(durationNs); writer.name(JsonKeys.RELEASE).value(release); - writer.name(JsonKeys.VERSION_CODE).value(""); + writer.name(JsonKeys.VERSION_CODE).value(versionCode); if (!transactions.isEmpty()) { writer.name(JsonKeys.TRANSACTION_LIST).value(logger, transactions); } @@ -539,6 +542,12 @@ public static final class Deserializer implements JsonDeserializer