Create instrumentation-core apache-httpclient-4.0 (#694)
This commit is contained in:
parent
10f24aff65
commit
3662cee7ec
|
|
@ -0,0 +1,24 @@
|
|||
plugins {
|
||||
id "com.github.johnrengelman.shadow"
|
||||
}
|
||||
|
||||
ext {
|
||||
noShadowPublish = true
|
||||
}
|
||||
|
||||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
group = 'io.opentelemetry.instrumentation'
|
||||
|
||||
shadowJar {
|
||||
archiveClassifier = 'agent'
|
||||
configurations = []
|
||||
relocate 'io.opentelemetry.instrumentation.apachehttpclient.v4_0', 'io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.shaded'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':auto-bootstrap')
|
||||
compileOnly deps.opentelemetryApi
|
||||
|
||||
compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.0'
|
||||
}
|
||||
|
|
@ -14,22 +14,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0;
|
||||
package io.opentelemetry.instrumentation.apachehttpclient.v4_0;
|
||||
|
||||
import io.grpc.Context;
|
||||
import io.opentelemetry.OpenTelemetry;
|
||||
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
|
||||
import io.opentelemetry.trace.Tracer;
|
||||
import java.net.URI;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpMessage;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
|
||||
public class ApacheHttpClientDecorator extends HttpClientDecorator<HttpUriRequest, HttpResponse> {
|
||||
class ApacheHttpClientDecorator extends HttpClientDecorator<HttpUriRequest, HttpResponse> {
|
||||
public static final ApacheHttpClientDecorator DECORATE = new ApacheHttpClientDecorator();
|
||||
|
||||
public static final Tracer TRACER =
|
||||
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.apache-httpclient-4.0");
|
||||
public void inject(Context context, HttpUriRequest request) {
|
||||
OpenTelemetry.getPropagators()
|
||||
.getHttpTextFormat()
|
||||
.inject(context, request, HttpHeadersInjectAdapter.SETTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(final HttpUriRequest httpRequest) {
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.apachehttpclient.v4_0;
|
||||
|
||||
import static io.opentelemetry.context.ContextUtils.withScopedContext;
|
||||
import static io.opentelemetry.instrumentation.apachehttpclient.v4_0.ApacheHttpClientDecorator.DECORATE;
|
||||
|
||||
import io.grpc.Context;
|
||||
import io.opentelemetry.OpenTelemetry;
|
||||
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
|
||||
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.ClientDecorator;
|
||||
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import io.opentelemetry.trace.Tracer;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
|
||||
public class ApacheHttpClientHelper {
|
||||
|
||||
public static final Tracer TRACER =
|
||||
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.spring-webflux-5.0");
|
||||
|
||||
public static SpanWithScope doMethodEnter(final HttpUriRequest request) {
|
||||
return doMethodEnter(request, TRACER);
|
||||
}
|
||||
|
||||
public static SpanWithScope doMethodEnter(final HttpUriRequest request, final Tracer tracer) {
|
||||
final Span span = DECORATE.getOrCreateSpan(request, tracer);
|
||||
|
||||
DECORATE.afterStart(span);
|
||||
DECORATE.onRequest(span, request);
|
||||
|
||||
final Context context = ClientDecorator.currentContextWith(span);
|
||||
if (span.getContext().isValid()) {
|
||||
DECORATE.inject(context, request);
|
||||
}
|
||||
final Scope scope = withScopedContext(context);
|
||||
|
||||
return new SpanWithScope(span, scope);
|
||||
}
|
||||
|
||||
public static void doMethodExitAndResetCallDepthThread(
|
||||
final SpanWithScope spanWithScope, final Object result, final Throwable throwable) {
|
||||
if (spanWithScope == null) {
|
||||
return;
|
||||
}
|
||||
CallDepthThreadLocalMap.reset(HttpClient.class);
|
||||
|
||||
doMethodExit(spanWithScope, result, throwable);
|
||||
}
|
||||
|
||||
public static void doMethodExit(
|
||||
final SpanWithScope spanWithScope, final Object result, final Throwable throwable) {
|
||||
try {
|
||||
final Span span = spanWithScope.getSpan();
|
||||
|
||||
if (result instanceof HttpResponse) {
|
||||
DECORATE.onResponse(span, (HttpResponse) result);
|
||||
} // else they probably provided a ResponseHandler.
|
||||
|
||||
DECORATE.onError(span, throwable);
|
||||
DECORATE.beforeFinish(span);
|
||||
span.end();
|
||||
} finally {
|
||||
spanWithScope.closeScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0;
|
||||
package io.opentelemetry.instrumentation.apachehttpclient.v4_0;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0;
|
||||
package io.opentelemetry.instrumentation.apachehttpclient.v4_0;
|
||||
|
||||
import io.opentelemetry.context.propagation.HttpTextFormat;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
|
||||
public class HttpHeadersInjectAdapter implements HttpTextFormat.Setter<HttpUriRequest> {
|
||||
class HttpHeadersInjectAdapter implements HttpTextFormat.Setter<HttpUriRequest> {
|
||||
|
||||
public static final HttpHeadersInjectAdapter SETTER = new HttpHeadersInjectAdapter();
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.apachehttpclient.v4_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.apachehttpclient.v4_0.ApacheHttpClientDecorator.DECORATE;
|
||||
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.io.IOException;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
|
||||
public class WrappingStatusSettingResponseHandler implements ResponseHandler {
|
||||
final Span span;
|
||||
final ResponseHandler handler;
|
||||
|
||||
public WrappingStatusSettingResponseHandler(final Span span, final ResponseHandler handler) {
|
||||
this.span = span;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handleResponse(final HttpResponse response)
|
||||
throws ClientProtocolException, IOException {
|
||||
if (null != span) {
|
||||
DECORATE.onResponse(span, response);
|
||||
}
|
||||
return handler.handleResponse(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
group = 'io.opentelemetry.instrumentation.spring'
|
||||
group = 'io.opentelemetry.instrumentation'
|
||||
|
||||
apply plugin: 'java'
|
||||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ ext {
|
|||
|
||||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
group = 'io.opentelemetry.instrumentation.spring.webflux'
|
||||
group = 'io.opentelemetry.instrumentation'
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':auto-bootstrap')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
group = 'io.opentelemetry.instrumentation.spring'
|
||||
group = 'io.opentelemetry.instrumentation'
|
||||
|
||||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ testSets {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':instrumentation-core:apache-httpclient-4.0', configuration: 'shadow')
|
||||
compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.0'
|
||||
|
||||
testImplementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.0'
|
||||
|
|
|
|||
|
|
@ -16,12 +16,8 @@
|
|||
|
||||
package io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0;
|
||||
|
||||
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.ApacheHttpClientDecorator.DECORATE;
|
||||
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.ApacheHttpClientDecorator.TRACER;
|
||||
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.HttpHeadersInjectAdapter.SETTER;
|
||||
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
|
||||
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
|
||||
import static io.opentelemetry.context.ContextUtils.withScopedContext;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
|
@ -30,15 +26,12 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.grpc.Context;
|
||||
import io.opentelemetry.OpenTelemetry;
|
||||
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
|
||||
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.ClientDecorator;
|
||||
import io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.shaded.ApacheHttpClientHelper;
|
||||
import io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.shaded.HostAndRequestAsHttpUriRequest;
|
||||
import io.opentelemetry.auto.instrumentation.apachehttpclient.v4_0.shaded.WrappingStatusSettingResponseHandler;
|
||||
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
|
||||
import io.opentelemetry.auto.tooling.Instrumenter;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
|
@ -48,8 +41,6 @@ import net.bytebuddy.implementation.bytecode.assign.Assigner;
|
|||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
|
|
@ -75,11 +66,11 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
packageName + ".ApacheHttpClientDecorator",
|
||||
packageName + ".HttpHeadersInjectAdapter",
|
||||
packageName + ".HostAndRequestAsHttpUriRequest",
|
||||
getClass().getName() + "$HelperMethods",
|
||||
getClass().getName() + "$WrappingStatusSettingResponseHandler",
|
||||
packageName + ".shaded.ApacheHttpClientDecorator",
|
||||
packageName + ".shaded.HttpHeadersInjectAdapter",
|
||||
packageName + ".shaded.HostAndRequestAsHttpUriRequest",
|
||||
packageName + ".shaded.ApacheHttpClientHelper",
|
||||
packageName + ".shaded.WrappingStatusSettingResponseHandler",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -170,45 +161,6 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
return transformers;
|
||||
}
|
||||
|
||||
public static class HelperMethods {
|
||||
public static SpanWithScope doMethodEnter(final HttpUriRequest request) {
|
||||
final Span span = DECORATE.getOrCreateSpan(request, TRACER);
|
||||
|
||||
DECORATE.afterStart(span);
|
||||
DECORATE.onRequest(span, request);
|
||||
|
||||
final Context context = ClientDecorator.currentContextWith(span);
|
||||
if (span.getContext().isValid()) {
|
||||
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request, SETTER);
|
||||
}
|
||||
final Scope scope = withScopedContext(context);
|
||||
|
||||
return new SpanWithScope(span, scope);
|
||||
}
|
||||
|
||||
public static void doMethodExit(
|
||||
final SpanWithScope spanWithScope, final Object result, final Throwable throwable) {
|
||||
if (spanWithScope == null) {
|
||||
return;
|
||||
}
|
||||
CallDepthThreadLocalMap.reset(HttpClient.class);
|
||||
|
||||
try {
|
||||
final Span span = spanWithScope.getSpan();
|
||||
|
||||
if (result instanceof HttpResponse) {
|
||||
DECORATE.onResponse(span, (HttpResponse) result);
|
||||
} // else they probably provided a ResponseHandler.
|
||||
|
||||
DECORATE.onError(span, throwable);
|
||||
DECORATE.beforeFinish(span);
|
||||
span.end();
|
||||
} finally {
|
||||
spanWithScope.closeScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class UriRequestAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static SpanWithScope methodEnter(@Advice.Argument(0) final HttpUriRequest request) {
|
||||
|
|
@ -217,7 +169,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
return null;
|
||||
}
|
||||
|
||||
return HelperMethods.doMethodEnter(request);
|
||||
return ApacheHttpClientHelper.doMethodEnter(request);
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
|
|
@ -225,8 +177,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Enter final SpanWithScope spanWithScope,
|
||||
@Advice.Return final Object result,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
|
||||
HelperMethods.doMethodExit(spanWithScope, result, throwable);
|
||||
ApacheHttpClientHelper.doMethodExitAndResetCallDepthThread(spanWithScope, result, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +197,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
return null;
|
||||
}
|
||||
|
||||
final SpanWithScope spanWithScope = HelperMethods.doMethodEnter(request);
|
||||
final SpanWithScope spanWithScope = ApacheHttpClientHelper.doMethodEnter(request);
|
||||
|
||||
// Wrap the handler so we capture the status code
|
||||
if (handler instanceof ResponseHandler) {
|
||||
|
|
@ -262,8 +213,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Enter final SpanWithScope spanWithScope,
|
||||
@Advice.Return final Object result,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
|
||||
HelperMethods.doMethodExit(spanWithScope, result, throwable);
|
||||
ApacheHttpClientHelper.doMethodExitAndResetCallDepthThread(spanWithScope, result, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -277,9 +227,10 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
}
|
||||
|
||||
if (request instanceof HttpUriRequest) {
|
||||
return HelperMethods.doMethodEnter((HttpUriRequest) request);
|
||||
return ApacheHttpClientHelper.doMethodEnter((HttpUriRequest) request);
|
||||
} else {
|
||||
return HelperMethods.doMethodEnter(new HostAndRequestAsHttpUriRequest(host, request));
|
||||
return ApacheHttpClientHelper.doMethodEnter(
|
||||
new HostAndRequestAsHttpUriRequest(host, request));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,8 +239,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Enter final SpanWithScope spanWithScope,
|
||||
@Advice.Return final Object result,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
|
||||
HelperMethods.doMethodExit(spanWithScope, result, throwable);
|
||||
ApacheHttpClientHelper.doMethodExitAndResetCallDepthThread(spanWithScope, result, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -313,10 +263,10 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
final SpanWithScope spanWithScope;
|
||||
|
||||
if (request instanceof HttpUriRequest) {
|
||||
spanWithScope = HelperMethods.doMethodEnter((HttpUriRequest) request);
|
||||
spanWithScope = ApacheHttpClientHelper.doMethodEnter((HttpUriRequest) request);
|
||||
} else {
|
||||
spanWithScope =
|
||||
HelperMethods.doMethodEnter(new HostAndRequestAsHttpUriRequest(host, request));
|
||||
ApacheHttpClientHelper.doMethodEnter(new HostAndRequestAsHttpUriRequest(host, request));
|
||||
}
|
||||
|
||||
// Wrap the handler so we capture the status code
|
||||
|
|
@ -333,27 +283,7 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Enter final SpanWithScope spanWithScope,
|
||||
@Advice.Return final Object result,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
|
||||
HelperMethods.doMethodExit(spanWithScope, result, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappingStatusSettingResponseHandler implements ResponseHandler {
|
||||
final Span span;
|
||||
final ResponseHandler handler;
|
||||
|
||||
public WrappingStatusSettingResponseHandler(final Span span, final ResponseHandler handler) {
|
||||
this.span = span;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handleResponse(final HttpResponse response)
|
||||
throws ClientProtocolException, IOException {
|
||||
if (null != span) {
|
||||
DECORATE.onResponse(span, response);
|
||||
}
|
||||
return handler.handleResponse(response);
|
||||
ApacheHttpClientHelper.doMethodExitAndResetCallDepthThread(spanWithScope, result, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ include ':instrumentation:twilio-6.6'
|
|||
include ':instrumentation:vertx-3.0'
|
||||
include ':instrumentation:vertx-reactive-3.5'
|
||||
|
||||
include ':instrumentation-core:apache-httpclient-4.0'
|
||||
include ':instrumentation-core:aws-sdk:aws-sdk-2.2'
|
||||
include ':instrumentation-core:reactor-3.1'
|
||||
include ':instrumentation-core:servlet'
|
||||
|
|
|
|||
Loading…
Reference in New Issue