-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added apachehttpclient common module * added apachehttpclient5 sync instrumentation * added apachehttpclient async impl, covered with tests * added comments for apache http client works with urlpath that contains userinfo * set isTestHttpCallWithUserInfoEnabled with false value in ApacheHttpClientInstrumentationTest 5 * handled case with recycling when client closed before executing * added httpclient5 plugin to agent builds pom. Run tests, generated license headers * added entry to changelog * updated supported technologies * added comment * added test that checks feignClient * minor polish * updated configuration.asciidoc * minor polish according to the review comments * updated failedWithoutException call for apachehttpclient 5. recycle AsyncRequestProducerWrapper in case when delegate is not null. Added tests that breaks behavior when asyncClientHelper.recycle(this); called multiple times when delegate is already null in ASyncRequestProductWrapper * updated docs * renamed class names for consistency * fixes according to comments * wrapped with try/finally block. removed static import --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
- Loading branch information
1 parent
d1aaa52
commit eb349d3
Showing
32 changed files
with
1,599 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
apm-agent-plugins/apm-apache-httpclient/apm-apache-httpclient-common/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<artifactId>apm-apache-httpclient</artifactId> | ||
<groupId>co.elastic.apm</groupId> | ||
<version>1.44.1-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>apm-apache-httpclient-common</artifactId> | ||
<name>${project.groupId}:${project.artifactId}</name> | ||
|
||
<properties> | ||
<apm-agent-parent.base.dir>${project.basedir}/../../..</apm-agent-parent.base.dir> | ||
</properties> | ||
|
||
</project> |
76 changes: 76 additions & 0 deletions
76
.../src/main/java/co/elastic/apm/agent/httpclient/common/AbstractApacheHttpClientAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.httpclient.common; | ||
|
||
|
||
import co.elastic.apm.agent.httpclient.HttpClientHelper; | ||
import co.elastic.apm.agent.tracer.ElasticContext; | ||
import co.elastic.apm.agent.tracer.Outcome; | ||
import co.elastic.apm.agent.tracer.Span; | ||
import co.elastic.apm.agent.tracer.Tracer; | ||
import co.elastic.apm.agent.tracer.dispatch.TextHeaderGetter; | ||
import co.elastic.apm.agent.tracer.dispatch.TextHeaderSetter; | ||
|
||
import java.net.URISyntaxException; | ||
|
||
public abstract class AbstractApacheHttpClientAdvice { | ||
|
||
public static <REQUEST, WRAPPER extends REQUEST, HTTPHOST, RESPONSE, | ||
HeaderAccessor extends TextHeaderSetter<REQUEST> & | ||
TextHeaderGetter<REQUEST>> Object startSpan(final Tracer tracer, | ||
final ApacheHttpClientApiAdapter<REQUEST, WRAPPER, HTTPHOST, RESPONSE> adapter, | ||
final WRAPPER request, | ||
final HTTPHOST httpHost, | ||
final HeaderAccessor headerAccessor) throws URISyntaxException { | ||
ElasticContext<?> elasticContext = tracer.currentContext(); | ||
Span<?> span = null; | ||
if (elasticContext.getSpan() != null) { | ||
span = HttpClientHelper.startHttpClientSpan(elasticContext, adapter.getMethod(request), adapter.getUri(request), adapter.getHostName(httpHost)); | ||
if (span != null) { | ||
span.activate(); | ||
} | ||
} | ||
tracer.currentContext().propagateContext(request, headerAccessor, headerAccessor); | ||
return span; | ||
} | ||
|
||
public static <REQUEST, WRAPPER extends REQUEST, HTTPHOST, RESPONSE> void endSpan(ApacheHttpClientApiAdapter<REQUEST, WRAPPER, HTTPHOST, RESPONSE> adapter, | ||
Object spanObj, | ||
Throwable t, | ||
RESPONSE response) { | ||
Span<?> span = (Span<?>) spanObj; | ||
if (span == null) { | ||
return; | ||
} | ||
try { | ||
if (response != null && adapter.isNotNullStatusLine(response)) { | ||
int statusCode = adapter.getResponseCode(response); | ||
span.getContext().getHttp().withStatusCode(statusCode); | ||
} | ||
span.captureException(t); | ||
} finally { | ||
// in case of circular redirect, we get an exception but status code won't be available without response | ||
// thus we have to deal with span outcome directly | ||
if (adapter.isCircularRedirectException(t)) { | ||
span.withOutcome(Outcome.FAILURE); | ||
} | ||
span.deactivate().end(); | ||
} | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
...main/java/co/elastic/apm/agent/httpclient/common/AbstractApacheHttpClientAsyncAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.httpclient.common; | ||
|
||
|
||
import co.elastic.apm.agent.httpclient.HttpClientHelper; | ||
import co.elastic.apm.agent.tracer.ElasticContext; | ||
import co.elastic.apm.agent.tracer.Span; | ||
import co.elastic.apm.agent.tracer.Tracer; | ||
|
||
public abstract class AbstractApacheHttpClientAsyncAdvice { | ||
|
||
public static <PRODUCER, WRAPPER extends PRODUCER, CALLBACK, CALLBACK_WRAPPER extends CALLBACK, CONTEXT> Object[] startSpan( | ||
Tracer tracer, ApacheHttpClientAsyncHelper<PRODUCER, WRAPPER, CALLBACK, CALLBACK_WRAPPER, CONTEXT> asyncHelper, | ||
PRODUCER asyncRequestProducer, CONTEXT context, CALLBACK futureCallback) { | ||
|
||
ElasticContext<?> parentContext = tracer.currentContext(); | ||
if (parentContext.isEmpty()) { | ||
// performance optimization, no need to wrap if we have nothing to propagate | ||
// empty context means also we will not create an exit span | ||
return null; | ||
} | ||
CALLBACK wrappedFutureCallback = futureCallback; | ||
ElasticContext<?> activeContext = tracer.currentContext(); | ||
Span<?> span = activeContext.createExitSpan(); | ||
if (span != null) { | ||
span.withType(HttpClientHelper.EXTERNAL_TYPE) | ||
.withSubtype(HttpClientHelper.HTTP_SUBTYPE) | ||
.withSync(false) | ||
.activate(); | ||
wrappedFutureCallback = asyncHelper.wrapFutureCallback(futureCallback, context, span); | ||
} | ||
PRODUCER wrappedProducer = asyncHelper.wrapRequestProducer(asyncRequestProducer, span, tracer.currentContext()); | ||
return new Object[]{wrappedProducer, wrappedFutureCallback, span}; | ||
} | ||
|
||
public static <PRODUCER, WRAPPER extends PRODUCER, CALLBACK, CALLBACK_WRAPPER extends CALLBACK, CONTEXT> void endSpan( | ||
ApacheHttpClientAsyncHelper<PRODUCER, WRAPPER, CALLBACK, CALLBACK_WRAPPER, CONTEXT> asyncHelper, Object[] enter, Throwable t) { | ||
Span<?> span = enter != null ? (Span<?>) enter[2] : null; | ||
if (span != null) { | ||
// Deactivate in this thread | ||
span.deactivate(); | ||
// End the span if the method terminated with an exception. | ||
// The exception means that the listener who normally does the ending will not be invoked. | ||
WRAPPER wrapper = (WRAPPER) enter[0]; | ||
if (t != null) { | ||
CALLBACK_WRAPPER cb = (CALLBACK_WRAPPER) enter[1]; | ||
// only for apachehttpclient_v4 | ||
asyncHelper.failedBeforeRequestStarted(cb, t); | ||
|
||
asyncHelper.recycle(wrapper); | ||
} | ||
} | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
...mmon/src/main/java/co/elastic/apm/agent/httpclient/common/ApacheHttpClientApiAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.httpclient.common; | ||
|
||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
|
||
public interface ApacheHttpClientApiAdapter<REQUEST, WRAPPER extends REQUEST, HTTPHOST, RESPONSE> { | ||
String getMethod(WRAPPER request); | ||
|
||
URI getUri(WRAPPER request) throws URISyntaxException; | ||
|
||
CharSequence getHostName(HTTPHOST httpHost); | ||
|
||
int getResponseCode(RESPONSE response); | ||
|
||
boolean isCircularRedirectException(Throwable t); | ||
|
||
boolean isNotNullStatusLine(RESPONSE response); | ||
} |
35 changes: 35 additions & 0 deletions
35
...mon/src/main/java/co/elastic/apm/agent/httpclient/common/ApacheHttpClientAsyncHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you 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 co.elastic.apm.agent.httpclient.common; | ||
|
||
|
||
import co.elastic.apm.agent.tracer.ElasticContext; | ||
import co.elastic.apm.agent.tracer.Span; | ||
|
||
public interface ApacheHttpClientAsyncHelper<AsyncProducer, AsyncProducerWrapper extends AsyncProducer, FutureCallback, FutureCallbackWrapper extends FutureCallback, HttpContext> { | ||
|
||
AsyncProducerWrapper wrapRequestProducer(AsyncProducer asyncRequestProducer, Span<?> span, ElasticContext<?> toPropagate); | ||
|
||
FutureCallbackWrapper wrapFutureCallback(FutureCallback futureCallback, HttpContext httpContext, Span<?> span); | ||
|
||
void failedBeforeRequestStarted(FutureCallbackWrapper cb, Throwable t); | ||
|
||
void recycle(AsyncProducerWrapper requestProducerWrapper); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.