diff --git a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/NettySslInstrumentationHandler.java b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/NettySslInstrumentationHandler.java index b52e7c4e6e4a..b63260246ce1 100644 --- a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/NettySslInstrumentationHandler.java +++ b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/NettySslInstrumentationHandler.java @@ -8,6 +8,8 @@ import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; import io.opentelemetry.context.Context; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -75,17 +77,7 @@ public void connect( // netty SslHandler starts the handshake after it receives the channelActive() signal; this // happens just after the connection is established // this makes connect() promise a good place to start the SSL handshake span - promise.addListener( - future -> { - // there won't be any SSL handshake if the channel fails to connect - if (!future.isSuccess()) { - return; - } - request = NettySslRequest.create(ctx.channel()); - if (instrumenter.shouldStart(parentContext, request)) { - context = instrumenter.start(parentContext, request); - } - }); + promise.addListener(new StartListener(ctx)); ctx.connect(remoteAddress, localAddress, promise); } @@ -112,4 +104,25 @@ private static Throwable getCause(Object evt) { return null; } } + + private class StartListener implements GenericFutureListener> { + + private final ChannelHandlerContext ctx; + + private StartListener(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + @Override + public void operationComplete(Future future) { + // there won't be any SSL handshake if the channel fails to connect + if (!future.isSuccess()) { + return; + } + request = NettySslRequest.create(ctx.channel()); + if (instrumenter.shouldStart(parentContext, request)) { + context = instrumenter.start(parentContext, request); + } + } + } } diff --git a/instrumentation/netty/netty-4.1-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/InstrumentedAddressResolverGroup.java b/instrumentation/netty/netty-4.1-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/InstrumentedAddressResolverGroup.java index 3607fce2e83d..8fb635ad550e 100644 --- a/instrumentation/netty/netty-4.1-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/InstrumentedAddressResolverGroup.java +++ b/instrumentation/netty/netty-4.1-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/InstrumentedAddressResolverGroup.java @@ -9,6 +9,7 @@ import io.netty.resolver.AddressResolverGroup; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.Promise; import io.opentelemetry.context.Context; import io.opentelemetry.javaagent.instrumentation.netty.common.NettyConnectionRequest; @@ -106,7 +107,7 @@ private Future instrumentResolve( Context context = instrumenter.start(parentContext, request); try { Future future = resolveFunc.get(); - return future.addListener(f -> instrumenter.end(context, request, null, f.cause())); + return future.addListener(new OnEndListener<>(request, context)); } catch (Throwable t) { instrumenter.end(context, request, null, t); throw t; @@ -117,5 +118,22 @@ private Future instrumentResolve( public void close() { delegate.close(); } + + // currently cannot use lambda for this + private class OnEndListener implements GenericFutureListener> { + + private final NettyConnectionRequest request; + private final Context context; + + private OnEndListener(NettyConnectionRequest request, Context context) { + this.request = request; + this.context = context; + } + + @Override + public void operationComplete(Future future) { + instrumenter.end(context, request, null, future.cause()); + } + } } }