Skip to content

chore(android-sqlite): Repair start times of spans generated by SentrySQLiteDriver#5543

Open
0xadam-brown wants to merge 1 commit into
feat/no-double-wrapping-sqlite-driverfrom
chore/offset-sqlite-start-timestamps
Open

chore(android-sqlite): Repair start times of spans generated by SentrySQLiteDriver#5543
0xadam-brown wants to merge 1 commit into
feat/no-double-wrapping-sqlite-driverfrom
chore/offset-sqlite-start-timestamps

Conversation

@0xadam-brown

@0xadam-brown 0xadam-brown commented Jun 12, 2026

Copy link
Copy Markdown
Member

📜 Description

Repairs the nanoTimetamp of the SentryNanotimeDates used as start times for the spans generated by SentrySQLiteDriver.

For more details, see the discussion here. This PR implements approach [1] ("Offset SQLite spans based nano duration between parent and child start times").

💡 Motivation and Context

Without those repairs, all spans within a given wall clock millisecond are displayed by Sentry UI as starting at that same millisecond and are re-ordered arbitrarily. Often that's quite confusing as actual BEGIN -> EXECUTE STATEMENT -> END sequences can appear as EXECUTE STATEMENT -> END -> BEGIN (etc.).

JAVA-275

Screenshots

Before

Before - R3

(Link)

After

After 2

(Link)

Before

Before - Room2

(Link)

After

After 3

(Link)

💚 How did you test it?

  • Unit tests
  • Via the sample app + verifying span appearance in Sentry UI (see screenshots above)

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

Consider implementing nesting of spans as mentioned here.

@sentry

sentry Bot commented Jun 12, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.43.1 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 473.69 ms 605.96 ms 132.27 ms
Size 0 B 0 B 0 B

Baseline results on branch: feat/no-double-wrapping-sqlite-driver

Startup times

Revision Plain With Sentry Diff
270954d 320.98 ms 350.34 ms 29.36 ms
5490807 411.52 ms 485.10 ms 73.58 ms

App size

Revision Plain With Sentry Diff
270954d 0 B 0 B 0 B
5490807 0 B 0 B 0 B

Previous results on branch: chore/offset-sqlite-start-timestamps

Startup times

Revision Plain With Sentry Diff
eb8ae87 323.80 ms 377.66 ms 53.86 ms
3cacd74 342.60 ms 409.53 ms 66.93 ms

App size

Revision Plain With Sentry Diff
eb8ae87 0 B 0 B 0 B
3cacd74 0 B 0 B 0 B

* "Coarse" in that it doesn't provide a nanosecond precision for [SentryNanotimeDate]
* [startTimestamp]s.
*/
fun recordCoarseSpan(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chime in if you can think of a better name. Not in love with this, but it'll do if it has to...

* END TRANSACTION ├███┤ 0.18 ms
* ```
*/
private fun SentryDate.repairPrecision(baseline: SentryDate?): SentryDate =

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This arguably belongs on SentryDate, especially as the latter's API is already enmeshed in the broken precision of SentryDate.nanoTimestamp. But I struggled to get it to work. I considered:

[1] adding a SentryDate.laterDateByDiff() that returns a SentryLongDate (declared as a SentryDate).

...but that seemed heavyweight for a single call site (new public method, tests against all implementing classes), esp as the only thing it buys us is a replacement for the already minimal line 112. Plus, bumping the minSdkVersion to 26 will let us move off of SentryNanotimeDate, so any investments in it will be short-lived.

[2] adding a repairPrecision() method solely to SentryNanotimeDate (allowing us to relocate all of the repair method).

...but that'd also be a new public API, and it'd mean we'd have to cast at the call site, which would be against the grain of how we typically use SentryDate.

So I left things as you see them, figuring we could shuffle bits around if we ever get a second call site.

Let me know if you have any opinions.

@0xadam-brown 0xadam-brown force-pushed the chore/offset-sqlite-start-timestamps branch from 70c2b17 to 1e20263 Compare June 12, 2026 19:57
…ySQLiteDriver (JAVA-275)

Repairs the nanoTimetamp of the SentryNanotimeDates used as start times for the spans generated by SentrySQLiteDriver. Without those repairs, all spans within a given wall clock millisecond are displayed by Sentry UI as starting at that same millisecond and are re-ordered arbitrarily. Often that's quite confusing as actual BEGIN -> EXECUTE STATEMENT -> END sequences can appear as EXECUTE STATEMENT -> END -> BEGIN (etc.).

For more details, see the discussion [here](#5504 (comment)).
@0xadam-brown 0xadam-brown force-pushed the chore/offset-sqlite-start-timestamps branch from 1e20263 to d29d3f8 Compare June 12, 2026 21:29
) {
recordSpan(sql, startTimestamp, endTimestamp = null, status, throwable)
val parent = scopes.span ?: return
val nanoPrecisionStart = startTimestamp.repairPrecision(baseline = parent.startDate)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repairing the incoming timestamp is the only interesting change this PR makes. (The diff looks a bit bigger because I switched the order of the first and second methods and renamed the second recordCoarseSpan.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant