sentry-java
sentry-java copied to clipboard
Custom transaction not getting recorded when screen navigates
Integration
sentry-android
Build System
Gradle
AGP Version
8.0.2
Proguard
Enabled
Version
7.1.0
Steps to Reproduce
I like using Transactions for recording an operation and measuring time taken along with the result of the operation. Everything works fine when I start a transaction and finish it wihin the same block.
A requirement which I have at the moment is to record the user's operation within another activity and capture the activity result as a transaction. For example, in the below code, I start a transaction and finish it on result.
private lateinit var transaction: ITransaction
private val activityLauncher = registerForActivityResult(CustomActivityContract()) { result ->
when (result) {
is Ok -> transaction.finish()
is Error -> {
transaction.throwable = result.throwable
transaction.finish(SpanStatus.INTERNAL_ERROR)
}
else -> transaction.finish(SpanStatus.CANCELLED)
}
}
fun doSomethingUsefulAndRecordAsTransaction() {
transaction = Sentry.startTransaction(
"customTransaction",
"doSomethingUsefulAndRecordAsTransaction()",
TransactionOptions().apply {
isBindToScope = true
}
)
activityLauncher.launch()
}
This transaction never gets reported to Sentry. I initially suspected that it was because of automatic instrumentation being enabled where any transaction in flight gets cancelled in favour of activity transactions. Disabling the options in init block didn't help either.
options.isEnableActivityLifecycleTracingAutoFinish = false
options.isEnableAutoActivityLifecycleTracing = false
options.isEnableTimeToFullDisplayTracing = false
options.isEnableUserInteractionTracing = false
Expected Result
Custom transaction being recorded and queriable through discover queries
Actual Result
When automatic instrumentation is enabled, the custom transaction gets discarded. When automatic instrumentation is disabled, then nothing gets recorded.
Hey @ashwin-coles, thanks for opening this issue!
Maybe as a first step could you enable sentry debug mode (options.isDebug = true), this should print some usable logcat output which may gives you more hints why your transaction is being dropped.
There could be a few reasons why a transaction is discarded/dropped:
- sampling
TransactionOptionshas a default deadline timeout of 30s, mayberegisterForActivityResultdoesn't finish in time- some other SDK features interfering with your custom transaction
- your transaction is dropped because it contains no child spans
Thanks for the reply Markushi. A few more details
- Sampling - Set to 1.0
- I have verified within 30s and still no sauce
- Transaction has child spans too
I have enabled the logs and I can see the transactions being captured as per logs but doesn't show up in Sentry dashboard.
Hey @ashwin-coles thanks for getting back! Do you also see logcat lines around envelope submission? Ideally you'd see the following message
Envelope sent successfully.
which indicates that the envelope was sent to the sentry.io backend.
Unfortunately, no. The last message I see in the sentry logs is
stop collecting performance info for transactions CustomActivityResult (0ef328eeb10d4761ab786e6d06df983c)
When I opened the issue, I thought it was a generic issue with Activity results and custom transactions. With the sample setup above, the transaction works as expected. However, when the user flow is complex, it doesn't get sent to Sentry.
For example, a user auth flow using auth0 library.
- User taps on login. (start transaction)
- Activity result launcher used to start auth process.
- Auth callback code executes (finish transaction).
In this case, you do see a log from Sentry
A transaction is already being profiled. Transaction AuthorizationManagementActivity (1965def522ad4f44bac3c310ded89ffe) will be ignored.
Although, the only transaction that is found in the dashboard is AuthorizationManagementActivity
Thanks for the details @ashwin-coles! This definitely sounds odd, I see you already shared some of the options you're setting on SDK init - would you mind pasting your whole (redacted) Sentry configuration?
Sure. Here is the init block.
SentryAndroid.init(context) { options ->
options.dsn = localConfig.sentryDsn
options.sampleRate = 1.0
options.tracesSampleRate = 1.0
options.profilesSampleRate = 1.0
options.isEnableActivityLifecycleTracingAutoFinish = true
options.isEnableAutoActivityLifecycleTracing = true
options.isEnableTimeToFullDisplayTracing = true
options.isEnableUserInteractionTracing = true
options.isAttachScreenshot = false
options.setBeforeSend { event, hint ->
getDefaultData().forEach { (key, value) ->
event.setTag(key, value)
}
}
An update. If I force a sampling decision, the transaction does get reported as expected. Still not sure why it never got sent in the first place.
private val transaction = Sentry.startTransaction(
TransactionContext(
/* name = */ taskName,
/* operation = */ operationName,
/* samplingDecision = */ TracesSamplingDecision(true)
)
)
However, the TracesSamplingDecision and TransactionContext are both marked as @ApiStatus.Internal. The document advises that this can be used to force a sampling decision.
Let's close this one for now, as this will be improved anyway with the upcoming screen API.