Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix add missing thread name/id to app start spans #3226

Merged
merged 3 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Fix old profiles deletion on SDK init ([#3216](https://github.com/getsentry/sentry-java/pull/3216))
- Fix hub restore point in wrappers: SentryWrapper, SentryTaskDecorator and SentryScheduleHook ([#3225](https://github.com/getsentry/sentry-java/pull/3225))
- We now reset the hub to its previous value on the thread where the `Runnable`/`Callable`/`Supplier` is executed instead of setting it to the hub that was used on the thread where the `Runnable`/`Callable`/`Supplier` was created.
- Fix add missing thread name/id to app start spans ([#3226](https://github.com/getsentry/sentry-java/pull/3226))

## 7.4.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -231,6 +233,11 @@ private static SentrySpan timeSpanToSentrySpan(
final @Nullable SpanId parentSpanId,
final @NotNull SentryId traceId,
final @NotNull String operation) {

final Map<String, Object> 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(),
Expand All @@ -242,6 +249,6 @@ private static SentrySpan timeSpanToSentrySpan(
SpanStatus.OK,
APP_METRICS_ORIGIN,
new HashMap<>(),
null);
defaultSpanData);
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -27,6 +29,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

@RunWith(AndroidJUnit4::class)
class PerformanceAndroidEventProcessorTest {

private class Fixture {
Expand Down Expand Up @@ -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) {
Expand Down
Loading