diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/BulkGetCompletionListener.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/BulkGetCompletionListener.java index e6b3239c3c3a..e26b1c1b9a12 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/BulkGetCompletionListener.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/BulkGetCompletionListener.java @@ -9,9 +9,11 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import java.util.Collection; import java.util.concurrent.ExecutionException; import javax.annotation.Nullable; import net.spy.memcached.MemcachedConnection; +import net.spy.memcached.MemcachedNode; import net.spy.memcached.internal.BulkGetFuture; public class BulkGetCompletionListener extends CompletionListener> @@ -24,13 +26,42 @@ private BulkGetCompletionListener(Context parentContext, SpymemcachedRequest req @Nullable public static BulkGetCompletionListener create( Context parentContext, MemcachedConnection connection, String methodName) { - SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName); + MemcachedNode handlingNode = getRepresentativeNodeFromConnection(connection); + SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName, handlingNode); if (!instrumenter().shouldStart(parentContext, request)) { return null; } return new BulkGetCompletionListener(parentContext, request); } + @Nullable + private static MemcachedNode getRepresentativeNodeFromConnection(MemcachedConnection connection) { + try { + // Strategy: Get the "most representative" node for bulk operations + // We choose the last active node in the list, which often represents + // the most recently added or most stable node in the cluster + Collection allNodes = connection.getLocator().getAll(); + + MemcachedNode lastActiveNode = null; + MemcachedNode fallbackNode = null; + + for (MemcachedNode node : allNodes) { + if (fallbackNode == null) { + fallbackNode = node; + } + + if (node.isActive()) { + lastActiveNode = node; + } + } + + // Return the last active node, or fallback to the first node + return lastActiveNode != null ? lastActiveNode : fallbackNode; + } catch (RuntimeException e) { + return null; + } + } + @Override public void onComplete(BulkGetFuture future) { closeAsyncSpan(future); diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/GetCompletionListener.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/GetCompletionListener.java index 012677c76fa1..40112beea579 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/GetCompletionListener.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/GetCompletionListener.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.spymemcached; +import static io.opentelemetry.javaagent.instrumentation.spymemcached.SpymemcachedSingletons.FUTURE_OPERATION; import static io.opentelemetry.javaagent.instrumentation.spymemcached.SpymemcachedSingletons.instrumenter; import io.opentelemetry.api.trace.Span; @@ -12,7 +13,9 @@ import java.util.concurrent.ExecutionException; import javax.annotation.Nullable; import net.spy.memcached.MemcachedConnection; +import net.spy.memcached.MemcachedNode; import net.spy.memcached.internal.GetFuture; +import net.spy.memcached.ops.Operation; public class GetCompletionListener extends CompletionListener> implements net.spy.memcached.internal.GetCompletionListener { @@ -23,14 +26,27 @@ private GetCompletionListener(Context parentContext, SpymemcachedRequest request @Nullable public static GetCompletionListener create( - Context parentContext, MemcachedConnection connection, String methodName) { - SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName); + Context parentContext, + MemcachedConnection connection, + String methodName, + GetFuture future) { + MemcachedNode handlingNode = extractHandlingNodeFromFuture(future); + SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName, handlingNode); if (!instrumenter().shouldStart(parentContext, request)) { return null; } return new GetCompletionListener(parentContext, request); } + @Nullable + private static MemcachedNode extractHandlingNodeFromFuture(GetFuture future) { + Operation operation = FUTURE_OPERATION.get(future); + if (operation != null) { + return operation.getHandlingNode(); + } + return null; + } + @Override public void onComplete(GetFuture future) { closeAsyncSpan(future); diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/MemcachedClientInstrumentation.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/MemcachedClientInstrumentation.java index 645579db34f2..6a01e17a0863 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/MemcachedClientInstrumentation.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/MemcachedClientInstrumentation.java @@ -76,7 +76,7 @@ public static void methodExit( if (future != null) { OperationCompletionListener listener = OperationCompletionListener.create( - currentContext(), client.getConnection(), methodName); + currentContext(), client.getConnection(), methodName, future); if (listener != null) { future.addListener(listener); } @@ -106,7 +106,8 @@ public static void methodExit( if (future != null) { GetCompletionListener listener = - GetCompletionListener.create(currentContext(), client.getConnection(), methodName); + GetCompletionListener.create( + currentContext(), client.getConnection(), methodName, future); if (listener != null) { future.addListener(listener); } @@ -156,7 +157,7 @@ private AdviceScope(CallDepth callDepth, @Nullable SyncCompletionListener listen this.listener = listener; } - public static AdviceScope start(MemcachedClient client, String methodName) { + public static AdviceScope start(MemcachedClient client, String methodName, String key) { CallDepth callDepth = CallDepth.forClass(MemcachedClient.class); if (callDepth.getAndIncrement() > 0) { return new AdviceScope(callDepth, null); @@ -164,7 +165,8 @@ public static AdviceScope start(MemcachedClient client, String methodName) { return new AdviceScope( callDepth, - SyncCompletionListener.create(Context.current(), client.getConnection(), methodName)); + SyncCompletionListener.create( + Context.current(), client.getConnection(), methodName, key)); } public void end(@Nullable Throwable throwable) { @@ -178,8 +180,10 @@ public void end(@Nullable Throwable throwable) { @Advice.OnMethodEnter(suppress = Throwable.class) public static AdviceScope methodEnter( - @Advice.This MemcachedClient client, @Advice.Origin("#m") String methodName) { - return AdviceScope.start(client, methodName); + @Advice.This MemcachedClient client, + @Advice.Origin("#m") String methodName, + @Advice.Argument(0) String key) { + return AdviceScope.start(client, methodName, key); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/OperationCompletionListener.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/OperationCompletionListener.java index 0e0e4fd3a91b..12292ecfa146 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/OperationCompletionListener.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/OperationCompletionListener.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.spymemcached; +import static io.opentelemetry.javaagent.instrumentation.spymemcached.SpymemcachedSingletons.FUTURE_OPERATION; import static io.opentelemetry.javaagent.instrumentation.spymemcached.SpymemcachedSingletons.instrumenter; import io.opentelemetry.api.trace.Span; @@ -12,7 +13,9 @@ import java.util.concurrent.ExecutionException; import javax.annotation.Nullable; import net.spy.memcached.MemcachedConnection; +import net.spy.memcached.MemcachedNode; import net.spy.memcached.internal.OperationFuture; +import net.spy.memcached.ops.Operation; public class OperationCompletionListener extends CompletionListener> implements net.spy.memcached.internal.OperationCompletionListener { @@ -23,14 +26,27 @@ private OperationCompletionListener(Context parentContext, SpymemcachedRequest r @Nullable public static OperationCompletionListener create( - Context parentContext, MemcachedConnection connection, String methodName) { - SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName); + Context parentContext, + MemcachedConnection connection, + String methodName, + OperationFuture future) { + MemcachedNode handlingNode = extractHandlingNodeFromFuture(future); + SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName, handlingNode); if (!instrumenter().shouldStart(parentContext, request)) { return null; } return new OperationCompletionListener(parentContext, request); } + @Nullable + private static MemcachedNode extractHandlingNodeFromFuture(OperationFuture future) { + Operation operation = FUTURE_OPERATION.get(future); + if (operation != null) { + return operation.getHandlingNode(); + } + return null; + } + @Override public void onComplete(OperationFuture future) { closeAsyncSpan(future); diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SetOperationInstrumentation.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SetOperationInstrumentation.java new file mode 100644 index 000000000000..3d5df01ca5da --- /dev/null +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SetOperationInstrumentation.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.spymemcached; + +import static io.opentelemetry.javaagent.instrumentation.spymemcached.SpymemcachedSingletons.FUTURE_OPERATION; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import java.util.concurrent.Future; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.spy.memcached.internal.GetFuture; +import net.spy.memcached.internal.OperationFuture; +import net.spy.memcached.ops.Operation; + +public class SetOperationInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return namedOneOf( + "net.spy.memcached.internal.OperationFuture", "net.spy.memcached.internal.GetFuture"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isMethod().and(named("setOperation")).and(takesArguments(1)), + this.getClass().getName() + "$SetOperationAdvice"); + } + + @SuppressWarnings("unused") + public static class SetOperationAdvice { + + @Advice.OnMethodExit(suppress = Throwable.class) + public static void onExit(@Advice.This Object future, @Advice.Argument(0) Operation operation) { + + if (future instanceof OperationFuture || future instanceof GetFuture) { + FUTURE_OPERATION.set((Future) future, operation); + } + } + } +} diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedInstrumentationModule.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedInstrumentationModule.java index 6f150ef5ef6c..1267bb38957e 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedInstrumentationModule.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedInstrumentationModule.java @@ -5,7 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.spymemcached; -import static java.util.Collections.singletonList; +import static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; @@ -23,7 +23,7 @@ public SpymemcachedInstrumentationModule() { @Override public List typeInstrumentations() { - return singletonList(new MemcachedClientInstrumentation()); + return asList(new MemcachedClientInstrumentation(), new SetOperationInstrumentation()); } @Override diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedNetworkAttributesGetter.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedNetworkAttributesGetter.java new file mode 100644 index 000000000000..8ffbdeaf2235 --- /dev/null +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedNetworkAttributesGetter.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.spymemcached; + +import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesGetter; +import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import javax.annotation.Nullable; +import net.spy.memcached.MemcachedNode; + +final class SpymemcachedNetworkAttributesGetter + implements ServerAttributesGetter, + NetworkAttributesGetter { + + @Nullable + @Override + public String getServerAddress(SpymemcachedRequest request) { + MemcachedNode handlingNode = request.getHandlingNode(); + if (handlingNode != null) { + SocketAddress socketAddress = handlingNode.getSocketAddress(); + if (socketAddress instanceof InetSocketAddress) { + return ((InetSocketAddress) socketAddress).getHostString(); + } + } + return null; + } + + @Nullable + @Override + public Integer getServerPort(SpymemcachedRequest request) { + MemcachedNode handlingNode = request.getHandlingNode(); + if (handlingNode != null) { + SocketAddress socketAddress = handlingNode.getSocketAddress(); + if (socketAddress instanceof InetSocketAddress) { + return ((InetSocketAddress) socketAddress).getPort(); + } + } + return null; + } +} diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedRequest.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedRequest.java index e8c45837a5ae..56d905eba2d3 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedRequest.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedRequest.java @@ -6,19 +6,25 @@ package io.opentelemetry.javaagent.instrumentation.spymemcached; import com.google.auto.value.AutoValue; +import javax.annotation.Nullable; import net.spy.memcached.MemcachedConnection; +import net.spy.memcached.MemcachedNode; @AutoValue public abstract class SpymemcachedRequest { - public static SpymemcachedRequest create(MemcachedConnection connection, String statement) { - return new AutoValue_SpymemcachedRequest(connection, statement); + public static SpymemcachedRequest create( + MemcachedConnection connection, String statement, @Nullable MemcachedNode handlingNode) { + return new AutoValue_SpymemcachedRequest(connection, statement, handlingNode); } public abstract MemcachedConnection getConnection(); public abstract String getStatement(); + @Nullable + public abstract MemcachedNode getHandlingNode(); + public String dbOperation() { String statement = getStatement(); if (statement.startsWith("async")) { diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedSingletons.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedSingletons.java index b896f5688ba4..804de04ff006 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedSingletons.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedSingletons.java @@ -11,14 +11,22 @@ import io.opentelemetry.instrumentation.api.incubator.semconv.db.DbClientSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesExtractor; +import io.opentelemetry.instrumentation.api.util.VirtualField; +import java.util.concurrent.Future; +import net.spy.memcached.ops.Operation; public final class SpymemcachedSingletons { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.spymemcached-2.12"; private static final Instrumenter INSTRUMENTER; + public static final VirtualField, Operation> FUTURE_OPERATION; + static { SpymemcachedAttributesGetter dbAttributesGetter = new SpymemcachedAttributesGetter(); + SpymemcachedNetworkAttributesGetter netAttributesGetter = + new SpymemcachedNetworkAttributesGetter(); INSTRUMENTER = Instrumenter.builder( @@ -26,8 +34,11 @@ public final class SpymemcachedSingletons { INSTRUMENTATION_NAME, DbClientSpanNameExtractor.create(dbAttributesGetter)) .addAttributesExtractor(DbClientAttributesExtractor.create(dbAttributesGetter)) + .addAttributesExtractor(ServerAttributesExtractor.create(netAttributesGetter)) .addOperationMetrics(DbClientMetrics.get()) .buildInstrumenter(SpanKindExtractor.alwaysClient()); + + FUTURE_OPERATION = VirtualField.find(Future.class, Operation.class); } public static Instrumenter instrumenter() { diff --git a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SyncCompletionListener.java b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SyncCompletionListener.java index c24ef86e6c93..ed1d372e4869 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SyncCompletionListener.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SyncCompletionListener.java @@ -12,6 +12,7 @@ import java.util.logging.Logger; import javax.annotation.Nullable; import net.spy.memcached.MemcachedConnection; +import net.spy.memcached.MemcachedNode; public class SyncCompletionListener extends CompletionListener { @@ -23,14 +24,26 @@ private SyncCompletionListener(Context parentContext, SpymemcachedRequest reques @Nullable public static SyncCompletionListener create( - Context parentContext, MemcachedConnection connection, String methodName) { - SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName); + Context parentContext, MemcachedConnection connection, String methodName, String key) { + // For sync operations, determine the handling node based on the key + MemcachedNode handlingNode = getHandlingNodeForKey(connection, key); + SpymemcachedRequest request = SpymemcachedRequest.create(connection, methodName, handlingNode); if (!instrumenter().shouldStart(parentContext, request)) { return null; } return new SyncCompletionListener(parentContext, request); } + @Nullable + private static MemcachedNode getHandlingNodeForKey(MemcachedConnection connection, String key) { + try { + // Use the connection's locator to find the primary node for this key + return connection.getLocator().getPrimary(key); + } catch (RuntimeException e) { + return null; + } + } + @Override protected void processResult(Span span, Void future) { logger.severe("processResult was called on SyncCompletionListener. This should never happen."); diff --git a/instrumentation/spymemcached-2.12/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedTest.java b/instrumentation/spymemcached-2.12/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedTest.java index 0408bbdd19af..9ac4fc3eb27e 100644 --- a/instrumentation/spymemcached-2.12/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedTest.java +++ b/instrumentation/spymemcached-2.12/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedTest.java @@ -14,6 +14,8 @@ import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_MESSAGE; import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_STACKTRACE; import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_TYPE; +import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; +import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; import static java.util.Collections.emptyMap; @@ -152,6 +154,8 @@ void getHit() { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -174,6 +178,8 @@ void getMiss() { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "miss")))); } @@ -209,6 +215,8 @@ void getCancel() { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(booleanKey("spymemcached.command.cancelled"), true)))); } @@ -268,7 +276,9 @@ void getTimeout() throws InterruptedException { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "get")))); + equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -296,7 +306,9 @@ void bulkGet() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "getBulk")))); + equalTo(maybeStable(DB_OPERATION), "getBulk"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -320,7 +332,9 @@ void set() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "set")))); + equalTo(maybeStable(DB_OPERATION), "set"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -357,6 +371,8 @@ void setCancel() { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "set"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(booleanKey("spymemcached.command.cancelled"), true)))); } @@ -382,7 +398,9 @@ void add() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "add")), + equalTo(maybeStable(DB_OPERATION), "add"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -392,6 +410,8 @@ void add() throws Exception { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -418,7 +438,9 @@ void secondAdd() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "add")), + equalTo(maybeStable(DB_OPERATION), "add"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("add") .hasKind(SpanKind.CLIENT) @@ -427,7 +449,9 @@ void secondAdd() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "add")))); + equalTo(maybeStable(DB_OPERATION), "add"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -452,7 +476,9 @@ void delete() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "delete")), + equalTo(maybeStable(DB_OPERATION), "delete"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -462,6 +488,8 @@ void delete() throws Exception { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "miss")))); } @@ -486,7 +514,9 @@ void deleteNonExistent() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "delete")))); + equalTo(maybeStable(DB_OPERATION), "delete"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -512,7 +542,9 @@ void replace() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "replace")), + equalTo(maybeStable(DB_OPERATION), "replace"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -522,6 +554,8 @@ void replace() throws Exception { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -550,7 +584,9 @@ void replaceNonExistent() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "replace")))); + equalTo(maybeStable(DB_OPERATION), "replace"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -577,7 +613,9 @@ void append() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "gets")), + equalTo(maybeStable(DB_OPERATION), "gets"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("append") .hasKind(SpanKind.CLIENT) @@ -586,7 +624,9 @@ void append() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "append")), + equalTo(maybeStable(DB_OPERATION), "append"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -596,6 +636,8 @@ void append() throws Exception { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -623,7 +665,9 @@ void prepend() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "gets")), + equalTo(maybeStable(DB_OPERATION), "gets"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("prepend") .hasKind(SpanKind.CLIENT) @@ -632,7 +676,9 @@ void prepend() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "prepend")), + equalTo(maybeStable(DB_OPERATION), "prepend"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -642,6 +688,8 @@ void prepend() throws Exception { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -669,7 +717,9 @@ void cas() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "gets")), + equalTo(maybeStable(DB_OPERATION), "gets"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("cas") .hasKind(SpanKind.CLIENT) @@ -678,7 +728,9 @@ void cas() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "cas")))); + equalTo(maybeStable(DB_OPERATION), "cas"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -704,7 +756,9 @@ void casNotFound() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "cas")))); + equalTo(maybeStable(DB_OPERATION), "cas"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -728,7 +782,9 @@ void touch() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "touch")))); + equalTo(maybeStable(DB_OPERATION), "touch"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -753,7 +809,9 @@ void touchNonExistent() throws Exception { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "touch")))); + equalTo(maybeStable(DB_OPERATION), "touch"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -778,7 +836,9 @@ void getAndTouch() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "getAndTouch")))); + equalTo(maybeStable(DB_OPERATION), "getAndTouch"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -803,7 +863,9 @@ void getAndTouchNonExistent() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "getAndTouch")))); + equalTo(maybeStable(DB_OPERATION), "getAndTouch"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -832,7 +894,9 @@ it needs values to be strings (with digits in them) and it returns actual long f equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "decr")), + equalTo(maybeStable(DB_OPERATION), "decr"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -842,6 +906,8 @@ it needs values to be strings (with digits in them) and it returns actual long f maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -866,7 +932,9 @@ void decrNonExistent() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "decr")))); + equalTo(maybeStable(DB_OPERATION), "decr"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -894,7 +962,9 @@ void decrException() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "decr")))); + equalTo(maybeStable(DB_OPERATION), "decr"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -923,7 +993,9 @@ it needs values to be strings (with digits in them) and it returns actual long f equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "incr")), + equalTo(maybeStable(DB_OPERATION), "incr"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))), span -> span.hasName("get") .hasKind(SpanKind.CLIENT) @@ -933,6 +1005,8 @@ it needs values to be strings (with digits in them) and it returns actual long f maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), equalTo(maybeStable(DB_OPERATION), "get"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211)), equalTo(stringKey("spymemcached.result"), "hit")))); } @@ -957,7 +1031,9 @@ void incrNonExistent() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "incr")))); + equalTo(maybeStable(DB_OPERATION), "incr"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } @Test @@ -985,7 +1061,9 @@ void incrException() { equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.MEMCACHED), - equalTo(maybeStable(DB_OPERATION), "incr")))); + equalTo(maybeStable(DB_OPERATION), "incr"), + equalTo(SERVER_ADDRESS, memcachedContainer.getHost()), + equalTo(SERVER_PORT, memcachedContainer.getMappedPort(11211))))); } private static String key(String k) {