getsentry / getsentry/sentry-dotnet
feat: Add API to retrieve persisted breadcrumbs on Android
- Dominant language
- C#
- Stars
- 770
- Forks
- 248
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 49
Description
### Summary
Add a user-accessible API to retrieve "persisted breadcrumbs" from the Android-SDK (`sentry-java`).
### Remarks
User Scenario: ANR
Does not use provided auto ANRs (environment always defaulted to prod, tracking app closures as ANR).
Set up custom solution, that is lacking the breadcrumb data from the previously crashed session.
Note: The Persisted Breadcrumb data, that the Android SDK stores, is not pure JSON, so a custom reader/parser is used.
Note: Retrieving the Persisted Breadcrumbs must be done before the default Integrations of the Android SDK override the previously Persisted Breadcrumbs. But actually during initialization, where the Sentry-Options are already available with the Path to the Cache-Directory.
#### Solution: Read during Init
- see getsentry/sentry-dotnet#4977
- At the end of the Java/Android-Options configuration callback, where we transfer .NET-SDK-Options to the Java/Android-SDK-Options, read the ReadPersisted Breadcrumbs into a static field that can be read by the user through a public member on `SentrySdk` on the Android Platform only.
Pro: We control the right timing of the read, have all internal types available to properly parse the data into a .NET type.
Con: we are pessimizing the Init/Startup of over .NET Android and .NET MAUI on Android app for this (currently) singular use case.
#### Solution: New static "Read" method with pay-for-play complexity
- see https://github.com/getsentry/sentry-dotnet/pull/4977/changes#r3273624965
Pro: separate method that can be invoked on an on-demand basis; could be marked `unsafe` considering [C# 15's Unsafe Evolution](https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md).
Con: required types are `internal`, and are not really meant to be constructed/owned by user code.
#### Solution: provide .NET integration
- `sentry-dotnet` implements a `io.sentry.Integration`
Pro: not added per default
Con: uncommon pattern of user code constructing the Integration in order to own a member via which the written Persisted Breadcrumbs can be read; the `sentry-dotnet` bindings would need to make two types public
- `io.sentry.SentryOptions` via `Sentry.JavaSdk.SentryOptions`
- `io.sentry.IScopes` via `Sentry.JavaSdk.IScopes`
#### Solution: provide a more generic way of Before/Pre-Init and After/Post-Init integration
- `sentry-java` exposes a generic integration layer
Pro: Persisted Breadcrumbs would just be one use case to use this interop layer
Con: Significant work required in `sentry-java` for a - currently - single use case
#### Solution: user reads file directly
- user reads the Persisted Breadcrumb data from Sentry as is
Pro: Sentry does not expose interop types/members for a (currently) singular scenario.
Con: brittle solution, as the user would need to duplicate/imitate internals (such as the format for the Persisted Breadcrumbs file as well as building the path to it) that might change in the future.
#### Solution: make some Android Bindings public to facilitate user code reading the file directly
- `sentry-dotnet` changes the accessibility of `io.sentry.cache.PersistingScopeObserver` from `internal` to `public`
- `sentry-dotnet` starts create bindings for `io.sentry.cache.tape.QueueFile` (currently remofed/excluded
Pro: exposing the already available building blocks to users.
Con: exposing the Android Bindings to .NET consumers introduces a new layer/vector of potential breaking changes.
Contributor guide
Assessment
This issue has not been assessed yet.