diff --git a/instrumentation/armeria-1.3/javaagent/build.gradle.kts b/instrumentation/armeria-1.3/javaagent/build.gradle.kts index 5bae93ddeb..1c8e9f758b 100644 --- a/instrumentation/armeria-1.3/javaagent/build.gradle.kts +++ b/instrumentation/armeria-1.3/javaagent/build.gradle.kts @@ -18,3 +18,9 @@ dependencies { testImplementation(project(":instrumentation:armeria-1.3:testing")) } + +tasks { + test { + systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) + } +} diff --git a/instrumentation/armeria-1.3/library/build.gradle.kts b/instrumentation/armeria-1.3/library/build.gradle.kts index fc599f337d..2d38bf072d 100644 --- a/instrumentation/armeria-1.3/library/build.gradle.kts +++ b/instrumentation/armeria-1.3/library/build.gradle.kts @@ -8,3 +8,9 @@ dependencies { testImplementation(project(":instrumentation:armeria-1.3:testing")) } + +tasks { + test { + systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) + } +} diff --git a/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpClientTest.java b/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpClientTest.java index 9ce8cfd6c7..6d7477fb4b 100644 --- a/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpClientTest.java +++ b/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpClientTest.java @@ -100,6 +100,12 @@ public abstract class AbstractArmeriaHttpClientTest extends AbstractHttpClientTe // armeria requests can't be reused options.disableTestReusedRequest(); options.enableTestReadTimeout(); + + // TODO armeria 1.19 changed how the HttpResponse#aggregate() method works, and callbacks no + // longer execute in parent context + if (Boolean.getBoolean("testLatestDeps")) { + options.disableTestCallback(); + } } @Test diff --git a/instrumentation/couchbase/couchbase-2.6/javaagent/src/test/groovy/CouchbaseSpanUtil.groovy b/instrumentation/couchbase/couchbase-2.6/javaagent/src/test/groovy/CouchbaseSpanUtil.groovy index 7ffd00ca48..84c548b1fe 100644 --- a/instrumentation/couchbase/couchbase-2.6/javaagent/src/test/groovy/CouchbaseSpanUtil.groovy +++ b/instrumentation/couchbase/couchbase-2.6/javaagent/src/test/groovy/CouchbaseSpanUtil.groovy @@ -37,16 +37,16 @@ class CouchbaseSpanUtil { "$SemanticAttributes.NET_TRANSPORT" { it == null || it == IP_TCP } // Because of caching, not all requests hit the server so these attributes may be absent "net.sock.peer.addr" { it == "127.0.0.1" || it == null } - "net.sock.peer.name" { it == "localhost" || it == null } - "net.sock.peer.port" { it == null || Number } + "net.sock.peer.name" { it == "localhost" || it == "127.0.0.1" || it == null } + "net.sock.peer.port" { it == null || it instanceof Number } // Because of caching, not all requests hit the server so this tag may be absent - "couchbase.local.address" { it == null || String } + "couchbase.local.address" { it == null || it instanceof String } // Not all couchbase operations have operation id. Notably, 'ViewQuery's do not // We assign a spanName of 'Bucket.query' and this is shared with n1ql queries // that do have operation ids - "couchbase.operation_id" { it == null || String } + "couchbase.operation_id" { it == null || it instanceof String } } } } diff --git a/instrumentation/couchbase/couchbase-3.2/javaagent/build.gradle.kts b/instrumentation/couchbase/couchbase-3.2/javaagent/build.gradle.kts index 2ae51cc0f2..e1a598c0cb 100644 --- a/instrumentation/couchbase/couchbase-3.2/javaagent/build.gradle.kts +++ b/instrumentation/couchbase/couchbase-3.2/javaagent/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { tasks { test { + systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) usesService(gradle.sharedServices.registrations["testcontainersBuildService"].getService()) } } diff --git a/instrumentation/couchbase/couchbase-3.2/javaagent/src/test/groovy/CouchbaseClient32Test.groovy b/instrumentation/couchbase/couchbase-3.2/javaagent/src/test/groovy/CouchbaseClient32Test.groovy index 4f28650d9f..9b8a4fba60 100644 --- a/instrumentation/couchbase/couchbase-3.2/javaagent/src/test/groovy/CouchbaseClient32Test.groovy +++ b/instrumentation/couchbase/couchbase-3.2/javaagent/src/test/groovy/CouchbaseClient32Test.groovy @@ -17,6 +17,8 @@ import spock.lang.Shared import java.time.Duration +import static io.opentelemetry.api.trace.StatusCode.ERROR + // Couchbase instrumentation is owned upstream so we don't assert on the contents of the spans, only // that the instrumentation is properly registered by the agent, meaning some spans were generated. class CouchbaseClient32Test extends AgentInstrumentationSpecification { @@ -61,6 +63,10 @@ class CouchbaseClient32Test extends AgentInstrumentationSpecification { trace(0, 2) { span(0) { name(~/.*get/) + if (Boolean.getBoolean("testLatestDeps")) { + // this is the correct behavior + status ERROR + } } span(1) { name(~/.*dispatch_to_server/) diff --git a/instrumentation/jedis/jedis-4.0/javaagent/src/test/groovy/Jedis40ClientTest.groovy b/instrumentation/jedis/jedis-4.0/javaagent/src/test/groovy/Jedis40ClientTest.groovy index 28fed6057b..affdc4d86b 100644 --- a/instrumentation/jedis/jedis-4.0/javaagent/src/test/groovy/Jedis40ClientTest.groovy +++ b/instrumentation/jedis/jedis-4.0/javaagent/src/test/groovy/Jedis40ClientTest.groovy @@ -53,7 +53,7 @@ class Jedis40ClientTest extends AgentInstrumentationSpecification { "$SemanticAttributes.DB_OPERATION" "SET" "$SemanticAttributes.NET_TRANSPORT" SemanticAttributes.NetTransportValues.IP_TCP "net.sock.peer.addr" "127.0.0.1" - "net.sock.peer.name" "localhost" + "net.sock.peer.name" { it == "localhost" || it == "127.0.0.1" } "net.sock.peer.port" port } } @@ -80,7 +80,7 @@ class Jedis40ClientTest extends AgentInstrumentationSpecification { "$SemanticAttributes.DB_OPERATION" "SET" "$SemanticAttributes.NET_TRANSPORT" SemanticAttributes.NetTransportValues.IP_TCP "net.sock.peer.addr" "127.0.0.1" - "net.sock.peer.name" "localhost" + "net.sock.peer.name" { it == "localhost" || it == "127.0.0.1" } "net.sock.peer.port" port } } @@ -95,7 +95,7 @@ class Jedis40ClientTest extends AgentInstrumentationSpecification { "$SemanticAttributes.DB_OPERATION" "GET" "$SemanticAttributes.NET_TRANSPORT" SemanticAttributes.NetTransportValues.IP_TCP "net.sock.peer.addr" "127.0.0.1" - "net.sock.peer.name" "localhost" + "net.sock.peer.name" { it == "localhost" || it == "127.0.0.1" } "net.sock.peer.port" port } } @@ -122,7 +122,7 @@ class Jedis40ClientTest extends AgentInstrumentationSpecification { "$SemanticAttributes.DB_OPERATION" "SET" "$SemanticAttributes.NET_TRANSPORT" SemanticAttributes.NetTransportValues.IP_TCP "net.sock.peer.addr" "127.0.0.1" - "net.sock.peer.name" "localhost" + "net.sock.peer.name" { it == "localhost" || it == "127.0.0.1" } "net.sock.peer.port" port } } @@ -137,7 +137,7 @@ class Jedis40ClientTest extends AgentInstrumentationSpecification { "$SemanticAttributes.DB_OPERATION" "RANDOMKEY" "$SemanticAttributes.NET_TRANSPORT" SemanticAttributes.NetTransportValues.IP_TCP "net.sock.peer.addr" "127.0.0.1" - "net.sock.peer.name" "localhost" + "net.sock.peer.name" { it == "localhost" || it == "127.0.0.1" } "net.sock.peer.port" port } } diff --git a/instrumentation/restlet/restlet-2.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v2_0/internal/RestletNetAttributesGetter.java b/instrumentation/restlet/restlet-2.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v2_0/internal/RestletNetAttributesGetter.java index 6a4f22a48b..845ca8b261 100644 --- a/instrumentation/restlet/restlet-2.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v2_0/internal/RestletNetAttributesGetter.java +++ b/instrumentation/restlet/restlet-2.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v2_0/internal/RestletNetAttributesGetter.java @@ -5,15 +5,75 @@ package io.opentelemetry.instrumentation.restlet.v2_0.internal; +import static java.lang.invoke.MethodType.methodType; + import io.opentelemetry.instrumentation.api.instrumenter.net.NetServerAttributesGetter; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import javax.annotation.Nullable; import org.restlet.Request; -import org.restlet.engine.http.HttpRequest; -import org.restlet.engine.http.ServerCall; final class RestletNetAttributesGetter implements NetServerAttributesGetter { + private static final Class HTTP_REQUEST_CLASS; + private static final MethodHandle GET_HTTP_CALL; + private static final MethodHandle GET_HOST_DOMAIN; + private static final MethodHandle GET_SERVER_PORT; + private static final MethodHandle GET_SERVER_ADDRESS; + + static { + Class httpRequestClass = null; + Class serverCallClass = null; + MethodHandle getHttpCall = null; + MethodHandle getHostDomain = null; + MethodHandle getServerPort = null; + MethodHandle getServerAddress = null; + + try { + httpRequestClass = Class.forName("org.restlet.engine.http.HttpRequest"); + } catch (ClassNotFoundException e) { + // moved to another package in version 2.4 + try { + httpRequestClass = Class.forName("org.restlet.engine.adapter.HttpRequest"); + } catch (ClassNotFoundException ex) { + // ignored + } + } + + try { + serverCallClass = Class.forName("org.restlet.engine.http.ServerCall"); + } catch (ClassNotFoundException e) { + // moved to another package in version 2.4 + try { + serverCallClass = Class.forName("org.restlet.engine.adapter.ServerCall"); + } catch (ClassNotFoundException ex) { + // ignored + } + } + + if (httpRequestClass != null && serverCallClass != null) { + try { + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + getHttpCall = + lookup.findVirtual(httpRequestClass, "getHttpCall", methodType(serverCallClass)); + getHostDomain = + lookup.findVirtual(serverCallClass, "getHostDomain", methodType(String.class)); + getServerPort = lookup.findVirtual(serverCallClass, "getServerPort", methodType(int.class)); + getServerAddress = + lookup.findVirtual(serverCallClass, "getServerAddress", methodType(String.class)); + } catch (NoSuchMethodException | IllegalAccessException e) { + // ignored + } + } + + HTTP_REQUEST_CLASS = httpRequestClass; + GET_HTTP_CALL = getHttpCall; + GET_HOST_DOMAIN = getHostDomain; + GET_SERVER_PORT = getServerPort; + GET_SERVER_ADDRESS = getServerAddress; + } + @Override public String transport(Request request) { return SemanticAttributes.NetTransportValues.IP_TCP; @@ -22,15 +82,35 @@ final class RestletNetAttributesGetter implements NetServerAttributesGetter