Skip to content

NO-TICKET: Upgrade Otel BOM dependency - #1683

Open
aditi-s3 wants to merge 15 commits into
developfrom
upgrade/otel-api
Open

NO-TICKET: Upgrade Otel BOM dependency#1683
aditi-s3 wants to merge 15 commits into
developfrom
upgrade/otel-api

Conversation

@aditi-s3

@aditi-s3 aditi-s3 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Title: Upgrade OTel dependencies

Description

Checklist

  • My code follows the project's coding standards.
  • I have run linters/formatters and fixed any issues.
  • There are no merge conflicts.
  • I have performed a self-review of my code.
  • All new and existing tests pass locally.
  • I have added license headers to all files.
  • (If applicable) I have added unit tests for my changes.
  • (If applicable) I have updated the sample app for integration testing.
  • (If applicable) I have updated any relevant documentation.

Generative AI usage

  • GAI was not used (or, no additional notation is required)
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • GAI was used to create a draft that was subsequently customized or modified
  • Code was generated entirely by GAI

How to Test These Changes

Launch a sample app with the latest changes and test

Future Considerations (Optional)

Need to track OTel updates and pro-actively identify risks/updates that should be included. Long term consider moving to Kotlin SDK ?

@aditi-s3 aditi-s3 changed the title Upgrade/otel api NO-TICKET: Upgrade/otel api Aug 24, 2026
@aditi-s3

Copy link
Copy Markdown
Contributor Author

@codex review

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.42105% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 11.51%. Comparing base (67da3c7) to head (8c09ccc).

Files with missing lines Patch % Lines
...m/agent/common/utils/PeerServiceMappingResolver.kt 68.75% 3 Missing and 7 partials ⚠️
...rash/internal/extractor/RuntimeDetailsExtractor.kt 0.00% 3 Missing ⚠️
...internal/OkHttpClientInstrumenterBuilderFactory.kt 0.00% 3 Missing ⚠️
...k/rum/agent/common/utils/InstrumenterBuildUtils.kt 0.00% 2 Missing ⚠️
...p3/auto/internal/PeerServiceAttributesExtractor.kt 84.61% 1 Missing and 1 partial ⚠️
...tion/interactions/InteractionsModuleIntegration.kt 0.00% 2 Missing ⚠️
...on/sessionreplay/SessionReplayModuleIntegration.kt 0.00% 2 Missing ⚠️
.../common/otel/logRecord/AndroidLogRecordExporter.kt 0.00% 0 Missing and 1 partial ⚠️
...on/auto/internal/PeerServiceAttributesExtractor.kt 92.30% 0 Missing and 1 partial ⚠️
...rum/integration/agent/internal/AgentIntegration.kt 0.00% 1 Missing ⚠️
... and 3 more
Additional details and impacted files
@@              Coverage Diff              @@
##             develop    #1683      +/-   ##
=============================================
+ Coverage       7.33%   11.51%   +4.17%     
- Complexity       166      234      +68     
=============================================
  Files            235      239       +4     
  Lines           4469     4534      +65     
  Branches         498      512      +14     
=============================================
+ Hits             328      522     +194     
+ Misses          4133     3987     -146     
- Partials           8       25      +17     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 3d44e5159f

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d44e5159f

ℹ️ 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".

Comment thread instrumentation/runtime/httpurlconnection-auto/build.gradle.kts
@aditi-s3 aditi-s3 changed the title NO-TICKET: Upgrade/otel api NO-TICKET: Upgrade Otel BOM dependency Aug 25, 2026
@aditi-s3

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 447d205d1c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 447d205d1c

ℹ️ 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".

Comment thread buildSrc/src/main/kotlin/Dependencies.kt
@aditi-s3
aditi-s3 marked this pull request as ready for review August 31, 2026 19:51
@aditi-s3
aditi-s3 requested a review from a team as a code owner August 31, 2026 19:51
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-10T18:59:10.259021Z 8c09ccc New commits
🔒 Security Review Completed 2026-09-10T18:57:33.147673Z 8c09ccc New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread docs/exec-plans/otel-api-1.62.md Outdated
Comment thread CHANGELOG.md Outdated
INSTRUMENTATION_NAME,
httpSpanNameExtractor
)
.setInstrumentationVersion(BuildConfig.VERSION_NAME)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Question - We've not been setting the instrumentationScopeInfo.version for any of our instrumentations (as it is same as rum.sdk.version) and just setting the instrumentationScopeInfo.name. Earlier http instrumentations were used from upstream so a instrumentationScopeInfo.version did help but may be not needed / redundant now?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@aditi-s3 Did you decide to keep this redundant attribute?

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aaa9fedc8a

ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82a1e679e9

ℹ️ 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".

Comment thread instrumentation/runtime/httpurlconnection-auto/build.gradle.kts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ae04569fce

ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd1ebccc87

ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95d951ec1b

ℹ️ 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".

Comment thread local.properties Outdated
}

log.attributes.asMap().forEach attrs@{ (key, value) ->
if (key.key == GlobalRumConstants.LOG_EVENT_NAME_KEY.key) {

@surbhiia surbhiia Sep 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we're preserving the fallback to event.name above, we need to preserve this block here to ensure event.name attribute is not added to the span as it's job is already done above - i.e supplying the span.name

But a neater solution is to remove line 98 above as we're no longer using event.name attribute anywhere now. Also remove the GlobalRumConstant LOG_EVENT_NAME_KEY as it won't be used anymore.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I had the neater solution initially but Codex review comment #1683 (comment) prompted me to change it back. But yes added the block to skip adding it as a span attribute.

}

@Test
fun `a custom extractor cannot override the crash event name`() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This test is no longer needed and can be removed.

}
}

// HttpUrlConnectionSingletons and OkHttpSingletons disable the instrumenter SPI lookup

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: Remove this comment. It's confusing here. You already added comments where you suppressed the SPI lookup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It was intentional to indicate why we are not doing a centralized override. But removed it


/** Extracts the configured `peer.service` mapping for auto-instrumented OkHttp requests. */
internal class PeerServiceAttributesExtractor(
private val attributesGetter: ServerAttributesGetter<Interceptor.Chain>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not use the super type :

Suggested change
private val attributesGetter: ServerAttributesGetter<Interceptor.Chain>,
private val attributesGetter: HttpClientAttributesGetter<Interceptor.Chain, Response>,

And also get the path on line 52 using the following instead of passing null:

attributesGetter.getUrlFull(request)


val instrumenter: Instrumenter<Interceptor.Chain, Response> = instrumenterBuilder.build()
// Avoid the instrumenter SPI lookup's one-time disk read, which trips Android StrictMode
// (see open-telemetry/opentelemetry-java-instrumentation#19954).

@surbhiia surbhiia Sep 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: it does not tell you whether to look at the PR #19954 or issue #19954, a link would be helpful. I couldn't search it, don't know why it doesn't pull up easily while searching in search bar (screenshot below)

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added word "issue" to the comments. You are searching PRs in the screenshot so no results were returned

// Null unless the caller opts in via setSpanNameExtractor().
private Function<SpanNameExtractor<Interceptor.Chain>, SpanNameExtractor<Interceptor.Chain>>
spanNameExtractorTransformer;
private Map<String, String> peerServiceMapping = java.util.Collections.emptyMap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
private Map<String, String> peerServiceMapping = java.util.Collections.emptyMap();
private Map<String, String> peerServiceMapping = Collections.emptyMap();

* Configures the extractor of the {@code peer.service} span attribute.
*/
public OkHttpTelemetryBuilder setPeerServiceMapping(Map<String, String> peerServiceMapping) {
this.peerServiceMapping = new java.util.HashMap<>(peerServiceMapping);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
this.peerServiceMapping = new java.util.HashMap<>(peerServiceMapping);
this.peerServiceMapping = HashMap<>(peerServiceMapping);

OkHttpClientInstrumenterBuilderFactory.create(openTelemetry);
builder.addAttributesExtractor(
new PeerServiceAttributesExtractor(
com.splunk.rum.instrumentation.okhttp3.common.internal.OkHttpAttributesGetter.INSTANCE,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
com.splunk.rum.instrumentation.okhttp3.common.internal.OkHttpAttributesGetter.INSTANCE,
OkHttpAttributesGetter.INSTANCE,

try {
builder.buildClientInstrumenter(RequestPropertySetter)
} finally {
ServiceLoaderUtil.setLoadFunction { serviceType -> ServiceLoader.load(serviceType) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure this can actually restore anything. ServiceLoaderUtil has no getter, only load and
setLoadFunction so we just overwrite with a fresh ServiceLoader::load. If a host app or
another OTel library had its own load function then I think its gone permanently.

Maybe can consider setting the override once, and gate it on a ThreadLocal so only our building thread sees the empty list. That closes the concurrent-build hole and clobbers the host once instead of every
build. Might be worth asking for a getter on #19954.

Also, lines 89 and 93 call into io.opentelemetry.instrumentation.api.internal ,
which is marked "This class is internal and is hence not for public use. Its APIs are
unstable and can change at any time"

https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/v2.30.0/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ServiceLoaderUtil.java#L11-L14

We export the BOM via api(platform(...)), so I worry that a host forcing a different
opentelemetry-instrumentation-api can hypothetically make setLoadFunction vanish: NoSuchMethodError out of install() on the main thread, i.e. the customer's app won't start.

Maybe we should catch LinkageError and then fall back to a normal build turns that into a StrictMode warning. This is the one thing e2e testing may not cover, since e2e ran against our own dependency graph.

@aditi-s3 aditi-s3 Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated comment to clarify there is no restoration

@tonzhan2 I am not inclined to increase the complexity of a temporary workaround with ThreadLocal. Limiting the window of override is okay I think.

I took your recommendation to catch errors for when setLoadFunction is unavailable in case of a competing OTel dependency.

Comment on lines +171 to +173
// Isolated so Function#apply (requires API 24 or desugaring) only runs when a caller opts in
// via setSpanNameExtractor(), not on every build() call.
@SuppressLint("NewApi") // This existing java.util.function API requires consumer desugaring.

@surbhiia surbhiia Sep 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In our SDK we use a simple comment :

Suggested change
// Isolated so Function#apply (requires API 24 or desugaring) only runs when a caller opts in
// via setSpanNameExtractor(), not on every build() call.
@SuppressLint("NewApi") // This existing java.util.function API requires consumer desugaring.
@SuppressLint("NewApi") // Requires API 24 or core library desugaring

try {
instrumenterBuilder.build()
} finally {
ServiceLoaderUtil.setLoadFunction { serviceType -> ServiceLoader.load(serviceType) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same thing as my comment on HttpUrlConnectionSingletons, maybe catch a linkageError then fall back to a normal build turns that into a StrictMode warning.

try {
return builder.build();
} finally {
ServiceLoaderUtil.setLoadFunction(ServiceLoader::load);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same thing as my comment on HttpUrlConnectionSingletons, maybe catch a linkageError then fall back to a normal build turns that into a StrictMode warning.

try {
builder.buildClientInstrumenter(RequestPropertySetter)
} finally {
ServiceLoaderUtil.setLoadFunction { serviceType -> ServiceLoader.load(serviceType) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Question - Are we sure that this restores the behavior? Do we need to restore it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It does not - updated the comments.

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.

3 participants