-
Notifications
You must be signed in to change notification settings - Fork 344
Fix for Vert.x 4.0 instrumentation to close span on timeout #5772
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| package datadog.trace.instrumentation.vertx_4_0.client; | ||
|
|
||
| import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; | ||
| import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; | ||
| import static datadog.trace.bootstrap.instrumentation.httpurlconnection.HttpUrlConnectionDecorator.DECORATE; | ||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
| import static net.bytebuddy.matcher.ElementMatchers.isPackagePrivate; | ||
| import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
|
||
| import com.google.auto.service.AutoService; | ||
| import datadog.trace.agent.tooling.Instrumenter; | ||
| import datadog.trace.bootstrap.instrumentation.api.AgentScope; | ||
| import datadog.trace.bootstrap.instrumentation.api.AgentSpan; | ||
| import datadog.trace.instrumentation.netty41.AttributeKeys; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be declared as a helper class here as well?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, otherwise it'll fail at muzzle check |
||
| import io.vertx.core.http.impl.HttpClientStream; | ||
| import net.bytebuddy.asm.Advice; | ||
|
|
||
| @AutoService(Instrumenter.class) | ||
| public class HttpClientRequestBaseInstrumentation extends Instrumenter.Tracing | ||
| implements Instrumenter.ForKnownTypes { | ||
| static final String[] CONCRETE_TYPES = { | ||
| "io.vertx.core.http.impl.HttpClientRequestImpl", | ||
| "io.vertx.core.http.impl.HttpClientRequestPushPromise" | ||
| }; | ||
|
|
||
| public HttpClientRequestBaseInstrumentation() { | ||
| super("vertx", "vertx-4.0"); | ||
| } | ||
|
|
||
| @Override | ||
| public String[] helperClassNames() { | ||
| return new String[] {"datadog.trace.instrumentation.netty41.AttributeKeys"}; | ||
| } | ||
|
|
||
| @Override | ||
| public void adviceTransformations(AdviceTransformation transformation) { | ||
| transformation.applyAdvice( | ||
| isMethod() | ||
| .and(isPackagePrivate()) | ||
| .and(named("reset")) | ||
| .and(takesArgument(0, named("java.lang.Throwable"))), | ||
| HttpClientRequestBaseInstrumentation.class.getName() + "$ResetAdvice"); | ||
| } | ||
|
|
||
| @Override | ||
| public String[] knownMatchingTypes() { | ||
| return CONCRETE_TYPES; | ||
| } | ||
|
|
||
| public static class ResetAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void onExit( | ||
| @Advice.Argument(value = 0) Throwable cause, | ||
| @Advice.FieldValue("stream") final HttpClientStream stream, | ||
| @Advice.Return(readOnly = false) boolean result) { | ||
| if (result) { | ||
| AgentSpan nettySpan = | ||
| stream.connection().channel().attr(AttributeKeys.SPAN_ATTRIBUTE_KEY).get(); | ||
| if (nettySpan != null) { | ||
| try (final AgentScope scope = activateSpan(nettySpan)) { | ||
| DECORATE.onError(scope, cause); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,10 @@ abstract class HttpClientTest extends VersionedNamingTestBase { | |
| .addHeader('x-datadog-test-response-header', 'baz') | ||
| .send(msg) | ||
| } | ||
| prefix("/timeout") { | ||
| Thread.sleep(10_000) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have to wait for 10 seconds? Could we make the timeouts shorter in the tests?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, we don't have to wait. The whole point for this endpoint is to prevent it responding. The client is supposed to cancel it earlier in this case it's 1s. Unless test is incorrect and the client doesn't cancel within shorter interval then it will wait for at max 10 seconds and then fail. |
||
| throw new IllegalStateException("Should never happen") | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
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.
I guess this is to ensure that the netty versions behave the same, since vertx seem to need netty 4.1.
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.
Correct, Vert.x uses Netty 4.1. I added this for Netty 4.0 too just because there might be a similar to Vert.x case leading to an unfinished span. Making sure we finish it here will potentially prevent this type of an issue.