RUM-13441: [Cronet] Migrating okHttp to new instrumentation API#3180
RUM-13441: [Cronet] Migrating okHttp to new instrumentation API#3180
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 57939dbb75
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| val tracingState = registry.update(call) { _, state -> | ||
| apmNetworkInstrumentation.onRequest(state.requestInfo) |
There was a problem hiding this comment.
Trace the current network request instead of cached state
RequestTracingStateRegistry.register() stores call.request() only once, but this interceptor later calls onRequest(state.requestInfo) and then proceeds with tracingState.requestInfo. For redirects/retries (where OkHttp invokes network interceptors again with a follow-up request) or when earlier interceptors mutate the request, this reuses a stale request and can drop URL/header/body changes (for example auth/signature headers), causing incorrect outbound calls and spans. The tracing state should be refreshed from chain.request() on each intercept.
Useful? React with 👍 / 👎.
| val requestInfo = registry.get(call)?.requestInfo | ||
| val okHttpRequest = (requestInfo as? OkHttpRequestInfo)?.originalRequest |
There was a problem hiding this comment.
Proceed RUM interception with the live chain request
This adapter reads requestInfo from the registry (initialized from call.request() before application interceptors run) and then calls chain.proceed(okHttpRequest), so any request mutations made by interceptors earlier in the chain are discarded. In practice, headers or URL rewrites added upstream can be lost, which can break authenticated requests and make RUM track a different request than the one the app intended to send. Use chain.request() as the source of truth and keep the registry for correlation metadata only.
Useful? React with 👍 / 👎.
8f048a3 to
91ec6c5
Compare
57939db to
404f86e
Compare
|
|
||
| @Test | ||
| @Repeat(10) | ||
| fun executionResultsMustBeSimilarWhen_rateLimited_okhttp_comparison() = asyncTest { |
There was a problem hiding this comment.
Seems the unit test is testing the equality not similarity, if so it should be renamed to executionResultsMustBeSameWhen_rateLimited_okhttp_comparison. Also, is it needed to execute 10 times on CI?
There was a problem hiding this comment.
This test tests that different instrumentation produces similar spans for requests. Technically speaking they are not 100% same (because spanId and traceId are unique), but spans structure (parent-child) structure, some http attributes (status codes, url, etc) should be the same. So it's called "similar". Let me know if you think this is confusing
...khttp/src/main/kotlin/com/datadog/android/okhttp/internal/ApmInstrumentationOkHttpAdapter.kt
Outdated
Show resolved
Hide resolved
...id-okhttp/src/main/kotlin/com/datadog/android/okhttp/internal/RequestTracingStateRegistry.kt
Outdated
Show resolved
Hide resolved
.../dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/OkHttpIntegrationPlugin.kt
Outdated
Show resolved
Hide resolved
.../dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/OkHttpIntegrationPlugin.kt
Show resolved
Hide resolved
...http/src/main/kotlin/com/datadog/android/okhttp/internal/RumInstrumentationTimingsCounter.kt
Show resolved
Hide resolved
cb8e557 to
62046e7
Compare
d4a5e23 to
f3b2a1e
Compare
404f86e to
bc7f3d2
Compare
…changes RUM-13441: Migrating okHttp to new instrumentation API
bc7f3d2 to
9e872b7
Compare
...ndroid-rum/src/main/kotlin/com/datadog/android/rum/internal/net/RumNetworkInstrumentation.kt
Show resolved
Hide resolved
.../dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/OkHttpIntegrationPlugin.kt
Show resolved
Hide resolved
...khttp/src/main/kotlin/com/datadog/android/okhttp/internal/ApmInstrumentationOkHttpAdapter.kt
Show resolved
Hide resolved
...sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/OkHttpIntegrationPluginTest.kt
Show resolved
Hide resolved
...p/src/test/kotlin/com/datadog/android/okhttp/internal/ApmInstrumentationOkHttpAdapterTest.kt
Show resolved
Hide resolved
...id-okhttp/src/main/kotlin/com/datadog/android/okhttp/internal/RequestTracingStateRegistry.kt
Show resolved
Hide resolved
...p/src/test/kotlin/com/datadog/android/okhttp/internal/ApmInstrumentationOkHttpAdapterTest.kt
Show resolved
Hide resolved
| */ | ||
| @ExperimentalTraceApi | ||
| @ExperimentalRumApi | ||
| fun OkHttpClient.Builder.configureDatadogInstrumentation( |
There was a problem hiding this comment.
We need to deprecate then existing interceptors in favor of this
There was a problem hiding this comment.
I would do that after dogfooding (before release) in a separate PR
...khttp/src/test/kotlin/com/datadog/android/okhttp/internal/RequestTracingStateRegistryTest.kt
Show resolved
Hide resolved
...khttp/src/test/kotlin/com/datadog/android/okhttp/internal/RequestTracingStateRegistryTest.kt
Show resolved
Hide resolved
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e872b76aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
.../dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/OkHttpIntegrationPlugin.kt
Show resolved
Hide resolved
| val taggedRequest = OkHttpRequestInfoBuilder(call.request().newBuilder()) | ||
| .addTag(UUID::class.java, UUID.randomUUID()) | ||
|
|
||
| requestTracingStateByCall[call] = RequestTracingState(taggedRequest) |
There was a problem hiding this comment.
Track RUM state from post-interceptor request
The registry is initialized from call.request() before application interceptors run, and in RUM-only mode there is no subsequent registry.update(...) to refresh it with the final request seen by RumInstrumentationOkHttpAdapter.startResource(...). If an upstream app interceptor rewrites method/URL/body, timing events (sendWaitForResourceTimingEvent / sendTiming) are emitted with a different resource key than the started resource, so resource timing can be dropped for those calls.
Useful? React with 👍 / 👎.
| ) { | ||
| internal val method: String | ||
| get() = requestParams.method | ||
|
|
| assertThat(engine.distributedTracingInstrumentation).isNull() | ||
| } | ||
|
|
||
| @OptIn(ExperimentalRumApi::class) |
There was a problem hiding this comment.
Is this needed? The CronetIntegrationPluginTest class already has this annotation.
What does this PR do?
OkHttpinstrumentation to the new networking-library agnostic approach.DatadogInterceptor/TracingInterceptor/DatadogEventListenerapproach (all classes kept for the backward compatibility)
with a single unified entry point:
same as for Cronet
Motivation
Review checklist (to be filled by reviewers)