-
-
Notifications
You must be signed in to change notification settings - Fork 458
RFF(replay): Adding OkHttp Request/Response bodies for sentry-java #4796
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
base: main
Are you sure you want to change the base?
Conversation
…dcrumbCallback to extract NetworkRequestData from Hint -> NetworkRequestData is landing on DefaultReplayBreadcrumbConverter via Hint.get(replay:networkDetails)
scopes.options.logger.log( | ||
io.sentry.SentryLevel.INFO, | ||
"SentryNetwork: Request - Headers count: ${requestHeaders.size}, Body size: $reqBodySize, Body info: $reqBodyInfo" | ||
) |
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.
Bug: Logging Overload and Network Data Loss
Debug logging statements (Android Log.d
, println
, Sentry logger INFO level) were committed, causing excessive log output. Separately, the DefaultReplayBreadcrumbConverter
loses network data for Replay when a user's BeforeBreadcrumbCallback
returns a new Breadcrumb
instance, as the httpBreadcrumbData
map lookup fails due to a key mismatch.
Additional Locations (5)
sentry-android-replay/src/main/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverter.kt#L134-L150
sentry-android-replay/src/main/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverter.kt#L159-L164
sentry-android-replay/src/main/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverter.kt#L180-L184
sentry-android-replay/src/main/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverter.kt#L198-L202
sentry-android-replay/src/main/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverter.kt#L2-L3
} | ||
|
||
private var lastConnectivityState: String? = null | ||
private val httpBreadcrumbData = mutableMapOf<Breadcrumb, NetworkRequestData>() |
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.
} | ||
|
||
private var lastConnectivityState: String? = null | ||
private val httpBreadcrumbData = mutableMapOf<Breadcrumb, NetworkRequestData>() |
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.
Potential bug: The singleton's httpBreadcrumbData
map is not thread-safe and grows indefinitely, leading to concurrency crashes and out-of-memory errors.
-
Description: The
DefaultReplayBreadcrumbConverter
is a singleton that uses a non-thread-safemutableMapOf
namedhttpBreadcrumbData
. This leads to two issues. First, because OkHttp interceptors can run on concurrent threads, simultaneous writes to the map can causeConcurrentModificationException
crashes. Second, entries are added to the map for every HTTP request but are never removed. This causes unbounded memory growth in the long-lived singleton, eventually leading to anOutOfMemoryError
. -
Suggested fix: Replace
mutableMapOf
with a thread-safe collection likeConcurrentHashMap
. Also, ensure entries are removed from the map after the corresponding breadcrumb data has been processed for the replay segment to prevent unbounded memory growth.
severity: 0.9, confidence: 0.98
Did we get this right? 👍 / 👎 to inform future reviews.
options.setBeforeBreadcrumb( | ||
replayBreadcrumbConverter | ||
); |
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.
Potential bug: A user-configured BeforeBreadcrumbCallback
overwrites the SDK's replay converter during initialization, silently disabling network capture for replays.
-
Description: During
SentryAndroid.init()
, theDefaultReplayBreadcrumbConverter
is set as theBeforeBreadcrumbCallback
before the user's configuration callback is executed. If a user provides their ownBeforeBreadcrumbCallback
in the configuration, it replaces the SDK's converter. This breaks the replay feature's ability to capture network request data, as the logic inDefaultReplayBreadcrumbConverter
is never called. The feature fails silently for any user following the common practice of setting a breadcrumb callback. -
Suggested fix: Modify the initialization logic to chain the callbacks instead of overwriting. The
DefaultReplayBreadcrumbConverter
should be initialized with the user's callback, which is retrieved after the user's configuration has run. The converter would then execute the user's callback before its own logic.
severity: 0.7, confidence: 0.99
Did we get this right? 👍 / 👎 to inform future reviews.
NB - NOT READY TO LAND - Request For Feedback!!
📜 Description
Introduce data classes (
pkg=io.sentry.util.network
), following format in the javascript SDK.Inject this new data holder object (
NetworkRequestData
) into the breadcrumb Hint (only for sentry-okhttp for now).Set up
DefaultReplayBreadcrumbConverter
as the defaultBeforeBreadcrumbCallback
.^Anytime replayintegration is enabled,
DefaultReplayBreadcrumbConverter
will be theBeforeBreadcrumbCallback
, and responsible for delegating to any user-defined callback.Extract any breadcrumb Hint
NetworkRequestData
into the replayperformanceSpan
when creating the replay segment.TODOs
Feedbacks:
Hint
Implementation:
CLEANUP:
💡 Motivation and Context
Part of [Mobile Replay] Capture Network request/response bodies
Initially, we were trying to keep SDK changes simple and re-use the existing OKHTTP_REQUEST|RESPONSE hint data.
However, the
:sentry-android-replay
gradle module doesn't compile against any of the http libs (makes sense).Because these
okhttp3.Request
, etc types don't exist in:sentry-android-replay
, I switched to this PR where http modules (e.g.:sentry-okhttp
) will set the http breadcrumb hints using newly introduced API (under the:sentry
build target) which is also available to:sentry-android-replay
💚 How did you test it?
See gist of entire replay payload
See snippet corresponding to http performanceSpans (network request data)