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

Send source for transactions #2180

Merged
merged 14 commits into from Aug 5, 2022
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Send source for transactions ([#2180](https://github.com/getsentry/sentry-java/pull/2180))

## 6.3.1

### Fixes
Expand Down
Expand Up @@ -20,6 +20,9 @@
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.SpanStatus;
import io.sentry.TransactionContext;
import io.sentry.TransactionOptions;
import io.sentry.protocol.TransactionNameSource;
import io.sentry.util.Objects;
import java.io.Closeable;
import java.io.IOException;
Expand Down Expand Up @@ -152,64 +155,44 @@ private void startTracing(final @NotNull Activity activity) {
// as we allow a single transaction running on the bound Scope, we finish the previous ones
stopPreviousTransactions();

// we can only bind to the scope if there's no running transaction
ITransaction transaction;
final String activityName = getActivityName(activity);

final Date appStartTime =
foregroundImportance ? AppStartState.getInstance().getAppStartTime() : null;
final Boolean coldStart = AppStartState.getInstance().isColdStart();

final TransactionOptions transactionOptions = new TransactionOptions();

transactionOptions.setWaitForChildren(true);
transactionOptions.setTransactionFinishedCallback(
(finishingTransaction) -> {
@Nullable Activity unwrappedActivity = weakActivity.get();
if (unwrappedActivity != null) {
activityFramesTracker.setMetrics(
unwrappedActivity, finishingTransaction.getEventId());
} else {
if (options != null) {
options
.getLogger()
.log(
SentryLevel.WARNING,
"Unable to track activity frames as the Activity %s has been destroyed.",
activityName);
}
}
});

// we can only bind to the scope if there's no running transaction
ITransaction transaction =
hub.startTransaction(
new TransactionContext(activityName, TransactionNameSource.COMPONENT, UI_LOAD_OP),
transactionOptions);

// in case appStartTime isn't available, we don't create a span for it.
if (firstActivityCreated || appStartTime == null || coldStart == null) {
transaction =
hub.startTransaction(
activityName,
UI_LOAD_OP,
(Date) null,
true,
(finishingTransaction) -> {
@Nullable Activity unwrappedActivity = weakActivity.get();
if (unwrappedActivity != null) {
activityFramesTracker.setMetrics(
unwrappedActivity, finishingTransaction.getEventId());
} else {
if (options != null) {
options
.getLogger()
.log(
SentryLevel.WARNING,
"Unable to track activity frames as the Activity %s has been destroyed.",
activityName);
}
}
});
} else {
// start transaction with app start timestamp
transaction =
hub.startTransaction(
activityName,
UI_LOAD_OP,
appStartTime,
true,
(finishingTransaction) -> {
@Nullable Activity unwrappedActivity = weakActivity.get();
if (unwrappedActivity != null) {
activityFramesTracker.setMetrics(
unwrappedActivity, finishingTransaction.getEventId());
} else {
if (options != null) {
options
.getLogger()
.log(
SentryLevel.WARNING,
"Unable to track activity frames as the Activity %s has been destroyed.",
activityName);
}
}
});
// start specific span for app start
if (!(firstActivityCreated || appStartTime == null || coldStart == null)) {
transactionOptions.setStartTimestamp(appStartTime);

// start specific span for app start
appStartSpan =
transaction.startChild(
getAppStartOp(coldStart), getAppStartDesc(coldStart), appStartTime);
Expand Down
Expand Up @@ -16,7 +16,10 @@
import io.sentry.Scope;
import io.sentry.SentryLevel;
import io.sentry.SpanStatus;
import io.sentry.TransactionContext;
import io.sentry.TransactionOptions;
import io.sentry.android.core.SentryAndroidOptions;
import io.sentry.protocol.TransactionNameSource;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Map;
Expand Down Expand Up @@ -249,8 +252,15 @@ private void startTracing(final @NotNull View target, final @NotNull String even
// we can only bind to the scope if there's no running transaction
final String name = getActivityName(activity) + "." + viewId;
final String op = UI_ACTION + "." + eventType;

final TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.setWaitForChildren(true);
transactionOptions.setIdleTimeout(options.getIdleTimeout());
transactionOptions.setTrimEnd(true);

final ITransaction transaction =
hub.startTransaction(name, op, true, options.getIdleTimeout(), true);
hub.startTransaction(
new TransactionContext(name, TransactionNameSource.COMPONENT, op), transactionOptions);

hub.configureScope(
scope -> {
Expand Down
Expand Up @@ -23,6 +23,8 @@ import io.sentry.SpanStatus
import io.sentry.TraceContext
import io.sentry.TransactionContext
import io.sentry.TransactionFinishedCallback
import io.sentry.TransactionOptions
import io.sentry.protocol.TransactionNameSource
import java.util.Date
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand Down Expand Up @@ -51,7 +53,7 @@ class ActivityLifecycleIntegrationTest {

fun getSut(apiVersion: Int = 29, importance: Int = RunningAppProcessInfo.IMPORTANCE_FOREGROUND): ActivityLifecycleIntegration {
whenever(hub.options).thenReturn(options)
whenever(hub.startTransaction(any(), any(), anyOrNull(), any(), any<TransactionFinishedCallback>())).thenReturn(transaction)
whenever(hub.startTransaction(any(), any<TransactionOptions>())).thenReturn(transaction)
whenever(buildInfo.sdkInfoVersion).thenReturn(apiVersion)

whenever(application.getSystemService(any())).thenReturn(am)
Expand Down Expand Up @@ -251,7 +253,7 @@ class ActivityLifecycleIntegrationTest {
val activity = mock<Activity>()
sut.onActivityCreated(activity, fixture.bundle)

verify(fixture.hub, never()).startTransaction(any(), any(), anyOrNull(), any(), any<TransactionFinishedCallback>())
verify(fixture.hub, never()).startTransaction(any(), any<TransactionOptions>())
}

@Test
Expand All @@ -264,7 +266,7 @@ class ActivityLifecycleIntegrationTest {
sut.onActivityCreated(activity, fixture.bundle)
sut.onActivityCreated(activity, fixture.bundle)

verify(fixture.hub).startTransaction(any(), any(), anyOrNull(), any(), any<TransactionFinishedCallback>())
verify(fixture.hub).startTransaction(any(), any<TransactionOptions>())
}

@Test
Expand All @@ -279,11 +281,11 @@ class ActivityLifecycleIntegrationTest {
sut.onActivityCreated(activity, fixture.bundle)

verify(fixture.hub).startTransaction(
any(),
check {
assertEquals("ui.load", it)
assertEquals("ui.load", it.operation)
assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource)
},
anyOrNull(), any(), any<TransactionFinishedCallback>()
any<TransactionOptions>()
)
}

Expand Down Expand Up @@ -312,9 +314,10 @@ class ActivityLifecycleIntegrationTest {

verify(fixture.hub).startTransaction(
check {
assertEquals("Activity", it)
assertEquals("Activity", it.name)
assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource)
},
any(), anyOrNull(), any(), any<TransactionFinishedCallback>()
any<TransactionOptions>()
)
}

Expand Down Expand Up @@ -532,7 +535,7 @@ class ActivityLifecycleIntegrationTest {
val activity = mock<Activity>()
sut.onActivityCreated(activity, mock())

verify(fixture.hub).startTransaction(any(), any(), anyOrNull(), any(), any<TransactionFinishedCallback>())
verify(fixture.hub).startTransaction(any(), any<TransactionOptions>())
}

@Test
Expand Down Expand Up @@ -631,7 +634,7 @@ class ActivityLifecycleIntegrationTest {
sut.onActivityCreated(activity, fixture.bundle)

// call only once
verify(fixture.hub).startTransaction(any(), any(), eq(date), any(), any())
verify(fixture.hub).startTransaction(any(), check<TransactionOptions> { assertEquals(date, it.startTimestamp) })
}

@Test
Expand All @@ -647,7 +650,7 @@ class ActivityLifecycleIntegrationTest {
sut.onActivityCreated(activity, fixture.bundle)

// call only once
verify(fixture.hub).startTransaction(any(), any(), eq(null), any(), any())
verify(fixture.hub).startTransaction(any(), check<TransactionOptions> { assertNull(it.startTimestamp) })
}

@Test
Expand Down Expand Up @@ -730,15 +733,15 @@ class ActivityLifecycleIntegrationTest {
val activity = mock<Activity>()
sut.onActivityCreated(activity, fixture.bundle)

verify(fixture.hub).startTransaction(any(), any(), eq(date), any(), any())
verify(fixture.hub).startTransaction(any(), check<TransactionOptions> { assertEquals(date, it.startTimestamp) })
sut.onActivityCreated(activity, fixture.bundle)
sut.onActivityPostResumed(activity)

val newActivity = mock<Activity>()
sut.onActivityCreated(newActivity, fixture.bundle)

val nullDate: Date? = null
verify(fixture.hub).startTransaction(any(), any(), eq(nullDate), any(), any())
verify(fixture.hub).startTransaction(any(), check<TransactionOptions> { assertNull(it.startTimestamp) })
}

@Test
Expand Down