Netty: add exception to span
MODIFY
instrumentation/netty/netty-3.8/javaagent/src/latestDepTest/groovy/Netty38ServerTest.groovy
instrumentation/netty/netty-3.8/javaagent/src/latestDepTest/groovy/Netty38ServerTest.groovy
@@ -144,10 +144,4 @@ class Netty38ServerTest extends HttpServerTest<ServerBootstrap> {
String expectedServerSpanName(ServerEndpoint endpoint) {
return "netty.request"
}
-
- @Override
- boolean testException() {
- // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/807
- return false
- }
}

ADD
instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/DefaultChannelPipelineInstrumentation.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.netty.v3_8;
+
+import static io.opentelemetry.javaagent.instrumentation.netty.v3_8.server.NettyHttpServerTracer.tracer;
+import static java.util.Collections.singletonMap;
+import static net.bytebuddy.matcher.ElementMatchers.isMethod;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
+import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
+import java.util.Map;
+import net.bytebuddy.asm.Advice;
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+public class DefaultChannelPipelineInstrumentation implements TypeInstrumentation {
+
+ @Override
+ public ElementMatcher<TypeDescription> typeMatcher() {
+ return named("org.jboss.netty.channel.DefaultChannelPipeline");
+ }
+
+ @Override
+ public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
+ return singletonMap(
+ isMethod()
+ .and(named("notifyHandlerException"))
+ .and(takesArgument(1, named(Throwable.class.getName()))),
+ DefaultChannelPipelineInstrumentation.class.getName() + "$NotifyHandlerExceptionAdvice");
+ }
+
+ public static class NotifyHandlerExceptionAdvice {
+ @Advice.OnMethodEnter
+ public static void onEnter(@Advice.Argument(1) Throwable throwable) {
+ Span span = Java8BytecodeBridge.currentSpan();
+ if (span.getSpanContext().isValid() && throwable != null) {
+ tracer().addThrowable(span, throwable);
+ }
+ }
+ }
+}

MODIFY
instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java
instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java
@@ -25,7 +25,8 @@ public class NettyInstrumentationModule extends InstrumentationModule {
return asList(
new ChannelFutureListenerInstrumentation(),
new NettyChannelInstrumentation(),
- new NettyChannelPipelineInstrumentation());
+ new NettyChannelPipelineInstrumentation(),
+ new DefaultChannelPipelineInstrumentation());
}
@Override

MODIFY
instrumentation/netty/netty-3.8/javaagent/src/test/groovy/Netty38ServerTest.groovy
instrumentation/netty/netty-3.8/javaagent/src/test/groovy/Netty38ServerTest.groovy
@@ -144,10 +144,4 @@ class Netty38ServerTest extends HttpServerTest<ServerBootstrap> {
String expectedServerSpanName(ServerEndpoint endpoint) {
return "netty.request"
}
-
- @Override
- boolean testException() {
- // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/807
- return false
- }
}

ADD
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/AbstractChannelHandlerContextInstrumentation.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.netty.v4_0;
+
+import static io.opentelemetry.javaagent.instrumentation.netty.v4_0.server.NettyHttpServerTracer.tracer;
+import static java.util.Collections.singletonMap;
+import static net.bytebuddy.matcher.ElementMatchers.isMethod;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
+import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
+import java.util.Map;
+import net.bytebuddy.asm.Advice;
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+public class AbstractChannelHandlerContextInstrumentation implements TypeInstrumentation {
+
+ @Override
+ public ElementMatcher<TypeDescription> typeMatcher() {
+ return named("io.netty.channel.AbstractChannelHandlerContext");
+ }
+
+ @Override
+ public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
+ return singletonMap(
+ isMethod()
+ .and(named("notifyHandlerException"))
+ .and(takesArgument(0, named(Throwable.class.getName()))),
+ AbstractChannelHandlerContextInstrumentation.class.getName()
+ + "$NotifyHandlerExceptionAdvice");
+ }
+
+ public static class NotifyHandlerExceptionAdvice {
+ @Advice.OnMethodEnter
+ public static void onEnter(@Advice.Argument(0) Throwable throwable) {
+ Span span = Java8BytecodeBridge.currentSpan();
+ if (span.getSpanContext().isValid() && throwable != null) {
+ tracer().addThrowable(span, throwable);
+ }
+ }
+ }
+}

MODIFY
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java
@@ -21,6 +21,8 @@ public class NettyInstrumentationModule extends InstrumentationModule {
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
- new ChannelFutureListenerInstrumentation(), new NettyChannelPipelineInstrumentation());
+ new ChannelFutureListenerInstrumentation(),
+ new NettyChannelPipelineInstrumentation(),
+ new AbstractChannelHandlerContextInstrumentation());
}
}

MODIFY
instrumentation/netty/netty-4.0/javaagent/src/test/groovy/Netty40ServerTest.groovy
instrumentation/netty/netty-4.0/javaagent/src/test/groovy/Netty40ServerTest.groovy
@@ -116,10 +116,4 @@ class Netty40ServerTest extends HttpServerTest<EventLoopGroup> {
String expectedServerSpanName(ServerEndpoint endpoint) {
return "netty.request"
}
-
- @Override
- boolean testException() {
- // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/807
- return false
- }
}

ADD
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/AbstractChannelHandlerContextInstrumentation.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
+
+import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.server.NettyHttpServerTracer.tracer;
+import static java.util.Collections.singletonMap;
+import static net.bytebuddy.matcher.ElementMatchers.isMethod;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
+import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
+import java.util.Map;
+import net.bytebuddy.asm.Advice;
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+public class AbstractChannelHandlerContextInstrumentation implements TypeInstrumentation {
+
+ @Override
+ public ElementMatcher<TypeDescription> typeMatcher() {
+ return named("io.netty.channel.AbstractChannelHandlerContext");
+ }
+
+ @Override
+ public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
+ return singletonMap(
+ isMethod()
+ .and(named("notifyHandlerException"))
+ .and(takesArgument(0, named(Throwable.class.getName()))),
+ AbstractChannelHandlerContextInstrumentation.class.getName()
+ + "$NotifyHandlerExceptionAdvice");
+ }
+
+ public static class NotifyHandlerExceptionAdvice {
+ @Advice.OnMethodEnter
+ public static void onEnter(@Advice.Argument(0) Throwable throwable) {
+ Span span = Java8BytecodeBridge.currentSpan();
+ if (span.getSpanContext().isValid() && throwable != null) {
+ tracer().addThrowable(span, throwable);
+ }
+ }
+ }
+}

MODIFY
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java
@@ -21,6 +21,8 @@ public class NettyInstrumentationModule extends InstrumentationModule {
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
- new ChannelFutureListenerInstrumentation(), new NettyChannelPipelineInstrumentation());
+ new ChannelFutureListenerInstrumentation(),
+ new NettyChannelPipelineInstrumentation(),
+ new AbstractChannelHandlerContextInstrumentation());
}
}

MODIFY
instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ServerTest.groovy
instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ServerTest.groovy
@@ -115,10 +115,4 @@ class Netty41ServerTest extends HttpServerTest<EventLoopGroup> {
String expectedServerSpanName(ServerEndpoint endpoint) {
return "netty.request"
}
-
- @Override
- boolean testException() {
- // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/807
- return false
- }
}

Netty: add exception to span (#2027)