diff --git a/src/main/java/io/lettuce/core/protocol/CommandHandler.java b/src/main/java/io/lettuce/core/protocol/CommandHandler.java index b5999fa8fb..31f68d3443 100644 --- a/src/main/java/io/lettuce/core/protocol/CommandHandler.java +++ b/src/main/java/io/lettuce/core/protocol/CommandHandler.java @@ -78,6 +78,7 @@ public class CommandHandler extends ChannelDuplexHandler implements HasQueuedCom private final boolean debugEnabled = logger.isDebugEnabled(); private final boolean latencyMetricsEnabled; private final boolean tracingEnabled; + private final boolean includeCommandArgsInSpanTags; private final boolean boundedQueues; private final BackpressureSource backpressureSource = new BackpressureSource(); @@ -111,6 +112,7 @@ public CommandHandler(ClientOptions clientOptions, ClientResources clientResourc Tracing tracing = clientResources.tracing(); this.tracingEnabled = tracing.isEnabled(); + this.includeCommandArgsInSpanTags = tracing.includeCommandArgsInSpanTags(); } public Queue> getStack() { @@ -385,7 +387,7 @@ private void writeSingleCommand(ChannelHandlerContext ctx, RedisCommand Tracer.Span span = tracer.nextSpan(context); span.name(command.getType().name()); - if (command.getArgs() != null) { + if (includeCommandArgsInSpanTags && command.getArgs() != null) { span.tag("redis.args", command.getArgs().toCommandString()); } diff --git a/src/main/java/io/lettuce/core/tracing/BraveTracing.java b/src/main/java/io/lettuce/core/tracing/BraveTracing.java index d479055c6e..266ec3971d 100644 --- a/src/main/java/io/lettuce/core/tracing/BraveTracing.java +++ b/src/main/java/io/lettuce/core/tracing/BraveTracing.java @@ -55,6 +55,7 @@ public class BraveTracing implements Tracing { private final BraveTracer tracer; private final BraveTracingOptions tracingOptions; + private final boolean includeCommandArgsInSpanTags; /** * Create a new {@link BraveTracing} instance. @@ -68,6 +69,7 @@ private BraveTracing(Builder builder) { this.tracingOptions = new BraveTracingOptions(builder.serviceName, builder.endpointCustomizer, builder.spanCustomizer); this.tracer = new BraveTracer(builder.tracing, this.tracingOptions); + this.includeCommandArgsInSpanTags = builder.includeCommandArgsInSpanTags; } /** @@ -103,6 +105,7 @@ public static class Builder { }; private Consumer spanCustomizer = it -> { }; + private boolean includeCommandArgsInSpanTags = true; private Builder() { } @@ -135,6 +138,19 @@ public Builder serviceName(String serviceName) { return this; } + /** + * Controls the inclusion of command arguments in {@link Span} tags. + * This is enabled by default. + * + * @param includeCommandArgsInSpanTags the flag to enable or disable the inclusion of command args in {@link Span} tags. + * @return {@code this} {@link Builder}. + */ + public Builder includeCommandArgsInSpanTags(boolean includeCommandArgsInSpanTags) { + + this.includeCommandArgsInSpanTags = includeCommandArgsInSpanTags; + return this; + } + /** * Sets an {@link zipkin2.Endpoint} customizer to customize the {@link zipkin2.Endpoint} through its * {@link zipkin2.Endpoint.Builder}. The customizer is invoked before {@link zipkin2.Endpoint.Builder#build() building} @@ -182,6 +198,11 @@ public boolean isEnabled() { return true; } + @Override + public boolean includeCommandArgsInSpanTags() { + return includeCommandArgsInSpanTags; + } + @Override public TracerProvider getTracerProvider() { return () -> tracer; diff --git a/src/main/java/io/lettuce/core/tracing/NoOpTracing.java b/src/main/java/io/lettuce/core/tracing/NoOpTracing.java index dc671b1bb2..b8bbc95d64 100644 --- a/src/main/java/io/lettuce/core/tracing/NoOpTracing.java +++ b/src/main/java/io/lettuce/core/tracing/NoOpTracing.java @@ -55,6 +55,11 @@ public boolean isEnabled() { return false; } + @Override + public boolean includeCommandArgsInSpanTags() { + return false; + } + @Override public Endpoint createEndpoint(SocketAddress socketAddress) { return NOOP_ENDPOINT; diff --git a/src/main/java/io/lettuce/core/tracing/Tracing.java b/src/main/java/io/lettuce/core/tracing/Tracing.java index 5ba662ea99..93e1cd8042 100644 --- a/src/main/java/io/lettuce/core/tracing/Tracing.java +++ b/src/main/java/io/lettuce/core/tracing/Tracing.java @@ -49,6 +49,11 @@ public interface Tracing { */ boolean isEnabled(); + /** + * @return {@literal true} if tags for {@link Tracer.Span}s should include the command arguments. + */ + boolean includeCommandArgsInSpanTags(); + /** * Create an {@link Endpoint} given {@link SocketAddress}. * diff --git a/src/test/java/io/lettuce/core/tracing/BraveTracingIntegrationTests.java b/src/test/java/io/lettuce/core/tracing/BraveTracingIntegrationTests.java index ed2fc7ae98..69594a441b 100644 --- a/src/test/java/io/lettuce/core/tracing/BraveTracingIntegrationTests.java +++ b/src/test/java/io/lettuce/core/tracing/BraveTracingIntegrationTests.java @@ -173,7 +173,43 @@ void reactiveGetAndSetWithTrace() { List spans = new ArrayList<>(BraveTracingIntegrationTests.spans); assertThat(spans.get(0).name()).isEqualTo("set"); + assertThat(spans.get(0).tags()).containsEntry("redis.args", "key value"); assertThat(spans.get(1).name()).isEqualTo("get"); + assertThat(spans.get(1).tags()).containsEntry("redis.args", "key"); + assertThat(spans.get(2).name()).isEqualTo("foo"); + } + + @Test + void reactiveGetAndSetWithTraceWithCommandArgsExcludedFromTags() { + + DefaultClientResources clientResources = DefaultClientResources.builder() + .tracing(BraveTracing.builder() + .tracing(clientTracing) + .includeCommandArgsInSpanTags(false) + .build() + ) + .build(); + RedisClient client = RedisClient.create(clientResources, RedisURI.Builder.redis(host, port).build()); + + ScopedSpan trace = clientTracing.tracer().startScopedSpan("foo"); + + StatefulRedisConnection connect = client.connect(); + connect.reactive().set("foo", "bar") // + .then(connect.reactive().get("foo")) // + .subscriberContext(it -> it.put(TraceContext.class, trace.context())) // + .as(StepVerifier::create) // + .expectNext("bar").verifyComplete(); + + Wait.untilEquals(2, spans::size).waitOrTimeout(); + + trace.finish(); + + List spans = new ArrayList<>(BraveTracingIntegrationTests.spans); + + assertThat(spans.get(0).name()).isEqualTo("set"); + assertThat(spans.get(0).tags()).doesNotContainKey("redis.args"); + assertThat(spans.get(1).name()).isEqualTo("get"); + assertThat(spans.get(1).tags()).doesNotContainKey("redis.args"); assertThat(spans.get(2).name()).isEqualTo("foo"); }