Skip to content
Open
6 changes: 6 additions & 0 deletions .fossa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,12 @@ targets:
- type: gradle
path: ./
target: ':instrumentation:armeria:armeria-grpc-1.14:javaagent'
- type: gradle
path: ./
target: ':instrumentation:async-http-client:async-http-client-1-common:javaagent'
- type: gradle
path: ./
target: ':instrumentation:async-http-client:async-http-client-1.8:javaagent'
- type: gradle
path: ./
target: ':instrumentation:async-http-client:async-http-client-1.9:javaagent'
Expand Down
2 changes: 1 addition & 1 deletion docs/supported-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ These are the supported libraries and frameworks:
| [Apache Wicket](https://wicket.apache.org/) | 8.0+ | N/A | Provides `http.route` [2] |
| [Armeria](https://armeria.dev) | 1.3+ | [opentelemetry-armeria-1.3](../instrumentation/armeria/armeria-1.3/library) | [HTTP Client Spans], [HTTP Client Metrics], [HTTP Server Spans], [HTTP Server Metrics] |
| [Armeria gRPC](https://armeria.dev) | 1.14+ | | [RPC Client Spans], [RPC Client Metrics], [RPC Server Spans], [RPC Server Metrics] |
| [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client) | 1.9+ | N/A | [HTTP Client Spans], [HTTP Client Metrics] |
| [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client) | 1.8+ | N/A | [HTTP Client Spans], [HTTP Client Metrics] |
| [Avaje Jex](https://avaje.io/jex/) | 3.0+ | N/A | Provides `http.route` [2] |
| [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html) | 1.0+ | [opentelemetry-aws-lambda-core-1.0](../instrumentation/aws-lambda/aws-lambda-core-1.0/library),<br>[opentelemetry-aws-lambda-events-3.11](../instrumentation/aws-lambda/aws-lambda-events-3.11/library) | [FaaS Server Spans] |
| [AWS SDK](https://aws.amazon.com/sdk-for-java/) | 1.11 - 1.12.583,<br>2.2+ | [opentelemetry-aws-sdk-1.11](../instrumentation/aws-sdk/aws-sdk-1.11/library),<br>[opentelemetry-aws-sdk-1.11-autoconfigure](../instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure),<br>[opentelemetry-aws-sdk-2.2](../instrumentation/aws-sdk/aws-sdk-2.2/library),<br>[opentelemetry-aws-sdk-2.2-autoconfigure](../instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure) | [Messaging Spans], [Database Client Spans], [Database Client Metrics]&nbsp;[6], [HTTP Client Spans], [GenAI Client Spans], [GenAI Client Metrics] |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
plugins {
id("otel.javaagent-instrumentation")
}

dependencies {
compileOnly("com.ning:async-http-client:1.8.3")

compileOnly("com.google.auto.value:auto-value-annotations")
annotationProcessor("com.google.auto.value:auto-value")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import com.google.auto.value.AutoValue;
import com.ning.http.client.Request;
import com.ning.http.client.Response;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;

@AutoValue
public abstract class AsyncHandlerData {

public static AsyncHandlerData create(
Context parentContext,
Context context,
Request request,
Instrumenter<Request, Response> instrumenter) {
return new AutoValue_AsyncHandlerData(parentContext, context, request, instrumenter);
}

public abstract Context getParentContext();

public abstract Context getContext();

public abstract Request getRequest();

public abstract Instrumenter<Request, Response> getInstrumenter();

public void end(Response response, Throwable throwable) {
Instrumenter<Request, Response> instrumenter = getInstrumenter();
if (instrumenter != null) {
instrumenter.end(getContext(), getRequest(), response, throwable);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import com.ning.http.client.Request;
import javax.annotation.Nullable;

public interface AsyncHttpClientHelper {

/**
* Get the full URL from the request.
*
* @param request the HTTP request
* @return the full URL as a string, or null if it cannot be determined
*/
@Nullable
String getUrlFull(Request request);

/**
* Get the server address (host) from the request.
*
* @param request the HTTP request
* @return the server address
*/
String getServerAddress(Request request);

/**
* Get the server port from the request.
*
* @param request the HTTP request
* @return the server port
*/
Integer getServerPort(Request request);

/**
* Set a header on the request.
*
* @param request the HTTP request
* @param key the header name
* @param value the header value
*/
void setHeader(Request request, String key, String value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,38 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import static java.util.Collections.emptyList;

import com.ning.http.client.Request;
import com.ning.http.client.Response;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

final class AsyncHttpClientHttpAttributesGetter
implements HttpClientAttributesGetter<Request, Response> {

private final AsyncHttpClientHelper helper;

AsyncHttpClientHttpAttributesGetter(AsyncHttpClientHelper helper) {
this.helper = helper;
}

@Override
public String getHttpRequestMethod(Request request) {
return request.getMethod();
}

@Override
public String getUrlFull(Request request) {
return request.getUri().toUrl();
return helper.getUrlFull(request);
}

@Override
public List<String> getHttpRequestHeader(Request request, String name) {
return request.getHeaders().getOrDefault(name, Collections.emptyList());
return request.getHeaders().getOrDefault(name, emptyList());
}

@Override
Expand All @@ -38,16 +45,16 @@ public Integer getHttpResponseStatusCode(

@Override
public List<String> getHttpResponseHeader(Request request, Response response, String name) {
return response.getHeaders().getOrDefault(name, Collections.emptyList());
return response.getHeaders().getOrDefault(name, emptyList());
}

@Override
public String getServerAddress(Request request) {
return request.getUri().getHost();
return helper.getServerAddress(request);
}

@Override
public Integer getServerPort(Request request) {
return request.getUri().getPort();
return helper.getServerPort(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import com.ning.http.client.Request;
import com.ning.http.client.Response;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpClientInstrumenters;

public final class AsyncHttpClientInstrumenterFactory {

public static Instrumenter<Request, Response> create(
String instrumentationName, AsyncHttpClientHelper helper) {
AsyncHttpClientHttpAttributesGetter httpAttributesGetter =
new AsyncHttpClientHttpAttributesGetter(helper);
HttpHeaderSetter headerSetter = new HttpHeaderSetter(helper);

return JavaagentHttpClientInstrumenters.create(
instrumentationName, httpAttributesGetter, headerSetter);
}

private AsyncHttpClientInstrumenterFactory() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import com.ning.http.client.Request;
import io.opentelemetry.context.propagation.TextMapSetter;

enum HttpHeaderSetter implements TextMapSetter<Request> {
INSTANCE;
final class HttpHeaderSetter implements TextMapSetter<Request> {

private final AsyncHttpClientHelper helper;

HttpHeaderSetter(AsyncHttpClientHelper helper) {
this.helper = helper;
}

@Override
public void set(Request carrier, String key, String value) {
carrier.getHeaders().replaceWith(key, value);
helper.setHeader(carrier, key, value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.ASYNC_HANDLER_DATA;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.instrumenter;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.common.VirtualFieldHelper.ASYNC_HANDLER_DATA;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperClass;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
Expand Down Expand Up @@ -58,7 +57,8 @@ public static Scope onEnter(
return null;
}
ASYNC_HANDLER_DATA.set(handler, null);
instrumenter().end(data.getContext(), data.getRequest(), response, null);

data.end(response, null);
return data.getParentContext().makeCurrent();
}

Expand All @@ -82,7 +82,8 @@ public static Scope onEnter(
return null;
}
ASYNC_HANDLER_DATA.set(handler, null);
instrumenter().end(data.getContext(), data.getRequest(), null, throwable);

data.end(null, throwable);
return data.getParentContext().makeCurrent();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;

import com.ning.http.client.AsyncHandler;
import io.opentelemetry.instrumentation.api.util.VirtualField;

public final class VirtualFieldHelper {
public static final VirtualField<AsyncHandler<?>, AsyncHandlerData> ASYNC_HANDLER_DATA =
VirtualField.find(AsyncHandler.class, AsyncHandlerData.class);

private VirtualFieldHelper() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
plugins {
id("otel.javaagent-instrumentation")
}

muzzle {
pass {
group.set("com.ning")
module.set("async-http-client")
versions.set("[1.8.0,1.9.0)")
assertInverse.set(true)
}
}

dependencies {
implementation(project(":instrumentation:async-http-client:async-http-client-1-common:javaagent"))

library("com.ning:async-http-client:1.8.3")

compileOnly("com.google.auto.value:auto-value-annotations")
annotationProcessor("com.google.auto.value:auto-value")

testInstrumentation(project(":instrumentation:netty:netty-3.8:javaagent"))
testInstrumentation(project(":instrumentation:async-http-client:async-http-client-1.9:javaagent"))
testInstrumentation(project(":instrumentation:async-http-client:async-http-client-2.0:javaagent"))

latestDepTestLibrary("com.ning:async-http-client:1.8.+") // see async-http-client-1.9 module
}

tasks {
withType<Test>().configureEach {
// required on jdk17
jvmArgs("--add-exports=java.base/sun.security.util=ALL-UNNAMED")
jvmArgs("-XX:+IgnoreUnrecognizedVMOptions")

systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean)

systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false")
}
}

// async-http-client 1.8.x does not work with Netty versions newer than this due to referencing an
// internal file.
configurations.configureEach {
if (!name.contains("muzzle")) {
resolutionStrategy {
eachDependency {
// specifying a fixed version for all libraries with io.netty' group
if (requested.group == "io.netty" && requested.name != "netty-bom") {
useVersion("3.9.0.Final")
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_8;

import com.ning.http.client.Request;
import io.opentelemetry.javaagent.instrumentation.asynchttpclient.common.AsyncHttpClientHelper;
import java.net.MalformedURLException;
import javax.annotation.Nullable;

final class AsyncHttpClient18Helper implements AsyncHttpClientHelper {

static final AsyncHttpClient18Helper INSTANCE = new AsyncHttpClient18Helper();

private AsyncHttpClient18Helper() {}

@Override
@Nullable
public String getUrlFull(Request request) {
try {
return request.getURI().toURL().toString();
} catch (MalformedURLException e) {
return null;
}
}

@Override
public String getServerAddress(Request request) {
return request.getOriginalURI().getHost();
}

@Override
public Integer getServerPort(Request request) {
return request.getOriginalURI().getPort();
}

@Override
public void setHeader(Request request, String key, String value) {
request.getHeaders().replace(key, value);
}
}
Loading
Loading