Skip to content

Commit 105c7ca

Browse files
committed
Add server.address and server.port for lettuce
1 parent ef21f68 commit 105c7ca

File tree

15 files changed

+319
-56
lines changed

15 files changed

+319
-56
lines changed

instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66
package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
77

88
import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
9+
import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceSingletons.COMMAND_CONNECTION_INFO;
10+
import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceSingletons.CONNECTION_URI;
911
import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceSingletons.instrumenter;
1012
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
1113
import static net.bytebuddy.matcher.ElementMatchers.named;
1214
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
1315

16+
import com.lambdaworks.redis.AbstractRedisAsyncCommands;
17+
import com.lambdaworks.redis.RedisURI;
18+
import com.lambdaworks.redis.api.StatefulConnection;
1419
import com.lambdaworks.redis.protocol.AsyncCommand;
1520
import com.lambdaworks.redis.protocol.RedisCommand;
1621
import io.opentelemetry.context.Context;
@@ -60,7 +65,16 @@ public void end(
6065
}
6166

6267
@Advice.OnMethodEnter(suppress = Throwable.class)
63-
public static AdviceScope onEnter(@Advice.Argument(0) RedisCommand<?, ?, ?> command) {
68+
public static AdviceScope onEnter(
69+
@Advice.This AbstractRedisAsyncCommands<?, ?> asyncCommands,
70+
@Advice.Argument(0) RedisCommand<?, ?, ?> command) {
71+
72+
StatefulConnection<?, ?> connection = asyncCommands.getConnection();
73+
RedisURI redisUri = CONNECTION_URI.get(connection);
74+
75+
if (redisUri != null) {
76+
COMMAND_CONNECTION_INFO.set(command, redisUri);
77+
}
6478

6579
Context parentContext = currentContext();
6680
if (!instrumenter().shouldStart(parentContext, command)) {

instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
77

88
import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
9+
import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceSingletons.CONNECTION_URI;
910
import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceSingletons.connectInstrumenter;
1011
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
1112
import static net.bytebuddy.matcher.ElementMatchers.named;
1213

1314
import com.lambdaworks.redis.RedisURI;
15+
import com.lambdaworks.redis.api.StatefulConnection;
1416
import io.opentelemetry.context.Context;
1517
import io.opentelemetry.context.Scope;
1618
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
@@ -66,8 +68,14 @@ public static AdviceScope onEnter(@Advice.Argument(1) RedisURI redisUri) {
6668
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
6769
public static void onExit(
6870
@Advice.Argument(1) RedisURI redisUri,
71+
@Advice.Return @Nullable StatefulConnection<?, ?> connection,
6972
@Advice.Thrown @Nullable Throwable throwable,
7073
@Advice.Enter @Nullable AdviceScope adviceScope) {
74+
75+
if (connection != null) {
76+
CONNECTION_URI.set(connection, redisUri);
77+
}
78+
7179
if (adviceScope != null) {
7280
adviceScope.end(throwable, redisUri);
7381
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
7+
8+
import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceSingletons.COMMAND_CONNECTION_INFO;
9+
10+
import com.lambdaworks.redis.RedisURI;
11+
import com.lambdaworks.redis.protocol.RedisCommand;
12+
import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter;
13+
import javax.annotation.Nullable;
14+
15+
public final class LettuceNetworkAttributesGetter
16+
implements ServerAttributesGetter<RedisCommand<?, ?, ?>> {
17+
18+
@Override
19+
@Nullable
20+
public String getServerAddress(RedisCommand<?, ?, ?> redisCommand) {
21+
RedisURI redisUri = COMMAND_CONNECTION_INFO.get(redisCommand);
22+
return redisUri != null ? redisUri.getHost() : null;
23+
}
24+
25+
@Override
26+
@Nullable
27+
public Integer getServerPort(RedisCommand<?, ?, ?> redisCommand) {
28+
RedisURI redisUri = COMMAND_CONNECTION_INFO.get(redisCommand);
29+
return redisUri != null ? redisUri.getPort() : null;
30+
}
31+
}

instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceSingletons.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
77

88
import com.lambdaworks.redis.RedisURI;
9+
import com.lambdaworks.redis.api.StatefulConnection;
910
import com.lambdaworks.redis.protocol.AsyncCommand;
1011
import com.lambdaworks.redis.protocol.RedisCommand;
1112
import io.opentelemetry.api.GlobalOpenTelemetry;
@@ -33,29 +34,35 @@ public final class LettuceSingletons {
3334

3435
public static final VirtualField<AsyncCommand<?, ?, ?>, Context> CONTEXT =
3536
VirtualField.find(AsyncCommand.class, Context.class);
37+
public static final VirtualField<StatefulConnection<?, ?>, RedisURI> CONNECTION_URI =
38+
VirtualField.find(StatefulConnection.class, RedisURI.class);
39+
public static final VirtualField<RedisCommand<?, ?, ?>, RedisURI>
40+
COMMAND_CONNECTION_INFO = VirtualField.find(RedisCommand.class, RedisURI.class);
3641

3742
static {
3843
LettuceDbAttributesGetter dbAttributesGetter = new LettuceDbAttributesGetter();
44+
LettuceNetworkAttributesGetter netAttributesGetter = new LettuceNetworkAttributesGetter();
3945

4046
INSTRUMENTER =
4147
Instrumenter.<RedisCommand<?, ?, ?>, Void>builder(
4248
GlobalOpenTelemetry.get(),
4349
INSTRUMENTATION_NAME,
4450
DbClientSpanNameExtractor.create(dbAttributesGetter))
4551
.addAttributesExtractor(DbClientAttributesExtractor.create(dbAttributesGetter))
52+
.addAttributesExtractor(ServerAttributesExtractor.create(netAttributesGetter))
4653
.addOperationMetrics(DbClientMetrics.get())
4754
.buildInstrumenter(SpanKindExtractor.alwaysClient());
4855

49-
LettuceConnectNetworkAttributesGetter netAttributesGetter =
56+
LettuceConnectNetworkAttributesGetter connectNetAttributesGetter =
5057
new LettuceConnectNetworkAttributesGetter();
5158

5259
CONNECT_INSTRUMENTER =
5360
Instrumenter.<RedisURI, Void>builder(
5461
GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, redisUri -> "CONNECT")
55-
.addAttributesExtractor(ServerAttributesExtractor.create(netAttributesGetter))
62+
.addAttributesExtractor(ServerAttributesExtractor.create(connectNetAttributesGetter))
5663
.addAttributesExtractor(
5764
PeerServiceAttributesExtractor.create(
58-
netAttributesGetter, AgentCommonConfig.get().getPeerServiceResolver()))
65+
connectNetAttributesGetter, AgentCommonConfig.get().getPeerServiceResolver()))
5966
.addAttributesExtractor(new LettuceConnectAttributesExtractor())
6067
.setEnabled(
6168
AgentInstrumentationConfig.get()

instrumentation/lettuce/lettuce-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncClientTest.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ void testSetCommandUsingFutureGetWithTimeout()
204204
.hasKind(SpanKind.CLIENT)
205205
.hasAttributesSatisfyingExactly(
206206
equalTo(maybeStable(DB_SYSTEM), "redis"),
207-
equalTo(maybeStable(DB_OPERATION), "SET"))));
207+
equalTo(maybeStable(DB_OPERATION), "SET"),
208+
equalTo(SERVER_ADDRESS, "localhost"),
209+
equalTo(SERVER_PORT, port))));
208210
}
209211

210212
@Test
@@ -234,7 +236,9 @@ void testCommandChainedWithThenAccept() {
234236
.hasParent(trace.getSpan(0))
235237
.hasAttributesSatisfyingExactly(
236238
equalTo(maybeStable(DB_SYSTEM), "redis"),
237-
equalTo(maybeStable(DB_OPERATION), "GET")),
239+
equalTo(maybeStable(DB_OPERATION), "GET"),
240+
equalTo(SERVER_ADDRESS, "localhost"),
241+
equalTo(SERVER_PORT, port)),
238242
span ->
239243
span.hasName("callback")
240244
.hasKind(SpanKind.INTERNAL)
@@ -296,7 +300,9 @@ void getNonExistentKeyCommandWithHandleAsyncAndChainedWithThenApply() {
296300
.hasParent(trace.getSpan(0))
297301
.hasAttributesSatisfyingExactly(
298302
equalTo(maybeStable(DB_SYSTEM), "redis"),
299-
equalTo(maybeStable(DB_OPERATION), "GET")),
303+
equalTo(maybeStable(DB_OPERATION), "GET"),
304+
equalTo(SERVER_ADDRESS, "localhost"),
305+
equalTo(SERVER_PORT, port)),
300306
span ->
301307
span.hasName("callback1")
302308
.hasKind(SpanKind.INTERNAL)
@@ -337,7 +343,9 @@ void testCommandWithNoArgumentsUsingBiconsumer() {
337343
.hasParent(trace.getSpan(0))
338344
.hasAttributesSatisfyingExactly(
339345
equalTo(maybeStable(DB_SYSTEM), "redis"),
340-
equalTo(maybeStable(DB_OPERATION), "RANDOMKEY")),
346+
equalTo(maybeStable(DB_OPERATION), "RANDOMKEY"),
347+
equalTo(SERVER_ADDRESS, "localhost"),
348+
equalTo(SERVER_PORT, port)),
341349
span ->
342350
span.hasName("callback")
343351
.hasKind(SpanKind.INTERNAL)
@@ -381,15 +389,19 @@ void testHashSetAndThenNestApplyToHashGetall() {
381389
.hasKind(SpanKind.CLIENT)
382390
.hasAttributesSatisfyingExactly(
383391
equalTo(maybeStable(DB_SYSTEM), "redis"),
384-
equalTo(maybeStable(DB_OPERATION), "HMSET"))),
392+
equalTo(maybeStable(DB_OPERATION), "HMSET"),
393+
equalTo(SERVER_ADDRESS, "localhost"),
394+
equalTo(SERVER_PORT, port))),
385395
trace ->
386396
trace.hasSpansSatisfyingExactly(
387397
span ->
388398
span.hasName("HGETALL")
389399
.hasKind(SpanKind.CLIENT)
390400
.hasAttributesSatisfyingExactly(
391401
equalTo(maybeStable(DB_SYSTEM), "redis"),
392-
equalTo(maybeStable(DB_OPERATION), "HGETALL"))));
402+
equalTo(maybeStable(DB_OPERATION), "HGETALL"),
403+
equalTo(SERVER_ADDRESS, "localhost"),
404+
equalTo(SERVER_PORT, port))));
393405
}
394406

395407
@Test
@@ -425,7 +437,9 @@ void testCommandCompletesExceptionally() {
425437
new ArrayList<>(
426438
Arrays.asList(
427439
equalTo(maybeStable(DB_SYSTEM), "redis"),
428-
equalTo(maybeStable(DB_OPERATION), "DEL")));
440+
equalTo(maybeStable(DB_OPERATION), "DEL"),
441+
equalTo(SERVER_ADDRESS, "localhost"),
442+
equalTo(SERVER_PORT, port)));
429443
if (SemconvStability.emitStableDatabaseSemconv()) {
430444
assertions.add(equalTo(ERROR_TYPE, "java.lang.IllegalStateException"));
431445
}
@@ -476,6 +490,8 @@ void testCommandBeforeItFinished() {
476490
.hasAttributesSatisfyingExactly(
477491
equalTo(maybeStable(DB_SYSTEM), "redis"),
478492
equalTo(maybeStable(DB_OPERATION), "SADD"),
493+
equalTo(SERVER_ADDRESS, "localhost"),
494+
equalTo(SERVER_PORT, port),
479495
equalTo(booleanKey("lettuce.command.cancelled"), true)),
480496
span ->
481497
span.hasName("callback")
@@ -512,7 +528,9 @@ void testDebugSegfaultCommandWithNoArgumentShouldProduceSpan() {
512528
.hasKind(SpanKind.CLIENT)
513529
.hasAttributesSatisfyingExactly(
514530
equalTo(maybeStable(DB_SYSTEM), "redis"),
515-
equalTo(maybeStable(DB_OPERATION), "DEBUG"))));
531+
equalTo(maybeStable(DB_OPERATION), "DEBUG"),
532+
equalTo(SERVER_ADDRESS, "localhost"),
533+
equalTo(SERVER_PORT, serverPort))));
516534
}
517535

518536
@Test
@@ -546,6 +564,8 @@ void testShutdownCommandShouldProduceSpan() {
546564
.hasKind(SpanKind.CLIENT)
547565
.hasAttributesSatisfyingExactly(
548566
equalTo(maybeStable(DB_SYSTEM), "redis"),
549-
equalTo(maybeStable(DB_OPERATION), "SHUTDOWN"))));
567+
equalTo(maybeStable(DB_OPERATION), "SHUTDOWN"),
568+
equalTo(SERVER_ADDRESS, "localhost"),
569+
equalTo(SERVER_PORT, shutdownServerPort))));
550570
}
551571
}

instrumentation/lettuce/lettuce-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceSyncClientTest.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ void testSetCommand() {
168168
.hasKind(SpanKind.CLIENT)
169169
.hasAttributesSatisfyingExactly(
170170
equalTo(maybeStable(DB_SYSTEM), "redis"),
171-
equalTo(maybeStable(DB_OPERATION), "SET"))));
171+
equalTo(maybeStable(DB_OPERATION), "SET"),
172+
equalTo(SERVER_ADDRESS, "localhost"),
173+
equalTo(SERVER_PORT, port))));
172174
}
173175

174176
@Test
@@ -184,7 +186,9 @@ void testGetCommand() {
184186
.hasKind(SpanKind.CLIENT)
185187
.hasAttributesSatisfyingExactly(
186188
equalTo(maybeStable(DB_SYSTEM), "redis"),
187-
equalTo(maybeStable(DB_OPERATION), "GET"))));
189+
equalTo(maybeStable(DB_OPERATION), "GET"),
190+
equalTo(SERVER_ADDRESS, "localhost"),
191+
equalTo(SERVER_PORT, port))));
188192
}
189193

190194
@Test
@@ -200,7 +204,9 @@ void testGetNonExistentKeyCommand() {
200204
.hasKind(SpanKind.CLIENT)
201205
.hasAttributesSatisfyingExactly(
202206
equalTo(maybeStable(DB_SYSTEM), "redis"),
203-
equalTo(maybeStable(DB_OPERATION), "GET"))));
207+
equalTo(maybeStable(DB_OPERATION), "GET"),
208+
equalTo(SERVER_ADDRESS, "localhost"),
209+
equalTo(SERVER_PORT, port))));
204210
}
205211

206212
@Test
@@ -216,7 +222,9 @@ void testCommandWithNoArguments() {
216222
.hasKind(SpanKind.CLIENT)
217223
.hasAttributesSatisfyingExactly(
218224
equalTo(maybeStable(DB_SYSTEM), "redis"),
219-
equalTo(maybeStable(DB_OPERATION), "RANDOMKEY"))));
225+
equalTo(maybeStable(DB_OPERATION), "RANDOMKEY"),
226+
equalTo(SERVER_ADDRESS, "localhost"),
227+
equalTo(SERVER_PORT, port))));
220228
}
221229

222230
@Test
@@ -232,7 +240,9 @@ void testListCommand() {
232240
.hasKind(SpanKind.CLIENT)
233241
.hasAttributesSatisfyingExactly(
234242
equalTo(maybeStable(DB_SYSTEM), "redis"),
235-
equalTo(maybeStable(DB_OPERATION), "LPUSH"))));
243+
equalTo(maybeStable(DB_OPERATION), "LPUSH"),
244+
equalTo(SERVER_ADDRESS, "localhost"),
245+
equalTo(SERVER_PORT, port))));
236246
}
237247

238248
@Test
@@ -248,7 +258,9 @@ void testHashSetCommand() {
248258
.hasKind(SpanKind.CLIENT)
249259
.hasAttributesSatisfyingExactly(
250260
equalTo(maybeStable(DB_SYSTEM), "redis"),
251-
equalTo(maybeStable(DB_OPERATION), "HMSET"))));
261+
equalTo(maybeStable(DB_OPERATION), "HMSET"),
262+
equalTo(SERVER_ADDRESS, "localhost"),
263+
equalTo(SERVER_PORT, port))));
252264
}
253265

254266
@Test
@@ -264,7 +276,9 @@ void testHashGetallCommand() {
264276
.hasKind(SpanKind.CLIENT)
265277
.hasAttributesSatisfyingExactly(
266278
equalTo(maybeStable(DB_SYSTEM), "redis"),
267-
equalTo(maybeStable(DB_OPERATION), "HGETALL"))));
279+
equalTo(maybeStable(DB_OPERATION), "HGETALL"),
280+
equalTo(SERVER_ADDRESS, "localhost"),
281+
equalTo(SERVER_PORT, port))));
268282
}
269283

270284
@Test
@@ -296,7 +310,9 @@ void testDebugSegfaultCommandWithNoArgumentShouldProduceSpan() {
296310
.hasKind(SpanKind.CLIENT)
297311
.hasAttributesSatisfyingExactly(
298312
equalTo(maybeStable(DB_SYSTEM), "redis"),
299-
equalTo(maybeStable(DB_OPERATION), "DEBUG"))));
313+
equalTo(maybeStable(DB_OPERATION), "DEBUG"),
314+
equalTo(SERVER_ADDRESS, "localhost"),
315+
equalTo(SERVER_PORT, serverPort))));
300316
}
301317

302318
@Test
@@ -330,6 +346,8 @@ void testShutdownCommandShouldProduceSpan() {
330346
.hasKind(SpanKind.CLIENT)
331347
.hasAttributesSatisfyingExactly(
332348
equalTo(maybeStable(DB_SYSTEM), "redis"),
333-
equalTo(maybeStable(DB_OPERATION), "SHUTDOWN"))));
349+
equalTo(maybeStable(DB_OPERATION), "SHUTDOWN"),
350+
equalTo(SERVER_ADDRESS, "localhost"),
351+
equalTo(SERVER_PORT, shutdownServerPort))));
334352
}
335353
}

instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/EndConnectAsyncBiFunction.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
package io.opentelemetry.javaagent.instrumentation.lettuce.v5_0;
77

8+
import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.LettuceSingletons.CONNECTION_URI;
89
import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.LettuceSingletons.connectInstrumenter;
910

1011
import io.lettuce.core.RedisURI;
12+
import io.lettuce.core.api.StatefulConnection;
1113
import io.opentelemetry.api.trace.Span;
1214
import io.opentelemetry.context.Context;
1315
import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig;
@@ -40,6 +42,10 @@ public EndConnectAsyncBiFunction(Context context, RedisURI redisUri) {
4042

4143
@Override
4244
public R apply(T t, Throwable throwable) {
45+
if (t instanceof StatefulConnection) {
46+
CONNECTION_URI.set((StatefulConnection<?, ?>) t, redisUri);
47+
}
48+
4349
if (throwable instanceof CancellationException) {
4450
if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
4551
Span.fromContext(context).setAttribute("lettuce.command.cancelled", true);

0 commit comments

Comments
 (0)