Skip to content

[4.0] Migrate the OpenTelemetry extension to Vert.x 5#53755

Draft
cescoffier wants to merge 2 commits intoquarkusio:vertx-5-migrationfrom
cescoffier:vertx5-migrate-otel
Draft

[4.0] Migrate the OpenTelemetry extension to Vert.x 5#53755
cescoffier wants to merge 2 commits intoquarkusio:vertx-5-migrationfrom
cescoffier:vertx5-migrate-otel

Conversation

@cescoffier
Copy link
Copy Markdown
Member

  • Rework the context storage
  • Change how gRPC tracing is working as we do not have gRPC java anymore (so, we have both the gRPC and HTTP spans, all linked together)

In draft, as we are waiting for SmallRye GraphQL.

- Rework the context storage
- Change how gRPC tracing is working as we do not have gRPC java anymore (so, we have both the gRPC and HTTP spans, all linked together)
@quarkus-bot
Copy link
Copy Markdown

quarkus-bot Bot commented Apr 22, 2026

/cc @brunobat (opentelemetry), @radcortez (opentelemetry)

Copy link
Copy Markdown
Member

@jponge jponge left a comment

Choose a reason for hiding this comment

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

Great, but don't merge until smallrye-graphql has been released with a Vert.x 5 version upstream (/cc @jmartisk)

import io.quarkus.test.QuarkusExtensionTest;
import io.restassured.RestAssured;

@Disabled
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Note: re-enable once we have an smallrye-graphql Vert.x. 5 release upstream

if (route != null) {
requestMetric.getContext().ifPresent(context -> context.putLocal("VertxRoute", route));
requestMetric.getContext()
.ifPresent(context -> context.getLocal(VertxContext.DATA_MAP_LOCAL).put("VertxRoute", route));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just in case, add ConcurrentHashMap::new

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Weird, I was pretty sure to use the other API. Let me fix it.


private static final Logger log = Logger.getLogger(QuarkusContextStorage.class);
private static final String OTEL_CONTEXT = QuarkusContextStorage.class.getName() + ".otelContext";
private static final ContextLocal<Context> CONTEXT_OVERRIDE = ContextLocal.registerLocal(Context.class);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you have a VertxServiceProvider to ensure it's loaded on time?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hum, no, need to add it.

this.client = vertx.httpClientBuilder()
.with(httpClientOptions)
.with(httpClientOptions.getPoolOptions())
.with(new PoolOptions()) // TODO Do we want to customize pool options?
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are the default values equivalent to Vert.x 4?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes.

Copy link
Copy Markdown
Member

@brunobat brunobat Apr 22, 2026

Choose a reason for hiding this comment

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

Then we shouldn't customize the PoolOptions


private static final Logger log = Logger.getLogger(QuarkusContextStorage.class);
private static final String OTEL_CONTEXT = QuarkusContextStorage.class.getName() + ".otelContext";
private static final ContextLocal<Context> CONTEXT_OVERRIDE = ContextLocal.registerLocal(Context.class);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What's the difference between ContextLocal and VertxContext.localContextData(vertxContext) ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ContextLocal is the Vert.x 5 way to define context storage, in Vert.x 4 this used to be a big map for getLocal / putLocal access. Now we get a more fine-grained storage where each context storage can define what happens on duplication, etc.

VertxContext provides helpers in smallrye-common, especially the parent-child duplicated contexts we use in Quarkus.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Then... Will ContextLocal and VertxContext.localContextData(vertxContext) get the same data?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes

public void onClose(final Status status, final Metadata trailers) {
instrumenter.end(spanContext, grpcRequest, status, status.getCause());
try (scope) {
QuarkusContextStorage.clearContextOverride(Vertx.currentContext());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't understand this part.
Why do we need to clear the context in this particular case?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Because SR Context propagation was in the way and clear things that should not be cleared. So, I had to find something different.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I would like to find a way to avoid this - but, ran out of options/time.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok, Can you just add a comment in the method to when it should be used?

ConcurrentMap<String, Object> local = VertxContext.localContextData(vertxContext);
if (containsIgnoredKey(ignoredKeys, local)) {
// Duplicate the context, copy the data, remove the request context
ConcurrentHashMap<String, Object> mdcData = vertxContext.getLocal(VertxMDC.MDC_LOCAL);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why only with the VertxMDC.MDC_LOCAL?

@jponge jponge changed the title Migrate the OpenTelemetry extension to Vert.x 5 [4.0] Migrate the OpenTelemetry extension to Vert.x 5 Apr 22, 2026
@quarkus-bot
Copy link
Copy Markdown

quarkus-bot Bot commented Apr 22, 2026

Thanks for your pull request!

Your pull request does not follow our editorial rules. Could you have a look?

  • title should preferably start with an uppercase character (if it makes sense!)

This message is automatically generated by a bot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants