From 5ade5ee1997b695561caae42db15b3c21e24de7e Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Mon, 26 Feb 2024 11:22:26 +0100 Subject: [PATCH 1/2] Fix add missing thread name/id to app start spans --- .../PerformanceAndroidEventProcessor.java | 9 ++- .../PerformanceAndroidEventProcessorTest.kt | 58 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java index 12419b4c90..00653b622e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java @@ -4,11 +4,13 @@ import static io.sentry.android.core.ActivityLifecycleIntegration.APP_START_WARM; import static io.sentry.android.core.ActivityLifecycleIntegration.UI_LOAD_OP; +import android.os.Looper; import io.sentry.EventProcessor; import io.sentry.Hint; import io.sentry.MeasurementUnit; import io.sentry.SentryEvent; import io.sentry.SpanContext; +import io.sentry.SpanDataConvention; import io.sentry.SpanId; import io.sentry.SpanStatus; import io.sentry.android.core.performance.ActivityLifecycleTimeSpan; @@ -231,6 +233,11 @@ private static SentrySpan timeSpanToSentrySpan( final @Nullable SpanId parentSpanId, final @NotNull SentryId traceId, final @NotNull String operation) { + + final Map defaultSpanData = new HashMap<>(2); + defaultSpanData.put(SpanDataConvention.THREAD_ID, Looper.getMainLooper().getThread().getId()); + defaultSpanData.put(SpanDataConvention.THREAD_NAME, "main"); + return new SentrySpan( span.getStartTimestampSecs(), span.getProjectedStopTimestampSecs(), @@ -242,6 +249,6 @@ private static SentrySpan timeSpanToSentrySpan( SpanStatus.OK, APP_METRICS_ORIGIN, new HashMap<>(), - null); + defaultSpanData); } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt index fac32d4e7d..9aaeb04770 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt @@ -1,6 +1,7 @@ package io.sentry.android.core import android.content.ContentProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hint import io.sentry.IHub import io.sentry.MeasurementUnit @@ -18,6 +19,7 @@ import io.sentry.android.core.performance.AppStartMetrics.AppStartType import io.sentry.protocol.MeasurementValue import io.sentry.protocol.SentrySpan import io.sentry.protocol.SentryTransaction +import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @@ -27,6 +29,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue +@RunWith(AndroidJUnit4::class) class PerformanceAndroidEventProcessorTest { private class Fixture { @@ -398,6 +401,61 @@ class PerformanceAndroidEventProcessorTest { ) } + @Test + fun `adds main thread name and id to app start spans`() { + // given some cold app start metrics + // where class loaded happened way before app start + val appStartMetrics = AppStartMetrics.getInstance() + appStartMetrics.appStartType = AppStartType.COLD + appStartMetrics.appStartTimeSpan.setStartedAt(1) + appStartMetrics.appStartTimeSpan.setStoppedAt(3000) + + AppStartMetrics.getInstance().applicationOnCreateTimeSpan.apply { + setStartedAt(1000) + description = "com.example.App.onCreate" + setStoppedAt(2000) + } + + val sut = fixture.getSut(enablePerformanceV2 = true) + val context = TransactionContext("Activity", UI_LOAD_OP) + val tracer = SentryTracer(context, fixture.hub) + var tr = SentryTransaction(tracer) + val appStartSpan = SentrySpan( + 0.0, + 1.0, + tr.contexts.trace!!.traceId, + SpanId(), + null, + APP_START_COLD, + "App Start", + SpanStatus.OK, + null, + emptyMap(), + null + ) + tr.spans.add(appStartSpan) + + // when the processor attaches the app start spans + tr = sut.process(tr, Hint()) + + // thread name and id should be set + assertTrue { + tr.spans.any { + it.op == "process.load" && + it.data!!["thread.name"] == "main" && + it.data!!.containsKey("thread.id") + } + } + + assertTrue { + tr.spans.any { + it.op == "application.load" && + it.data!!["thread.name"] == "main" && + it.data!!.containsKey("thread.id") + } + } + } + private fun setAppStart(options: SentryAndroidOptions, coldStart: Boolean = true) { AppStartMetrics.getInstance().apply { appStartType = when (coldStart) { From 17c8f376a20b393da66e0a66c8afd3fc6eab3e30 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Mon, 26 Feb 2024 11:26:20 +0100 Subject: [PATCH 2/2] Update Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6602434ac..754d15ffd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Ensure performance measurement collection is not taken too frequently ([#3221](https://github.com/getsentry/sentry-java/pull/3221)) - Fix old profiles deletion on SDK init ([#3216](https://github.com/getsentry/sentry-java/pull/3216)) +- Fix add missing thread name/id to app start spans ([#3226](https://github.com/getsentry/sentry-java/pull/3226)) ## 7.4.0