Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support globalHubMode for OpenTelemetry #4349

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

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

adinauer
Copy link
Member

We're planning to release an alpha version from this branch so this PR shouldn't be merged to main yet.

📜 Description

  • Always returns a wrapped Context from OpenTelemetry ContextStorage if globalHubMode is enabled
  • Returns the last known unfinished root span / transaction from Context.get if there is no (valid) span stored on the context

💡 Motivation and Context

Using Sentry with OpenTelemetry for Java Desktop apps where customers have no control over their scheduling requires globalHubMode to ensure e.g. outgoing HTTP client spans are attached to the root span / transaction that is currently running.

Without this fix, HTTP client spans are recorded as separate Sentry transactions due to OpenTelemetry Context not being propagated e.g. when using new Thread(new Runnable() { ... }).start().

To fix this it's also possible to manually transfer the OpenTelemetry Context but not every customer has control over their scheduling:

    private void fetchTodo() {
        fetchButton.setEnabled(false);

        final Context opentelemetryContext = Context.current(); // <----------------- remember Context ------------------------

        Runnable r = new Runnable() {
            @Override
            public void run() {
                try (Scope scope = opentelemetryContext.makeCurrent()) {   // <------------------ make Context current in thread -----------------------
                    HttpClient client = HttpClient.newHttpClient();
                    HttpRequest request = HttpRequest.newBuilder()
                            .uri(URI.create("https://jsonplaceholder.typicode.com/todos/1"))
                            .build();

                    try {
                        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
                        String prettyJson = gson.toJson(
                                gson.fromJson(response.body(), Object.class)
                        );
                        resultArea.setText(prettyJson);
                    } catch (Exception e) {
                        resultArea.setText("Error: " + e.getMessage());
                    } finally {
                        fetchButton.setEnabled(true);
                    }
                }
            }
        };
        new Thread(r).start();
    }

💚 How did you test it?

📝 Checklist

  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

Copy link
Contributor

github-actions bot commented Apr 22, 2025

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against be70b9d

if (Sentry.isGlobalHubMode()) {
if (result == null
|| (result instanceof Span && !((Span) result).getSpanContext().isValid())) {
if (isOpentelemetrySpan(contextKey)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Played around with this too much. It should check whether the key refers to a Span earlier.

Copy link
Contributor

github-actions bot commented Apr 22, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 421.76 ms 456.98 ms 35.22 ms
Size 1.58 MiB 2.08 MiB 507.93 KiB

Previous results on branch: feat/experimental-otel-global-hub-mode

Startup times

Revision Plain With Sentry Diff
e3d2723 425.58 ms 481.35 ms 55.76 ms
fef532b 444.25 ms 466.31 ms 22.06 ms
d0dccd7 399.63 ms 437.92 ms 38.29 ms
bdc74cc 531.79 ms 677.23 ms 145.44 ms
0eb29b3 431.80 ms 455.50 ms 23.70 ms
0d57111 387.49 ms 414.13 ms 26.64 ms
0f2f4fd 395.67 ms 444.42 ms 48.75 ms
9ab9244 449.06 ms 501.39 ms 52.33 ms
53db701 399.88 ms 423.54 ms 23.66 ms

App size

Revision Plain With Sentry Diff
e3d2723 1.58 MiB 2.08 MiB 507.28 KiB
fef532b 1.58 MiB 2.08 MiB 507.45 KiB
d0dccd7 1.58 MiB 2.08 MiB 507.67 KiB
bdc74cc 1.58 MiB 2.08 MiB 507.34 KiB
0eb29b3 1.58 MiB 2.08 MiB 507.44 KiB
0d57111 1.58 MiB 2.08 MiB 507.45 KiB
0f2f4fd 1.58 MiB 2.08 MiB 507.44 KiB
9ab9244 1.58 MiB 2.08 MiB 507.92 KiB
53db701 1.58 MiB 2.08 MiB 507.28 KiB

Copy link
Collaborator

@lbloder lbloder left a comment

Choose a reason for hiding this comment

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

Minor comment about param naming.
Otherwise LGTM 👍

}

private <V> boolean shouldReturnRootSpanInstead(
final @NotNull ContextKey<V> contextKey, final @Nullable V result) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

(l) not sure about the param naming. Would something other than result be more fitting?

}

@SuppressWarnings("unchecked")
private <V> @Nullable V returnUnfinishedRootSpanIfAvailable(final @Nullable V result) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

(l) not sure about the param naming. Would something other than result be more fitting?


### Features

- Support `globalHubMode` for OpenTelemetry ([#4349](https://github.com/getsentry/sentry-java/pull/4349))
Copy link
Contributor

Choose a reason for hiding this comment

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

  • 🚫 The changelog entry seems to be part of an already released section ## 8.11.0.
    Consider moving the entry to the ## Unreleased section, please.

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