Convert google-http-client-1.19 to instrumenter api (#3932)
* Convert google-http-client-1.19 to instrumenter api * remove some nullable annotations * remove nullable
This commit is contained in:
parent
6f22d90aa6
commit
c0aad71650
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpRequest;
|
||||||
|
import com.google.api.client.http.HttpResponse;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpAttributesExtractor;
|
||||||
|
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
final class GoogleHttpClientHttpAttributesExtractor
|
||||||
|
extends HttpAttributesExtractor<HttpRequest, HttpResponse> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String method(HttpRequest httpRequest) {
|
||||||
|
return httpRequest.getRequestMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String url(HttpRequest httpRequest) {
|
||||||
|
return httpRequest.getUrl().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String target(HttpRequest httpRequest) {
|
||||||
|
return httpRequest.getUrl().buildRelativeUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String host(HttpRequest httpRequest) {
|
||||||
|
return httpRequest.getUrl().getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String scheme(HttpRequest httpRequest) {
|
||||||
|
return httpRequest.getUrl().getScheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String userAgent(HttpRequest httpRequest) {
|
||||||
|
return httpRequest.getHeaders().getUserAgent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable Long requestContentLength(
|
||||||
|
HttpRequest httpRequest, @Nullable HttpResponse httpResponse) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable Long requestContentLengthUncompressed(
|
||||||
|
HttpRequest httpRequest, @Nullable HttpResponse httpResponse) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String flavor(HttpRequest httpRequest, @Nullable HttpResponse httpResponse) {
|
||||||
|
return SemanticAttributes.HttpFlavorValues.HTTP_1_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable Integer statusCode(HttpRequest httpRequest, HttpResponse httpResponse) {
|
||||||
|
return httpResponse.getStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable Long responseContentLength(
|
||||||
|
HttpRequest httpRequest, HttpResponse httpResponse) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable Long responseContentLengthUncompressed(
|
||||||
|
HttpRequest httpRequest, HttpResponse httpResponse) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String route(HttpRequest httpRequest) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable String serverName(
|
||||||
|
HttpRequest httpRequest, @Nullable HttpResponse httpResponse) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpRequest;
|
||||||
|
import com.google.api.client.http.HttpResponse;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.net.NetAttributesExtractor;
|
||||||
|
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
final class GoogleHttpClientNetAttributesExtractor
|
||||||
|
extends NetAttributesExtractor<HttpRequest, HttpResponse> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String transport(HttpRequest request) {
|
||||||
|
return SemanticAttributes.NetTransportValues.IP_TCP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String peerName(HttpRequest request, @Nullable HttpResponse response) {
|
||||||
|
return request.getUrl().getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer peerPort(HttpRequest request, @Nullable HttpResponse response) {
|
||||||
|
int port = request.getUrl().getPort();
|
||||||
|
if (port != -1) {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String peerIp(HttpRequest request, @Nullable HttpResponse response) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpRequest;
|
||||||
|
import com.google.api.client.http.HttpResponse;
|
||||||
|
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpAttributesExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
|
||||||
|
|
||||||
|
public class GoogleHttpClientSingletons {
|
||||||
|
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.google-http-client-1.19";
|
||||||
|
|
||||||
|
private static final Instrumenter<HttpRequest, HttpResponse> INSTRUMENTER;
|
||||||
|
|
||||||
|
static {
|
||||||
|
HttpAttributesExtractor<HttpRequest, HttpResponse> httpAttributesExtractor =
|
||||||
|
new GoogleHttpClientHttpAttributesExtractor();
|
||||||
|
SpanNameExtractor<? super HttpRequest> spanNameExtractor =
|
||||||
|
HttpSpanNameExtractor.create(httpAttributesExtractor);
|
||||||
|
SpanStatusExtractor<? super HttpRequest, ? super HttpResponse> spanStatusExtractor =
|
||||||
|
HttpSpanStatusExtractor.create(httpAttributesExtractor);
|
||||||
|
GoogleHttpClientNetAttributesExtractor netAttributesExtractor =
|
||||||
|
new GoogleHttpClientNetAttributesExtractor();
|
||||||
|
|
||||||
|
INSTRUMENTER =
|
||||||
|
Instrumenter.<HttpRequest, HttpResponse>newBuilder(
|
||||||
|
GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor)
|
||||||
|
.setSpanStatusExtractor(spanStatusExtractor)
|
||||||
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
|
.addAttributesExtractor(netAttributesExtractor)
|
||||||
|
.addAttributesExtractor(PeerServiceAttributesExtractor.create(netAttributesExtractor))
|
||||||
|
.addRequestMetrics(HttpClientMetrics.get())
|
||||||
|
.newClientInstrumenter(new HttpHeaderSetter());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instrumenter<HttpRequest, HttpResponse> instrumenter() {
|
||||||
|
return INSTRUMENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GoogleHttpClientSingletons() {}
|
||||||
|
}
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.instrumentation.googlehttpclient.HeadersInjectAdapter.SETTER;
|
|
||||||
|
|
||||||
import com.google.api.client.http.HttpHeaders;
|
|
||||||
import com.google.api.client.http.HttpRequest;
|
|
||||||
import com.google.api.client.http.HttpResponse;
|
|
||||||
import io.opentelemetry.context.Context;
|
|
||||||
import io.opentelemetry.context.propagation.TextMapSetter;
|
|
||||||
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
|
|
||||||
import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
|
|
||||||
public class GoogleHttpClientTracer
|
|
||||||
extends HttpClientTracer<HttpRequest, HttpHeaders, HttpResponse> {
|
|
||||||
private static final GoogleHttpClientTracer TRACER = new GoogleHttpClientTracer();
|
|
||||||
|
|
||||||
private GoogleHttpClientTracer() {
|
|
||||||
super(NetPeerAttributes.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GoogleHttpClientTracer tracer() {
|
|
||||||
return TRACER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context startSpan(Context parentContext, HttpRequest request) {
|
|
||||||
return startSpan(parentContext, request, request.getHeaders());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getInstrumentationName() {
|
|
||||||
return "io.opentelemetry.google-http-client-1.19";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String method(HttpRequest httpRequest) {
|
|
||||||
return httpRequest.getRequestMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected URI url(HttpRequest httpRequest) throws URISyntaxException {
|
|
||||||
// Google uses %20 (space) instead of "+" for spaces in the fragment
|
|
||||||
// Add "+" back for consistency with the other http client instrumentations
|
|
||||||
String url = httpRequest.getUrl().build();
|
|
||||||
String fixedUrl = url.replaceAll("%20", "+");
|
|
||||||
return new URI(fixedUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Integer status(HttpResponse httpResponse) {
|
|
||||||
return httpResponse.getStatusCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String requestHeader(HttpRequest httpRequest, String name) {
|
|
||||||
return header(httpRequest.getHeaders(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String responseHeader(HttpResponse httpResponse, String name) {
|
|
||||||
return header(httpResponse.getHeaders(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TextMapSetter<HttpHeaders> getSetter() {
|
|
||||||
return SETTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String header(HttpHeaders headers, String name) {
|
|
||||||
return headers.getFirstHeaderStringValue(name);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@
|
||||||
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
|
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
|
||||||
import static io.opentelemetry.javaagent.instrumentation.googlehttpclient.GoogleHttpClientTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.googlehttpclient.GoogleHttpClientSingletons.instrumenter;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
@ -67,15 +67,16 @@ public class GoogleHttpRequestInstrumentation implements TypeInstrumentation {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Context parentContext = currentContext();
|
Context parentContext = currentContext();
|
||||||
if (!tracer().shouldStartSpan(parentContext)) {
|
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
context = tracer().startSpan(parentContext, request);
|
context = instrumenter().start(parentContext, request);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void methodExit(
|
public static void methodExit(
|
||||||
|
@Advice.This HttpRequest request,
|
||||||
@Advice.Return HttpResponse response,
|
@Advice.Return HttpResponse response,
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
|
@ -85,7 +86,7 @@ public class GoogleHttpRequestInstrumentation implements TypeInstrumentation {
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.close();
|
scope.close();
|
||||||
tracer().endMaybeExceptionally(context, response, throwable);
|
instrumenter().end(context, request, response, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,11 +99,10 @@ public class GoogleHttpRequestInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
Context parentContext = currentContext();
|
Context parentContext = currentContext();
|
||||||
if (!tracer().shouldStartSpan(parentContext)) {
|
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
context = instrumenter().start(parentContext, request);
|
||||||
context = tracer().startSpan(parentContext, request);
|
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
|
|
||||||
InstrumentationContext.get(HttpRequest.class, Context.class).put(request, context);
|
InstrumentationContext.get(HttpRequest.class, Context.class).put(request, context);
|
||||||
|
@ -110,6 +110,7 @@ public class GoogleHttpRequestInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void methodExit(
|
public static void methodExit(
|
||||||
|
@Advice.This HttpRequest request,
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
@ -119,7 +120,7 @@ public class GoogleHttpRequestInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
scope.close();
|
scope.close();
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
tracer().endExceptionally(context, throwable);
|
instrumenter().end(context, request, null, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
|
||||||
|
|
||||||
import com.google.api.client.http.HttpHeaders;
|
|
||||||
import io.opentelemetry.context.propagation.TextMapSetter;
|
|
||||||
|
|
||||||
public class HeadersInjectAdapter implements TextMapSetter<HttpHeaders> {
|
|
||||||
|
|
||||||
public static final HeadersInjectAdapter SETTER = new HeadersInjectAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(HttpHeaders carrier, String key, String value) {
|
|
||||||
carrier.put(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpRequest;
|
||||||
|
import io.opentelemetry.context.propagation.TextMapSetter;
|
||||||
|
|
||||||
|
public class HttpHeaderSetter implements TextMapSetter<HttpRequest> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(HttpRequest carrier, String key, String value) {
|
||||||
|
carrier.getHeaders().set(key, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,6 +83,9 @@ abstract class AbstractGoogleHttpClientTest extends HttpClientTest<HttpRequest>
|
||||||
"${SemanticAttributes.HTTP_METHOD.key}" method
|
"${SemanticAttributes.HTTP_METHOD.key}" method
|
||||||
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 500
|
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 500
|
||||||
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
|
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
|
||||||
|
"${SemanticAttributes.HTTP_HOST.key}" "localhost"
|
||||||
|
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
|
||||||
|
"${SemanticAttributes.HTTP_TARGET.key}" "/error"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serverSpan(it, 1, span(0))
|
serverSpan(it, 1, span(0))
|
||||||
|
|
Loading…
Reference in New Issue