Netty: add exception to span (#2027)

This commit is contained in:
Lauri Tulmin 2021-01-14 19:36:14 +02:00 committed by GitHub
parent 99bcf7dcf2
commit 2a4e07dce1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 154 additions and 27 deletions

View File

@ -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
}
}

View File

@ -0,0 +1,48 @@
/*
* 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);
}
}
}
}

View File

@ -25,7 +25,8 @@ public class NettyInstrumentationModule extends InstrumentationModule {
return asList(
new ChannelFutureListenerInstrumentation(),
new NettyChannelInstrumentation(),
new NettyChannelPipelineInstrumentation());
new NettyChannelPipelineInstrumentation(),
new DefaultChannelPipelineInstrumentation());
}
@Override

View File

@ -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
}
}

View File

@ -0,0 +1,49 @@
/*
* 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);
}
}
}
}

View File

@ -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());
}
}

View File

@ -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
}
}

View File

@ -0,0 +1,49 @@
/*
* 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);
}
}
}
}

View File

@ -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());
}
}

View File

@ -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
}
}