-
-
Notifications
You must be signed in to change notification settings - Fork 435
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
Improve possible date precision to 10 μs #2451
Conversation
@@ -56,8 +56,12 @@ public SentrySpan(final @NotNull Span span, final @Nullable Map<String, Object> | |||
this.status = span.getStatus(); | |||
final Map<String, String> tagsCopy = CollectionUtils.newConcurrentHashMap(span.getTags()); | |||
this.tags = tagsCopy != null ? tagsCopy : new ConcurrentHashMap<>(); | |||
this.timestamp = span.getHighPrecisionTimestamp(); | |||
this.startTimestamp = DateUtils.dateToSeconds(span.getStartTimestamp()); | |||
// we lose precision here, from potential nanosecond precision down to 10 microsecond precision |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because a Double
cannot offer high enough precision for timestamps.
@marandaneto you mentioned that doing this might cause problems. I can no longer find the comment but afair it went something like "older versions of android / AGP might run into issues". Do you mind giving this a review 🙏 ? |
sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroidDateProvider.java
Outdated
Show resolved
Hide resolved
@romtsn checked that IIRC, so maybe he can help. |
H: This likely requires a major bump since it changes the public APIs with a new type and people can rely on either for comparison or even in compilation due to type errors. |
|
Performance metrics 🚀
|
Revision | Plain | With Sentry | Diff |
---|---|---|---|
904bfec | 301.42 ms | 339.55 ms | 38.13 ms |
aab1277 | 336.48 ms | 386.74 ms | 50.26 ms |
55654bd | 331.98 ms | 370.85 ms | 38.87 ms |
da89816 | 344.00 ms | 404.19 ms | 60.19 ms |
a8de2dd | 333.56 ms | 398.04 ms | 64.48 ms |
b818243 | 264.58 ms | 350.81 ms | 86.23 ms |
App size
Revision | Plain | With Sentry | Diff |
---|---|---|---|
904bfec | 1.73 MiB | 2.33 MiB | 619.16 KiB |
aab1277 | 1.73 MiB | 2.33 MiB | 618.18 KiB |
55654bd | 1.73 MiB | 2.33 MiB | 621.17 KiB |
da89816 | 1.73 MiB | 2.33 MiB | 619.14 KiB |
a8de2dd | 1.73 MiB | 2.33 MiB | 621.15 KiB |
b818243 | 1.73 MiB | 2.33 MiB | 619.15 KiB |
Codecov ReportBase: 80.16% // Head: 80.06% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #2451 +/- ##
============================================
- Coverage 80.16% 80.06% -0.10%
- Complexity 3882 3902 +20
============================================
Files 313 320 +7
Lines 14695 14751 +56
Branches 1947 1950 +3
============================================
+ Hits 11780 11811 +31
- Misses 2154 2169 +15
- Partials 761 771 +10
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
@marandaneto I think it should be fine as I only modified / removed things marked internal. Did you see any specific thing that would require the major bump? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great effort!
I'm wondering if there would be another way of designing the DateProvider.
Instead of overriding the Provider on init we could have a singleton and register more precise implementations on init.
e.g.
SentryDateProvider.now()
always provides a SentryDate
, probably just ms
precision at app start.
Then during init we could register a more precise one:
SentryDateProvider.registerProvider(new SentryInstantDateProvider())
If SentryDateProvider.now()
gets called after init, it would provide ns
precision.
Although this deviates from our usual options.getXYZ()
approach we could get rid of AndroidDateUtils
this way (with the downside of only having a lower resolution during app start).
sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java
Show resolved
Hide resolved
@@ -67,7 +66,7 @@ | |||
|
|||
private @Nullable ISpan appStartSpan; | |||
private final @NotNull WeakHashMap<Activity, ISpan> ttidSpanMap = new WeakHashMap<>(); | |||
private @NotNull Date lastPausedTime = DateUtils.getCurrentDateTime(); | |||
private @NotNull SentryDate lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it would be fine to set the lastPausedTime
when register()
is called using options.getDateProvider().now()
- this way it's more consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about consequences, maybe @romtsn or @marandaneto can confirm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stefanosiano was one implementing it, he might have opinions. But I don't see any problems with moving this into register
since it's called shortly after this integration is instantiated anyway.
sentry-android-core/src/main/java/io/sentry/android/core/AndroidDateUtils.java
Outdated
Show resolved
Hide resolved
sentry-android-core/src/test/java/io/sentry/android/core/SentryAndroidDateProviderTest.kt
Outdated
Show resolved
Hide resolved
Sounds good to me. If others agree I'll change it to not use options. Makes even more sense now that it's an internal option anyways. |
If we query the date provider on app start it'll do so before However this might also be fine as until now we also only offer |
@adinauer I guess some classes or methods were without the internal annotation yet or I missed them in the code diff, just skimmed thru, and apparently it's alright, didn't see Public APIs changing, so all good, sorry for the confusion. |
So, using In addition, if we wanna support older API versions, we'd need our users to use AGP 4.0 + enabled coreLibraryDesugaring. I think for these cases we could try to access |
If we want users to override the date provider, we should still keep it in the options. But I don't see why they would do it, so I don't have a strong opinion here. |
sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java
Outdated
Show resolved
Hide resolved
sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroidDateProvider.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few points, but otherwise LGTM 🚀 Agree with Max - great effort, thanks for doing this!
@romtsn is there varying time source precision? If we use
@romtsn @markushi Having the static then makes it easier to use the wrong implementation. For static invocations like |
I believe the desugared version of
fine for me 👍 |
If we expect it to be |
Just did some testing, try/catch seems to work on older API Levels with desugaring enabled and uses An alternative would be to use Haven't found a way to check whether |
After some more testing I was able to narrow the problem down. When enabling desugaring, I never got high precision timestamps. Without desugaring on the build, API 33 gave high precision timestamps, while 32 and below only gave One thing that surprised me was the Android Studio eval dialog |
This code could serve to check for high precision availability in the future but for now we decided to keep it simple and stick with It's possible desktop/server JDK only offers
|
@adinauer nice investigation efforts! |
📜 Description
This especially affects precision when passing in custom start/end dates for spans/transactions.
It also improves timestamp precision where possible instead of relying on a
ms
precision start timestamp and a fake end timestamp that simply has elapsedns
added to the start timestamp.We could further improve precision by not using
Double
inSentrySpan
andSentryTransaction
. However without changes in relay this would probably only get us toμs
precision.💡 Motivation and Context
Improves #2394 but there's even more room to improve.
💚 How did you test it?
Unit tests, manually
📝 Checklist
🔮 Next steps