Split out :instrumentation:netty:netty-4.1 library (#6820)
Resolves #6734. Builds on #6811.
This commit is contained in:
parent
77035fc88c
commit
d5aadbab04
|
@ -153,6 +153,11 @@ public abstract class AbstractNettyChannelPipelineInstrumentation implements Typ
|
|||
.getName()
|
||||
.startsWith("io.opentelemetry.javaagent.instrumentation.netty.")) {
|
||||
pipeline.removeLast();
|
||||
} else if (handler
|
||||
.getClass()
|
||||
.getName()
|
||||
.startsWith("io.opentelemetry.instrumentation.netty.")) {
|
||||
pipeline.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4.common.internal;
|
||||
package io.opentelemetry.instrumentation.netty.v4.common;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import io.netty.channel.Channel;
|
||||
|
@ -11,23 +11,29 @@ import io.netty.handler.codec.http.HttpRequest;
|
|||
import java.net.SocketAddress;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
/** A tuple of an {@link HttpRequest} and a {@link Channel}. */
|
||||
@AutoValue
|
||||
public abstract class HttpRequestAndChannel {
|
||||
|
||||
/** Create a new {@link HttpRequestAndChannel}. */
|
||||
public static HttpRequestAndChannel create(HttpRequest request, Channel channel) {
|
||||
return new AutoValue_HttpRequestAndChannel(request, channel, channel.remoteAddress());
|
||||
}
|
||||
|
||||
/** Returns the {@link HttpRequest}. */
|
||||
public abstract HttpRequest request();
|
||||
|
||||
/** Returns the {@link Channel}. */
|
||||
public abstract Channel channel();
|
||||
|
||||
// we're capturing the remote address early because in case of timeouts or other connection issues
|
||||
// netty may return null when calling Channel.remoteAddress() at the end of processing
|
||||
/**
|
||||
* Return the {@link Channel#remoteAddress()} present when this {@link HttpRequestAndChannel} was
|
||||
* created.
|
||||
*
|
||||
* <p>We capture the remote address early because netty may return null when calling {@link
|
||||
* Channel#remoteAddress()} at the end of processing in cases of timeouts or other connection
|
||||
* issues.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract SocketAddress remoteAddress();
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.instrumentation.netty.v4.common.internal;
|
||||
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
package io.opentelemetry.instrumentation.netty.v4.common.internal.client;
|
||||
|
||||
import io.opentelemetry.context.propagation.TextMapSetter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
|
||||
enum HttpRequestHeadersSetter implements TextMapSetter<HttpRequestAndChannel> {
|
||||
INSTANCE;
|
||||
|
|
|
@ -7,7 +7,8 @@ package io.opentelemetry.instrumentation.netty.v4.common.internal.client;
|
|||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
|
@ -19,7 +20,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributes
|
|||
import io.opentelemetry.instrumentation.api.instrumenter.net.PeerServiceAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.HttpClientSpanKeyAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.NettyConnectionRequest;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -29,35 +30,36 @@ import java.util.Map;
|
|||
*/
|
||||
public final class NettyClientInstrumenterFactory {
|
||||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
private final String instrumentationName;
|
||||
private final boolean connectionTelemetryEnabled;
|
||||
private final boolean sslTelemetryEnabled;
|
||||
private final List<String> capturedRequestHeaders;
|
||||
private final List<String> capturedResponseHeaders;
|
||||
private final Map<String, String> peerServiceMapping;
|
||||
|
||||
public NettyClientInstrumenterFactory(
|
||||
OpenTelemetry openTelemetry,
|
||||
String instrumentationName,
|
||||
boolean connectionTelemetryEnabled,
|
||||
boolean sslTelemetryEnabled,
|
||||
List<String> capturedRequestHeaders,
|
||||
List<String> capturedResponseHeaders,
|
||||
Map<String, String> peerServiceMapping) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
this.instrumentationName = instrumentationName;
|
||||
this.connectionTelemetryEnabled = connectionTelemetryEnabled;
|
||||
this.sslTelemetryEnabled = sslTelemetryEnabled;
|
||||
this.capturedRequestHeaders = capturedRequestHeaders;
|
||||
this.capturedResponseHeaders = capturedResponseHeaders;
|
||||
this.peerServiceMapping = peerServiceMapping;
|
||||
}
|
||||
|
||||
public Instrumenter<HttpRequestAndChannel, HttpResponse> createHttpInstrumenter() {
|
||||
public Instrumenter<HttpRequestAndChannel, HttpResponse> createHttpInstrumenter(
|
||||
List<String> capturedRequestHeaders,
|
||||
List<String> capturedResponseHeaders,
|
||||
List<AttributesExtractor<HttpRequestAndChannel, HttpResponse>>
|
||||
additionalHttpAttributeExtractors) {
|
||||
NettyHttpClientAttributesGetter httpClientAttributesGetter =
|
||||
new NettyHttpClientAttributesGetter();
|
||||
NettyNetClientAttributesGetter netAttributesGetter = new NettyNetClientAttributesGetter();
|
||||
|
||||
return Instrumenter.<HttpRequestAndChannel, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
openTelemetry,
|
||||
instrumentationName,
|
||||
HttpSpanNameExtractor.create(httpClientAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpClientAttributesGetter))
|
||||
|
@ -69,6 +71,7 @@ public final class NettyClientInstrumenterFactory {
|
|||
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter))
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(netAttributesGetter, peerServiceMapping))
|
||||
.addAttributesExtractors(additionalHttpAttributeExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpRequestHeadersSetter.INSTANCE);
|
||||
}
|
||||
|
@ -78,7 +81,7 @@ public final class NettyClientInstrumenterFactory {
|
|||
|
||||
InstrumenterBuilder<NettyConnectionRequest, Channel> instrumenterBuilder =
|
||||
Instrumenter.<NettyConnectionRequest, Channel>builder(
|
||||
GlobalOpenTelemetry.get(), instrumentationName, NettyConnectionRequest::spanName)
|
||||
openTelemetry, instrumentationName, NettyConnectionRequest::spanName)
|
||||
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter))
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(netAttributesGetter, peerServiceMapping));
|
||||
|
@ -108,7 +111,7 @@ public final class NettyClientInstrumenterFactory {
|
|||
NettySslNetAttributesGetter netAttributesGetter = new NettySslNetAttributesGetter();
|
||||
Instrumenter<NettySslRequest, Void> instrumenter =
|
||||
Instrumenter.<NettySslRequest, Void>builder(
|
||||
GlobalOpenTelemetry.get(), instrumentationName, NettySslRequest::spanName)
|
||||
openTelemetry, instrumentationName, NettySslRequest::spanName)
|
||||
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter))
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(netAttributesGetter, peerServiceMapping))
|
||||
|
|
|
@ -9,7 +9,7 @@ import static io.opentelemetry.instrumentation.netty.v4.common.internal.HttpSche
|
|||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesGetter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
|
|
@ -11,7 +11,7 @@ import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTr
|
|||
import io.netty.channel.socket.DatagramChannel;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.InetSocketAddressNetClientAttributesGetter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import javax.annotation.Nullable;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
package io.opentelemetry.instrumentation.netty.v4.common.internal.server;
|
||||
|
||||
import io.opentelemetry.context.propagation.TextMapGetter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
enum HttpRequestHeadersGetter implements TextMapGetter<HttpRequestAndChannel> {
|
||||
|
|
|
@ -9,7 +9,7 @@ import static io.opentelemetry.instrumentation.netty.v4.common.internal.HttpSche
|
|||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesGetter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTr
|
|||
|
||||
import io.netty.channel.socket.DatagramChannel;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.InetSocketAddressNetServerAttributesGetter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import javax.annotation.Nullable;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
package io.opentelemetry.instrumentation.netty.v4.common.internal.server;
|
||||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
|
||||
|
@ -15,7 +15,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtrac
|
|||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.NetServerAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.NettyErrorHolder;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@ import java.util.List;
|
|||
public final class NettyServerInstrumenterFactory {
|
||||
|
||||
public static Instrumenter<HttpRequestAndChannel, HttpResponse> create(
|
||||
OpenTelemetry openTelemetry,
|
||||
String instrumentationName,
|
||||
List<String> capturedRequestHeaders,
|
||||
List<String> capturedResponseHeaders) {
|
||||
|
@ -32,9 +33,7 @@ public final class NettyServerInstrumenterFactory {
|
|||
NettyHttpServerAttributesGetter httpAttributesGetter = new NettyHttpServerAttributesGetter();
|
||||
|
||||
return Instrumenter.<HttpRequestAndChannel, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
instrumentationName,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
openTelemetry, instrumentationName, HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(
|
||||
HttpServerAttributesExtractor.builder(httpAttributesGetter)
|
||||
|
|
|
@ -15,7 +15,7 @@ import io.netty.channel.ChannelHandlerContext;
|
|||
import io.netty.util.Attribute;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.NettyErrorHolder;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
|
|
@ -8,7 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.netty.v4_0;
|
|||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import io.netty.handler.codec.http.HttpRequest;
|
|||
import io.netty.util.Attribute;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.AttributeKeys;
|
||||
|
||||
public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapter {
|
||||
|
|
|
@ -15,7 +15,7 @@ import io.netty.handler.codec.http.LastHttpContent;
|
|||
import io.netty.util.Attribute;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.AttributeKeys;
|
||||
|
||||
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.netty.v4_0.client;
|
||||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettyClientInstrumenterFactory;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettyConnectionInstrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettySslInstrumenter;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.DeprecatedConfigPropertyWarning;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class NettyClientSingletons {
|
||||
|
||||
|
@ -42,13 +44,16 @@ public final class NettyClientSingletons {
|
|||
static {
|
||||
NettyClientInstrumenterFactory factory =
|
||||
new NettyClientInstrumenterFactory(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.netty-4.0",
|
||||
connectionTelemetryEnabled,
|
||||
sslTelemetryEnabled,
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
INSTRUMENTER =
|
||||
factory.createHttpInstrumenter(
|
||||
CommonConfig.get().getClientRequestHeaders(),
|
||||
CommonConfig.get().getClientResponseHeaders(),
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
INSTRUMENTER = factory.createHttpInstrumenter();
|
||||
Collections.emptyList());
|
||||
CONNECTION_INSTRUMENTER = factory.createConnectionInstrumenter();
|
||||
SSL_INSTRUMENTER = factory.createSslInstrumenter();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import io.netty.handler.codec.http.HttpRequest;
|
|||
import io.netty.util.Attribute;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.AttributeKeys;
|
||||
|
||||
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
||||
|
|
|
@ -15,7 +15,7 @@ import io.netty.handler.codec.http.HttpResponse;
|
|||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.NettyErrorHolder;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.AttributeKeys;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.netty.v4_0.server;
|
||||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.server.NettyServerInstrumenterFactory;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
|
||||
|
||||
|
@ -15,6 +16,7 @@ public final class NettyServerSingletons {
|
|||
|
||||
private static final Instrumenter<HttpRequestAndChannel, HttpResponse> INSTRUMENTER =
|
||||
NettyServerInstrumenterFactory.create(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.netty-4.0",
|
||||
CommonConfig.get().getServerRequestHeaders(),
|
||||
CommonConfig.get().getServerResponseHeaders());
|
||||
|
|
|
@ -25,6 +25,7 @@ muzzle {
|
|||
|
||||
dependencies {
|
||||
library("io.netty:netty-codec-http:4.1.0.Final")
|
||||
implementation(project(":instrumentation:netty:netty-4.1:library"))
|
||||
implementation(project(":instrumentation:netty:netty-4-common:javaagent"))
|
||||
implementation(project(":instrumentation:netty:netty-4-common:library"))
|
||||
implementation(project(":instrumentation:netty:netty-common:library"))
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.instrumenter;
|
||||
import static io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientRequestTracingHandler.HTTP_REQUEST;
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.NettyClientSingletons.instrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
@ -14,10 +15,10 @@ import io.netty.channel.ChannelHandlerContext;
|
|||
import io.netty.util.Attribute;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.NettyErrorHolder;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
@ -51,8 +52,7 @@ public class AbstractChannelHandlerContextInstrumentation implements TypeInstrum
|
|||
if (clientContext != null) {
|
||||
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_CONTEXT).remove();
|
||||
contextAttr.remove();
|
||||
HttpRequestAndChannel request =
|
||||
ctx.channel().attr(NettyClientSingletons.HTTP_REQUEST).getAndRemove();
|
||||
HttpRequestAndChannel request = ctx.channel().attr(HTTP_REQUEST).getAndRemove();
|
||||
instrumenter().end(clientContext, request, null, throwable);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.connectionInstrumenter;
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.NettyClientSingletons.connectionInstrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
|
|
@ -12,6 +12,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.sslInstrumenter;
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.NettyClientSingletons.sslInstrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -22,15 +22,15 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
|
|||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.opentelemetry.instrumentation.api.util.VirtualField;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettySslInstrumentationHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientRequestTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientResponseTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerRequestTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerResponseTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerTracingHandler;
|
||||
import io.opentelemetry.javaagent.bootstrap.CallDepth;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4.common.AbstractNettyChannelPipelineInstrumentation;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.HttpClientRequestTracingHandler;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.HttpClientResponseTracingHandler;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.HttpClientTracingHandler;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.server.HttpServerRequestTracingHandler;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.server.HttpServerResponseTracingHandler;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.server.HttpServerTracingHandler;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
||||
public class NettyChannelPipelineInstrumentation
|
||||
|
@ -105,18 +105,18 @@ public class NettyChannelPipelineInstrumentation
|
|||
ChannelHandler ourHandler = null;
|
||||
// Server pipeline handlers
|
||||
if (handler instanceof HttpServerCodec) {
|
||||
ourHandler = new HttpServerTracingHandler();
|
||||
ourHandler = new HttpServerTracingHandler(NettyServerSingletons.instrumenter());
|
||||
} else if (handler instanceof HttpRequestDecoder) {
|
||||
ourHandler = new HttpServerRequestTracingHandler();
|
||||
ourHandler = new HttpServerRequestTracingHandler(NettyServerSingletons.instrumenter());
|
||||
} else if (handler instanceof HttpResponseEncoder) {
|
||||
ourHandler = new HttpServerResponseTracingHandler();
|
||||
ourHandler = new HttpServerResponseTracingHandler(NettyServerSingletons.instrumenter());
|
||||
// Client pipeline handlers
|
||||
} else if (handler instanceof HttpClientCodec) {
|
||||
ourHandler = new HttpClientTracingHandler();
|
||||
ourHandler = new HttpClientTracingHandler(NettyClientSingletons.instrumenter());
|
||||
} else if (handler instanceof HttpRequestEncoder) {
|
||||
ourHandler = new HttpClientRequestTracingHandler();
|
||||
ourHandler = new HttpClientRequestTracingHandler(NettyClientSingletons.instrumenter());
|
||||
} else if (handler instanceof HttpResponseDecoder) {
|
||||
ourHandler = new HttpClientResponseTracingHandler();
|
||||
ourHandler = new HttpClientResponseTracingHandler(NettyClientSingletons.instrumenter());
|
||||
// the SslHandler lives in the netty-handler module, using class name comparison to avoid
|
||||
// adding a dependency
|
||||
} else if (handler.getClass().getName().equals("io.netty.handler.ssl.SslHandler")) {
|
||||
|
|
|
@ -3,26 +3,22 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
|
||||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettyClientInstrumenterFactory;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettyConnectionInstrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettySslInstrumenter;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.DeprecatedConfigPropertyWarning;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class NettyClientSingletons {
|
||||
|
||||
public static final AttributeKey<HttpRequestAndChannel> HTTP_REQUEST =
|
||||
AttributeKey.valueOf(NettyClientSingletons.class, "http-client-request");
|
||||
static final AttributeKey<HttpResponse> HTTP_RESPONSE =
|
||||
AttributeKey.valueOf(NettyClientSingletons.class, "http-client-response");
|
||||
|
||||
private static final boolean connectionTelemetryEnabled;
|
||||
private static final boolean sslTelemetryEnabled;
|
||||
|
||||
|
@ -48,13 +44,16 @@ public final class NettyClientSingletons {
|
|||
static {
|
||||
NettyClientInstrumenterFactory factory =
|
||||
new NettyClientInstrumenterFactory(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.netty-4.1",
|
||||
connectionTelemetryEnabled,
|
||||
sslTelemetryEnabled,
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
INSTRUMENTER =
|
||||
factory.createHttpInstrumenter(
|
||||
CommonConfig.get().getClientRequestHeaders(),
|
||||
CommonConfig.get().getClientResponseHeaders(),
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
INSTRUMENTER = factory.createHttpInstrumenter();
|
||||
Collections.emptyList());
|
||||
CONNECTION_INSTRUMENTER = factory.createConnectionInstrumenter();
|
||||
SSL_INSTRUMENTER = factory.createSslInstrumenter();
|
||||
}
|
|
@ -3,24 +3,20 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.server;
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
|
||||
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.server.NettyServerInstrumenterFactory;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
|
||||
|
||||
public final class NettyServerSingletons {
|
||||
|
||||
static final AttributeKey<HttpRequestAndChannel> HTTP_REQUEST =
|
||||
AttributeKey.valueOf(NettyServerSingletons.class, "http-server-request");
|
||||
static final AttributeKey<HttpResponse> HTTP_RESPONSE =
|
||||
AttributeKey.valueOf(NettyServerSingletons.class, "http-server-response");
|
||||
|
||||
private static final Instrumenter<HttpRequestAndChannel, HttpResponse> INSTRUMENTER =
|
||||
NettyServerInstrumenterFactory.create(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.netty-4.1",
|
||||
CommonConfig.get().getServerRequestHeaders(),
|
||||
CommonConfig.get().getServerResponseHeaders());
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
|
||||
|
||||
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||
|
||||
public class HttpClientTracingHandler
|
||||
extends CombinedChannelDuplexHandler<
|
||||
HttpClientResponseTracingHandler, HttpClientRequestTracingHandler> {
|
||||
|
||||
public HttpClientTracingHandler() {
|
||||
super(new HttpClientResponseTracingHandler(), new HttpClientRequestTracingHandler());
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.server;
|
||||
|
||||
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||
|
||||
public class HttpServerTracingHandler
|
||||
extends CombinedChannelDuplexHandler<
|
||||
HttpServerRequestTracingHandler, HttpServerResponseTracingHandler> {
|
||||
|
||||
public HttpServerTracingHandler() {
|
||||
super(new HttpServerRequestTracingHandler(), new HttpServerResponseTracingHandler());
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ import io.netty.channel.DefaultChannelPipeline
|
|||
import io.netty.channel.embedded.EmbeddedChannel
|
||||
import io.netty.handler.codec.http.HttpClientCodec
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.HttpClientTracingHandler
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler
|
||||
import spock.lang.Unroll
|
||||
|
||||
@Unroll
|
||||
|
@ -31,7 +31,7 @@ class ChannelPipelineTest extends AgentInstrumentationSpecification {
|
|||
channelPipeline.addLast("http", handler)
|
||||
channelPipeline.first() == handler
|
||||
// our handler was also added
|
||||
channelPipeline.last().getClass() == HttpClientTracingHandler
|
||||
channelPipeline.last().getClass().simpleName == "HttpClientTracingHandler"
|
||||
|
||||
and:
|
||||
removeMethod.call(channelPipeline, handler)
|
||||
|
@ -70,7 +70,7 @@ class ChannelPipelineTest extends AgentInstrumentationSpecification {
|
|||
then: "noop handler was removed; http and instrumentation handlers were added"
|
||||
channelPipeline.size() == 2
|
||||
channelPipeline.first() == httpHandler
|
||||
channelPipeline.last().getClass() == HttpClientTracingHandler
|
||||
channelPipeline.last().getClass().simpleName == "HttpClientTracingHandler"
|
||||
|
||||
when:
|
||||
def anotherNoopHandler = new NoopChannelHandler()
|
||||
|
@ -103,7 +103,7 @@ class ChannelPipelineTest extends AgentInstrumentationSpecification {
|
|||
then: "add http and instrumentation handlers"
|
||||
channelPipeline.size() == 2
|
||||
channelPipeline.first() == httpHandler
|
||||
channelPipeline.last().getClass() == HttpClientTracingHandler
|
||||
channelPipeline.last().getClass().simpleName == "HttpClientTracingHandler"
|
||||
|
||||
when:
|
||||
def noopHandler = new NoopChannelHandler()
|
||||
|
@ -120,7 +120,7 @@ class ChannelPipelineTest extends AgentInstrumentationSpecification {
|
|||
then: "http and instrumentation handlers will be remained"
|
||||
channelPipeline.size() == 2
|
||||
channelPipeline.first() == httpHandler
|
||||
channelPipeline.last().getClass() == HttpClientTracingHandler
|
||||
channelPipeline.last().getClass().simpleName == "HttpClientTracingHandler"
|
||||
|
||||
when:
|
||||
channelPipeline.removeLast()
|
||||
|
|
|
@ -30,7 +30,6 @@ import io.opentelemetry.instrumentation.test.AgentTestTrait
|
|||
import io.opentelemetry.instrumentation.test.base.HttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.SingleConnection
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.HttpClientTracingHandler
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Unroll
|
||||
|
@ -253,7 +252,7 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
|
|||
|
||||
then:
|
||||
// The first one returns the removed tracing handler
|
||||
pipeline.remove(HttpClientTracingHandler.getName()) != null
|
||||
pipeline.remove("io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler") != null
|
||||
}
|
||||
|
||||
def "when a handler is added to the netty pipeline we add ONLY ONE tracing handler"() {
|
||||
|
@ -264,9 +263,9 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
|
|||
when:
|
||||
pipeline.addLast("name", new HttpClientCodec())
|
||||
// The first one returns the removed tracing handler
|
||||
pipeline.remove(HttpClientTracingHandler.getName())
|
||||
pipeline.remove("io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler")
|
||||
// There is only one
|
||||
pipeline.remove(HttpClientTracingHandler.getName()) == null
|
||||
pipeline.remove("io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler") == null
|
||||
|
||||
then:
|
||||
thrown NoSuchElementException
|
||||
|
@ -283,7 +282,7 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
|
|||
|
||||
then:
|
||||
// The first one returns the removed tracing handler
|
||||
null != pipeline.remove(HttpClientTracingHandler.getName())
|
||||
null != pipeline.remove("io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler")
|
||||
null != pipeline.remove("some_handler")
|
||||
null != pipeline.remove("a_traced_handler")
|
||||
}
|
||||
|
@ -311,9 +310,9 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
|
|||
channel.pipeline().addLast(new TracedHandlerFromInitializerHandler())
|
||||
|
||||
then:
|
||||
null != channel.pipeline().get(HttpClientTracingHandler.getName())
|
||||
null != channel.pipeline().get("io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler")
|
||||
null != channel.pipeline().remove("added_in_initializer")
|
||||
null == channel.pipeline().get(HttpClientTracingHandler.getName())
|
||||
null == channel.pipeline().get("io.opentelemetry.javaagent.shaded.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler")
|
||||
}
|
||||
|
||||
def "request with trace annotated method #method"() {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
plugins {
|
||||
id("otel.library-instrumentation")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
library("io.netty:netty-codec-http:4.1.0.Final")
|
||||
implementation(project(":instrumentation:netty:netty-4-common:library"))
|
||||
implementation(project(":instrumentation:netty:netty-common:library"))
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4_1;
|
||||
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientRequestTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientResponseTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientTracingHandler;
|
||||
|
||||
/** Entrypoint for instrumenting Netty HTTP clients. */
|
||||
public final class NettyClientTelemetry {
|
||||
|
||||
private final Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter;
|
||||
|
||||
NettyClientTelemetry(Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
/** Returns a new {@link NettyClientTelemetry} configured with the given {@link OpenTelemetry}. */
|
||||
public static NettyClientTelemetry create(OpenTelemetry openTelemetry) {
|
||||
return builder(openTelemetry).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link NettyClientTelemetryBuilder} configured with the given {@link
|
||||
* OpenTelemetry}.
|
||||
*/
|
||||
public static NettyClientTelemetryBuilder builder(OpenTelemetry openTelemetry) {
|
||||
return new NettyClientTelemetryBuilder(openTelemetry);
|
||||
}
|
||||
|
||||
/**
|
||||
* /** Returns a new {@link ChannelOutboundHandlerAdapter} that generates telemetry for outgoing
|
||||
* HTTP requests. Must be paired with {@link #createResponseHandler()}.
|
||||
*/
|
||||
public ChannelOutboundHandlerAdapter createRequestHandler() {
|
||||
return new HttpClientRequestTracingHandler(instrumenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ChannelInboundHandlerAdapter} that generates telemetry for incoming HTTP
|
||||
* responses. Must be paired with {@link #createRequestHandler()}.
|
||||
*/
|
||||
public ChannelInboundHandlerAdapter createResponseHandler() {
|
||||
return new HttpClientResponseTracingHandler(instrumenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link CombinedChannelDuplexHandler} that generates telemetry for outgoing HTTP
|
||||
* requests and incoming responses in a single handler.
|
||||
*/
|
||||
public CombinedChannelDuplexHandler<
|
||||
? extends ChannelInboundHandlerAdapter, ? extends ChannelOutboundHandlerAdapter>
|
||||
createCombinedHandler() {
|
||||
return new HttpClientTracingHandler(instrumenter);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4_1;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.client.NettyClientInstrumenterFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** A builder of {@link NettyClientTelemetry}. */
|
||||
public final class NettyClientTelemetryBuilder {
|
||||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
private List<String> capturedRequestHeaders = Collections.emptyList();
|
||||
private List<String> capturedResponseHeaders = Collections.emptyList();
|
||||
private final List<AttributesExtractor<HttpRequestAndChannel, HttpResponse>>
|
||||
additionalAttributesExtractors = new ArrayList<>();
|
||||
|
||||
NettyClientTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the HTTP request headers that will be captured as span attributes.
|
||||
*
|
||||
* @param capturedRequestHeaders A list of HTTP header names.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public NettyClientTelemetryBuilder setCapturedRequestHeaders(
|
||||
List<String> capturedRequestHeaders) {
|
||||
this.capturedRequestHeaders = capturedRequestHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the HTTP response headers that will be captured as span attributes.
|
||||
*
|
||||
* @param capturedResponseHeaders A list of HTTP header names.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public NettyClientTelemetryBuilder setCapturedResponseHeaders(
|
||||
List<String> capturedResponseHeaders) {
|
||||
this.capturedResponseHeaders = capturedResponseHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional {@link AttributesExtractor} to invoke to set attributes to instrumented
|
||||
* items.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public NettyClientTelemetryBuilder addAttributesExtractor(
|
||||
AttributesExtractor<HttpRequestAndChannel, HttpResponse> attributesExtractor) {
|
||||
additionalAttributesExtractors.add(attributesExtractor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns a new {@link NettyClientTelemetry} with the given configuration. */
|
||||
public NettyClientTelemetry build() {
|
||||
return new NettyClientTelemetry(
|
||||
new NettyClientInstrumenterFactory(
|
||||
openTelemetry, "io.opentelemetry.netty-4.1", false, false, Collections.emptyMap())
|
||||
.createHttpInstrumenter(
|
||||
capturedRequestHeaders, capturedResponseHeaders, additionalAttributesExtractors));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4_1;
|
||||
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerRequestTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerResponseTracingHandler;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerTracingHandler;
|
||||
|
||||
/** Entrypoint for instrumenting Netty HTTP servers. */
|
||||
public final class NettyServerTelemetry {
|
||||
|
||||
private final Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter;
|
||||
|
||||
NettyServerTelemetry(Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
/** Returns a new {@link NettyServerTelemetry} configured with the given {@link OpenTelemetry}. */
|
||||
public static NettyServerTelemetry create(OpenTelemetry openTelemetry) {
|
||||
return builder(openTelemetry).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link NettyServerTelemetryBuilder} configured with the given {@link
|
||||
* OpenTelemetry}.
|
||||
*/
|
||||
public static NettyServerTelemetryBuilder builder(OpenTelemetry openTelemetry) {
|
||||
return new NettyServerTelemetryBuilder(openTelemetry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ChannelInboundHandlerAdapter} that generates telemetry for incoming HTTP
|
||||
* requests. Must be paired with {@link #createResponseHandler()}.
|
||||
*/
|
||||
public ChannelInboundHandlerAdapter createRequestHandler() {
|
||||
return new HttpServerRequestTracingHandler(instrumenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ChannelOutboundHandlerAdapter} that generates telemetry for outgoing HTTP
|
||||
* responses. Must be paired with {@link #createRequestHandler()}.
|
||||
*/
|
||||
public ChannelOutboundHandlerAdapter createResponseHandler() {
|
||||
return new HttpServerResponseTracingHandler(instrumenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link CombinedChannelDuplexHandler} that generates telemetry for incoming HTTP
|
||||
* requests and outgoing responses in a single handler.
|
||||
*/
|
||||
public CombinedChannelDuplexHandler<
|
||||
? extends ChannelInboundHandlerAdapter, ? extends ChannelOutboundHandlerAdapter>
|
||||
createCombinedHandler() {
|
||||
return new HttpServerTracingHandler(instrumenter);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4_1;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.server.NettyServerInstrumenterFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** A builder of {@link NettyServerTelemetry}. */
|
||||
public final class NettyServerTelemetryBuilder {
|
||||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
private List<String> capturedRequestHeaders = Collections.emptyList();
|
||||
private List<String> capturedResponseHeaders = Collections.emptyList();
|
||||
|
||||
NettyServerTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the HTTP request headers that will be captured as span attributes.
|
||||
*
|
||||
* @param capturedRequestHeaders A list of HTTP header names.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public NettyServerTelemetryBuilder setCapturedRequestHeaders(
|
||||
List<String> capturedRequestHeaders) {
|
||||
this.capturedRequestHeaders = capturedRequestHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the HTTP response headers that will be captured as span attributes.
|
||||
*
|
||||
* @param capturedResponseHeaders A list of HTTP header names.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public NettyServerTelemetryBuilder setCapturedResponseHeaders(
|
||||
List<String> capturedResponseHeaders) {
|
||||
this.capturedResponseHeaders = capturedResponseHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns a new {@link NettyServerTelemetry} with the given configuration. */
|
||||
public NettyServerTelemetry build() {
|
||||
return new NettyServerTelemetry(
|
||||
NettyServerInstrumenterFactory.create(
|
||||
openTelemetry,
|
||||
"io.opentelemetry.netty-4.1",
|
||||
capturedRequestHeaders,
|
||||
capturedResponseHeaders));
|
||||
}
|
||||
}
|
|
@ -3,11 +3,15 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal;
|
||||
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.context.Context;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public final class AttributeKeys {
|
||||
|
||||
public static final AttributeKey<Context> WRITE_CONTEXT =
|
|
@ -3,23 +3,37 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.HTTP_REQUEST;
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.instrumenter;
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal.client;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapter {
|
||||
|
||||
public static final AttributeKey<HttpRequestAndChannel> HTTP_REQUEST =
|
||||
AttributeKey.valueOf(HttpClientRequestTracingHandler.class, "http-client-request");
|
||||
|
||||
private final Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter;
|
||||
|
||||
public HttpClientRequestTracingHandler(
|
||||
Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) {
|
||||
if (!(msg instanceof HttpRequest)) {
|
||||
|
@ -27,13 +41,13 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
|||
return;
|
||||
}
|
||||
|
||||
Context parentContext = ctx.channel().attr(AttributeKeys.WRITE_CONTEXT).getAndRemove();
|
||||
Context parentContext = ctx.channel().attr(AttributeKeys.WRITE_CONTEXT).getAndSet(null);
|
||||
if (parentContext == null) {
|
||||
parentContext = Context.current();
|
||||
}
|
||||
|
||||
HttpRequestAndChannel request = HttpRequestAndChannel.create((HttpRequest) msg, ctx.channel());
|
||||
if (!instrumenter().shouldStart(parentContext, request) || isAwsRequest(request)) {
|
||||
if (!instrumenter.shouldStart(parentContext, request) || isAwsRequest(request)) {
|
||||
ctx.write(msg, prm);
|
||||
return;
|
||||
}
|
||||
|
@ -42,7 +56,7 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
|||
Attribute<Context> contextAttr = ctx.channel().attr(AttributeKeys.CLIENT_CONTEXT);
|
||||
Attribute<HttpRequestAndChannel> requestAttr = ctx.channel().attr(HTTP_REQUEST);
|
||||
|
||||
Context context = instrumenter().start(parentContext, request);
|
||||
Context context = instrumenter.start(parentContext, request);
|
||||
parentContextAttr.set(parentContext);
|
||||
contextAttr.set(context);
|
||||
requestAttr.set(request);
|
||||
|
@ -51,8 +65,8 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
|||
ctx.write(msg, prm);
|
||||
// span is ended normally in HttpClientResponseTracingHandler
|
||||
} catch (Throwable throwable) {
|
||||
instrumenter().end(contextAttr.getAndRemove(), requestAttr.getAndRemove(), null, throwable);
|
||||
parentContextAttr.remove();
|
||||
instrumenter.end(contextAttr.getAndSet(null), requestAttr.getAndSet(null), null, throwable);
|
||||
parentContextAttr.set(null);
|
||||
throw throwable;
|
||||
}
|
||||
}
|
|
@ -3,10 +3,9 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal.client;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.HTTP_RESPONSE;
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyClientSingletons.instrumenter;
|
||||
import static io.opentelemetry.instrumentation.netty.v4_1.internal.client.HttpClientRequestTracingHandler.HTTP_REQUEST;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
|
@ -14,13 +13,29 @@ import io.netty.handler.codec.http.FullHttpResponse;
|
|||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private static final AttributeKey<HttpResponse> HTTP_RESPONSE =
|
||||
AttributeKey.valueOf(HttpClientResponseTracingHandler.class, "http-client-response");
|
||||
|
||||
private final Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter;
|
||||
|
||||
public HttpClientResponseTracingHandler(
|
||||
Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
Attribute<Context> contextAttr = ctx.channel().attr(AttributeKeys.CLIENT_CONTEXT);
|
||||
|
@ -31,25 +46,24 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
|||
}
|
||||
|
||||
Attribute<Context> parentContextAttr = ctx.channel().attr(AttributeKeys.CLIENT_PARENT_CONTEXT);
|
||||
Attribute<HttpRequestAndChannel> requestAttr =
|
||||
ctx.channel().attr(NettyClientSingletons.HTTP_REQUEST);
|
||||
Attribute<HttpRequestAndChannel> requestAttr = ctx.channel().attr(HTTP_REQUEST);
|
||||
|
||||
Context parentContext = parentContextAttr.get();
|
||||
HttpRequestAndChannel request = requestAttr.get();
|
||||
|
||||
if (msg instanceof FullHttpResponse) {
|
||||
parentContextAttr.remove();
|
||||
contextAttr.remove();
|
||||
requestAttr.remove();
|
||||
parentContextAttr.set(null);
|
||||
contextAttr.set(null);
|
||||
requestAttr.set(null);
|
||||
} else if (msg instanceof HttpResponse) {
|
||||
// Headers before body have been received, store them to use when finishing the span.
|
||||
ctx.channel().attr(HTTP_RESPONSE).set((HttpResponse) msg);
|
||||
} else if (msg instanceof LastHttpContent) {
|
||||
// Not a FullHttpResponse so this is content that has been received after headers. Finish the
|
||||
// span using what we stored in attrs.
|
||||
parentContextAttr.remove();
|
||||
contextAttr.remove();
|
||||
requestAttr.remove();
|
||||
parentContextAttr.set(null);
|
||||
contextAttr.set(null);
|
||||
requestAttr.set(null);
|
||||
}
|
||||
|
||||
// We want the callback in the scope of the parent, not the client span
|
||||
|
@ -62,9 +76,9 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
|||
}
|
||||
|
||||
if (msg instanceof FullHttpResponse) {
|
||||
instrumenter().end(context, request, (HttpResponse) msg, null);
|
||||
instrumenter.end(context, request, (HttpResponse) msg, null);
|
||||
} else if (msg instanceof LastHttpContent) {
|
||||
instrumenter().end(context, request, ctx.channel().attr(HTTP_RESPONSE).getAndRemove(), null);
|
||||
instrumenter.end(context, request, ctx.channel().attr(HTTP_RESPONSE).getAndSet(null), null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal.client;
|
||||
|
||||
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class HttpClientTracingHandler
|
||||
extends CombinedChannelDuplexHandler<
|
||||
HttpClientResponseTracingHandler, HttpClientRequestTracingHandler> {
|
||||
|
||||
public HttpClientTracingHandler(Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
super(
|
||||
new HttpClientResponseTracingHandler(instrumenter),
|
||||
new HttpClientRequestTracingHandler(instrumenter));
|
||||
}
|
||||
}
|
|
@ -3,27 +3,42 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.server;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.server.NettyServerSingletons.instrumenter;
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal.server;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
static final AttributeKey<HttpRequestAndChannel> HTTP_REQUEST =
|
||||
AttributeKey.valueOf(HttpServerRequestTracingHandler.class, "http-server-request");
|
||||
|
||||
private final Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter;
|
||||
|
||||
public HttpServerRequestTracingHandler(
|
||||
Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
Channel channel = ctx.channel();
|
||||
Attribute<Context> contextAttr = channel.attr(AttributeKeys.SERVER_CONTEXT);
|
||||
Attribute<HttpRequestAndChannel> requestAttr = channel.attr(NettyServerSingletons.HTTP_REQUEST);
|
||||
Attribute<HttpRequestAndChannel> requestAttr = channel.attr(HTTP_REQUEST);
|
||||
|
||||
if (!(msg instanceof HttpRequest)) {
|
||||
Context serverContext = contextAttr.get();
|
||||
|
@ -43,12 +58,12 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
|||
}
|
||||
HttpRequestAndChannel request = HttpRequestAndChannel.create((HttpRequest) msg, channel);
|
||||
|
||||
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||
if (!instrumenter.shouldStart(parentContext, request)) {
|
||||
ctx.fireChannelRead(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = instrumenter().start(parentContext, request);
|
||||
Context context = instrumenter.start(parentContext, request);
|
||||
contextAttr.set(context);
|
||||
requestAttr.set(request);
|
||||
|
||||
|
@ -57,7 +72,7 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
|||
// the span is ended normally in HttpServerResponseTracingHandler
|
||||
} catch (Throwable throwable) {
|
||||
// make sure to remove the server context on end() call
|
||||
instrumenter().end(contextAttr.getAndRemove(), requestAttr.getAndRemove(), null, throwable);
|
||||
instrumenter.end(contextAttr.getAndSet(null), requestAttr.getAndSet(null), null, throwable);
|
||||
throw throwable;
|
||||
}
|
||||
}
|
|
@ -3,9 +3,9 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.server;
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal.server;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.server.NettyServerSingletons.instrumenter;
|
||||
import static io.opentelemetry.instrumentation.netty.v4_1.internal.server.HttpServerRequestTracingHandler.HTTP_REQUEST;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
|
@ -16,15 +16,31 @@ import io.netty.handler.codec.http.FullHttpResponse;
|
|||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.common.internal.NettyErrorHolder;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.internal.HttpRequestAndChannel;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
||||
|
||||
static final AttributeKey<HttpResponse> HTTP_RESPONSE =
|
||||
AttributeKey.valueOf(HttpServerResponseTracingHandler.class, "http-server-response");
|
||||
|
||||
private final Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter;
|
||||
|
||||
public HttpServerResponseTracingHandler(
|
||||
Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) {
|
||||
Attribute<Context> contextAttr = ctx.channel().attr(AttributeKeys.SERVER_CONTEXT);
|
||||
|
@ -59,14 +75,14 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap
|
|||
future ->
|
||||
end(
|
||||
ctx.channel(),
|
||||
ctx.channel().attr(NettyServerSingletons.HTTP_RESPONSE).getAndRemove(),
|
||||
ctx.channel().attr(HTTP_RESPONSE).getAndSet(null),
|
||||
writePromise));
|
||||
}
|
||||
} else {
|
||||
writePromise = prm;
|
||||
if (msg instanceof HttpResponse) {
|
||||
// Headers before body has been sent, store them to use when finishing the span.
|
||||
ctx.channel().attr(NettyServerSingletons.HTTP_RESPONSE).set((HttpResponse) msg);
|
||||
ctx.channel().attr(HTTP_RESPONSE).set((HttpResponse) msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,17 +94,16 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap
|
|||
}
|
||||
}
|
||||
|
||||
private static void end(Channel channel, HttpResponse response, ChannelFuture future) {
|
||||
private void end(Channel channel, HttpResponse response, ChannelFuture future) {
|
||||
Throwable error = future.isSuccess() ? null : future.cause();
|
||||
end(channel, response, error);
|
||||
}
|
||||
|
||||
// make sure to remove the server context on end() call
|
||||
private static void end(
|
||||
Channel channel, @Nullable HttpResponse response, @Nullable Throwable error) {
|
||||
Context context = channel.attr(AttributeKeys.SERVER_CONTEXT).getAndRemove();
|
||||
HttpRequestAndChannel request = channel.attr(NettyServerSingletons.HTTP_REQUEST).getAndRemove();
|
||||
private void end(Channel channel, @Nullable HttpResponse response, @Nullable Throwable error) {
|
||||
Context context = channel.attr(AttributeKeys.SERVER_CONTEXT).getAndSet(null);
|
||||
HttpRequestAndChannel request = channel.attr(HTTP_REQUEST).getAndSet(null);
|
||||
error = NettyErrorHolder.getOrDefault(context, error);
|
||||
instrumenter().end(context, request, response, error);
|
||||
instrumenter.end(context, request, response, error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.netty.v4_1.internal.server;
|
||||
|
||||
import io.netty.channel.CombinedChannelDuplexHandler;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class HttpServerTracingHandler
|
||||
extends CombinedChannelDuplexHandler<
|
||||
HttpServerRequestTracingHandler, HttpServerResponseTracingHandler> {
|
||||
|
||||
public HttpServerTracingHandler(Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter) {
|
||||
super(
|
||||
new HttpServerRequestTracingHandler(instrumenter),
|
||||
new HttpServerResponseTracingHandler(instrumenter));
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ dependencies {
|
|||
library("io.ratpack:ratpack-core:1.4.0")
|
||||
|
||||
implementation(project(":instrumentation:netty:netty-4.1:javaagent"))
|
||||
implementation(project(":instrumentation:netty:netty-4.1:library"))
|
||||
|
||||
testImplementation(project(":instrumentation:ratpack:ratpack-1.4:testing"))
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ import static io.opentelemetry.javaagent.instrumentation.ratpack.RatpackSingleto
|
|||
|
||||
import io.netty.util.Attribute;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import ratpack.handling.Context;
|
||||
import ratpack.handling.Handler;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ muzzle {
|
|||
|
||||
dependencies {
|
||||
implementation(project(":instrumentation:netty:netty-4.1:javaagent"))
|
||||
implementation(project(":instrumentation:netty:netty-4.1:library"))
|
||||
library("io.projectreactor.netty:reactor-netty:0.9.0.RELEASE")
|
||||
|
||||
testInstrumentation(project(":instrumentation:reactor:reactor-netty:reactor-netty-1.0:javaagent"))
|
||||
|
|
|
@ -8,7 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.reactornetty.v0_9;
|
|||
import io.netty.channel.Channel;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.netty.Connection;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.reactornetty.v0_9;
|
||||
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import java.util.function.BiConsumer;
|
||||
import reactor.netty.Connection;
|
||||
import reactor.netty.http.client.HttpClientRequest;
|
||||
|
|
|
@ -24,6 +24,7 @@ dependencies {
|
|||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
|
||||
implementation(project(":instrumentation:netty:netty-4.1:javaagent"))
|
||||
implementation(project(":instrumentation:netty:netty-4.1:library"))
|
||||
implementation(project(":instrumentation:netty:netty-4-common:library"))
|
||||
implementation(project(":instrumentation:netty:netty-common:library"))
|
||||
implementation(project(":instrumentation:reactor:reactor-3.1:library"))
|
||||
|
|
|
@ -11,8 +11,8 @@ import static io.opentelemetry.javaagent.instrumentation.reactornetty.v1_0.React
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.internal.AttributeKeys;
|
||||
import io.opentelemetry.instrumentation.reactor.ContextPropagationOperator;
|
||||
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.AttributeKeys;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
|
|
|
@ -72,11 +72,10 @@ public final class ReactorNettySingletons {
|
|||
|
||||
NettyClientInstrumenterFactory instrumenterFactory =
|
||||
new NettyClientInstrumenterFactory(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
connectionTelemetryEnabled,
|
||||
false,
|
||||
CommonConfig.get().getClientRequestHeaders(),
|
||||
CommonConfig.get().getClientResponseHeaders(),
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
CONNECTION_INSTRUMENTER = instrumenterFactory.createConnectionInstrumenter();
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ include(":instrumentation:mongo:mongo-common:testing")
|
|||
include(":instrumentation:netty:netty-3.8:javaagent")
|
||||
include(":instrumentation:netty:netty-4.0:javaagent")
|
||||
include(":instrumentation:netty:netty-4.1:javaagent")
|
||||
include(":instrumentation:netty:netty-4.1:library")
|
||||
include(":instrumentation:netty:netty-4-common:javaagent")
|
||||
include(":instrumentation:netty:netty-4-common:library")
|
||||
include(":instrumentation:netty:netty-common:library")
|
||||
|
|
Loading…
Reference in New Issue