From 8e4c518d960aeb3e85622a9955eee47df53f4c0f Mon Sep 17 00:00:00 2001 From: stefanosiano Date: Fri, 24 May 2024 15:09:40 +0200 Subject: [PATCH 1/2] added start timestamp in ProfileStartData when a profile starts added the timestamp in ProfilingTraceData and send it in the json payload --- .../api/sentry-android-core.api | 3 ++- .../sentry/android/core/AndroidProfiler.java | 10 +++++++-- .../core/AndroidTransactionProfiler.java | 6 ++++++ .../android/core/AndroidProfilerTest.kt | 1 + sentry/api/sentry.api | 5 ++++- .../java/io/sentry/ProfilingTraceData.java | 21 +++++++++++++++++++ .../test/java/io/sentry/JsonSerializerTest.kt | 5 +++++ 7 files changed, 47 insertions(+), 4 deletions(-) diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index 8eb017346d..89c93723fa 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -81,7 +81,8 @@ public class io/sentry/android/core/AndroidProfiler$ProfileEndData { public class io/sentry/android/core/AndroidProfiler$ProfileStartData { public final field startCpuMillis J public final field startNanos J - public fun (JJ)V + public final field startTimestamp Ljava/util/Date; + public fun (JJLjava/util/Date;)V } public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidProfiler.java index 0018f8b75f..2dba6d79c3 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidProfiler.java @@ -6,6 +6,7 @@ import android.os.Process; import android.os.SystemClock; import io.sentry.CpuCollectionData; +import io.sentry.DateUtils; import io.sentry.ILogger; import io.sentry.ISentryExecutorService; import io.sentry.MemoryCollectionData; @@ -17,6 +18,7 @@ import io.sentry.util.Objects; import java.io.File; import java.util.ArrayDeque; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,10 +35,13 @@ public class AndroidProfiler { public static class ProfileStartData { public final long startNanos; public final long startCpuMillis; + public final @NotNull Date startTimestamp; - public ProfileStartData(final long startNanos, final long startCpuMillis) { + public ProfileStartData( + final long startNanos, final long startCpuMillis, final @NotNull Date startTimestamp) { this.startNanos = startNanos; this.startCpuMillis = startCpuMillis; + this.startTimestamp = startTimestamp; } } @@ -192,6 +197,7 @@ public void onFrameMetricCollected( } profileStartNanos = SystemClock.elapsedRealtimeNanos(); + final @NotNull Date profileStartTimestamp = DateUtils.getCurrentDateTime(); long profileStartCpuMillis = Process.getElapsedCpuTime(); // We don't make any check on the file existence or writeable state, because we don't want to @@ -203,7 +209,7 @@ public void onFrameMetricCollected( // tests) Debug.startMethodTracingSampling(traceFile.getPath(), BUFFER_SIZE_BYTES, intervalUs); isRunning = true; - return new ProfileStartData(profileStartNanos, profileStartCpuMillis); + return new ProfileStartData(profileStartNanos, profileStartCpuMillis, profileStartTimestamp); } catch (Throwable e) { endAndCollect(false, null); logger.log(SentryLevel.ERROR, "Unable to start a profile: ", e); 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 3abfe1306a..0404f3efd2 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 @@ -9,6 +9,7 @@ import android.os.Build; import android.os.Process; import android.os.SystemClock; +import io.sentry.DateUtils; import io.sentry.HubAdapter; import io.sentry.IHub; import io.sentry.ILogger; @@ -24,6 +25,7 @@ import io.sentry.android.core.internal.util.SentryFrameMetricsCollector; import io.sentry.util.Objects; import java.util.ArrayList; +import java.util.Date; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,6 +46,7 @@ final class AndroidTransactionProfiler implements ITransactionProfiler { private @Nullable AndroidProfiler profiler = null; private long profileStartNanos; private long profileStartCpuMillis; + private @NotNull Date profileStartTimestamp; /** * @deprecated please use a constructor that doesn't takes a {@link IHub} instead, as it would be @@ -95,6 +98,7 @@ public AndroidTransactionProfiler( this.profilingTracesHz = profilingTracesHz; this.executorService = Objects.requireNonNull(executorService, "The ISentryExecutorService is required."); + this.profileStartTimestamp = DateUtils.getCurrentDateTime(); } private void init() { @@ -164,6 +168,7 @@ private boolean onFirstStart() { } profileStartNanos = startData.startNanos; profileStartCpuMillis = startData.startCpuMillis; + profileStartTimestamp = startData.startTimestamp; return true; } @@ -274,6 +279,7 @@ public synchronized void bindTransaction(final @NotNull ITransaction transaction // done in the background when the trace file is read return new ProfilingTraceData( endData.traceFile, + profileStartTimestamp, transactionList, transactionName, transactionId, diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidProfilerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidProfilerTest.kt index a726b2c55b..0efd13850e 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidProfilerTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidProfilerTest.kt @@ -178,6 +178,7 @@ class AndroidProfilerTest { val endData = profiler.endAndCollect(false, null) assertNotNull(startData?.startNanos) assertNotNull(startData?.startCpuMillis) + assertNotNull(startData?.startTimestamp) assertNotNull(endData?.endNanos) assertNotNull(endData?.endCpuMillis) } diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 121ef1af76..d29b04dd7d 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -1420,7 +1420,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;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;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 (Ljava/io/File;Ljava/util/Date;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;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; @@ -1439,6 +1439,7 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public fun getProfileId ()Ljava/lang/String; public fun getRelease ()Ljava/lang/String; public fun getSampledProfile ()Ljava/lang/String; + public fun getTimestamp ()Ljava/util/Date; public fun getTraceFile ()Ljava/io/File; public fun getTraceId ()Ljava/lang/String; public fun getTransactionId ()Ljava/lang/String; @@ -1465,6 +1466,7 @@ public final class io/sentry/ProfilingTraceData : io/sentry/JsonSerializable, io public fun setProfileId (Ljava/lang/String;)V public fun setRelease (Ljava/lang/String;)V public fun setSampledProfile (Ljava/lang/String;)V + public fun setTimestamp (Ljava/util/Date;)V public fun setTraceId (Ljava/lang/String;)V public fun setTransactionId (Ljava/lang/String;)V public fun setTransactionName (Ljava/lang/String;)V @@ -1499,6 +1501,7 @@ public final class io/sentry/ProfilingTraceData$JsonKeys { 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 TIMESTAMP Ljava/lang/String; public static final field TRACE_ID Ljava/lang/String; public static final field TRANSACTION_ID Ljava/lang/String; public static final field TRANSACTION_LIST Ljava/lang/String; diff --git a/sentry/src/main/java/io/sentry/ProfilingTraceData.java b/sentry/src/main/java/io/sentry/ProfilingTraceData.java index 35902f5f04..d1410245af 100644 --- a/sentry/src/main/java/io/sentry/ProfilingTraceData.java +++ b/sentry/src/main/java/io/sentry/ProfilingTraceData.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -64,6 +65,7 @@ public final class ProfilingTraceData implements JsonUnknown, JsonSerializable { private @NotNull String profileId; private @NotNull String environment; private @NotNull String truncationReason; + private @NotNull Date timestamp; private final @NotNull Map measurementsMap; // Stacktrace (file) @@ -78,6 +80,7 @@ public ProfilingTraceData( final @NotNull File traceFile, final @NotNull ITransaction transaction) { this( traceFile, + DateUtils.getCurrentDateTime(), new ArrayList<>(), transaction.getName(), transaction.getEventId().toString(), @@ -101,6 +104,7 @@ public ProfilingTraceData( public ProfilingTraceData( @NotNull File traceFile, + @NotNull Date profileStartTimestamp, @NotNull List transactions, @NotNull String transactionName, @NotNull String transactionId, @@ -120,6 +124,7 @@ public ProfilingTraceData( @NotNull String truncationReason, final @NotNull Map measurementsMap) { this.traceFile = traceFile; + this.timestamp = profileStartTimestamp; this.cpuArchitecture = cpuArchitecture; this.deviceCpuFrequenciesReader = deviceCpuFrequenciesReader; @@ -262,6 +267,10 @@ public boolean isDeviceIsEmulator() { return truncationReason; } + public @NotNull Date getTimestamp() { + return timestamp; + } + public @NotNull Map getMeasurementsMap() { return measurementsMap; } @@ -306,6 +315,10 @@ public void setDevicePhysicalMemoryBytes(final @NotNull String devicePhysicalMem this.devicePhysicalMemoryBytes = devicePhysicalMemoryBytes; } + public void setTimestamp(final @NotNull Date timestamp) { + this.timestamp = timestamp; + } + public void setTruncationReason(final @NotNull String truncationReason) { this.truncationReason = truncationReason; } @@ -386,6 +399,7 @@ public static final class JsonKeys { public static final String SAMPLED_PROFILE = "sampled_profile"; public static final String TRUNCATION_REASON = "truncation_reason"; public static final String MEASUREMENTS = "measurements"; + public static final String TIMESTAMP = "timestamp"; } @Override @@ -422,6 +436,7 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger writer.name(JsonKeys.SAMPLED_PROFILE).value(sampledProfile); } writer.name(JsonKeys.MEASUREMENTS).value(logger, measurementsMap); + writer.name(JsonKeys.TIMESTAMP).value(logger, timestamp); if (unknown != null) { for (String key : unknown.keySet()) { Object value = unknown.get(key); @@ -602,6 +617,12 @@ public static final class Deserializer implements JsonDeserializer Date: Fri, 24 May 2024 15:14:26 +0200 Subject: [PATCH 2/2] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6a4685caf..788117d1aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Fixes - Fix faulty `span.frame_delay` calculation for early app start spans ([#3427](https://github.com/getsentry/sentry-java/pull/3427)) +- Add timestamp when a profile starts ([#3442](https://github.com/getsentry/sentry-java/pull/3442)) ## 7.9.0