From 13adf93bd9fd8c8d21633e4482720394d890d5ca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:31:28 +0000 Subject: [PATCH 1/7] Initial plan From 540ac84a627b91657f7007b36fb3fd82ae86ef4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 17:03:25 +0000 Subject: [PATCH 2/7] Add shouldStart checks to lettuce instrumentation span creation Co-authored-by: trask <218610+trask@users.noreply.github.com> --- .../lettuce/v5_1/LettuceTelemetry.java | 9 +- .../lettuce/v5_1/OpenTelemetryTracing.java | 45 +++++-- .../lettuce/v5_1/LettuceShouldStartTest.java | 113 ++++++++++++++++++ 3 files changed, 158 insertions(+), 9 deletions(-) create mode 100644 instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java index 3dbf0234ea53..c49d7da21b95 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java @@ -10,7 +10,9 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.TracerBuilder; import io.opentelemetry.instrumentation.api.incubator.semconv.db.RedisCommandSanitizer; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.OperationListener; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; /** Entrypoint for instrumenting Lettuce or clients. */ @@ -33,6 +35,7 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { private final Tracer tracer; private final RedisCommandSanitizer sanitizer; private final OperationListener metrics; + private final Instrumenter instrumenter; LettuceTelemetry( OpenTelemetry openTelemetry, @@ -46,6 +49,10 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { } tracer = tracerBuilder.build(); sanitizer = RedisCommandSanitizer.create(statementSanitizationEnabled); + + // Create instrumenter for shouldStart checks + instrumenter = Instrumenter.builder(openTelemetry, INSTRUMENTATION_NAME, req -> "redis") + .buildInstrumenter(SpanKindExtractor.alwaysInternal()); } /** @@ -53,6 +60,6 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { * io.lettuce.core.resource.ClientResources.Builder#tracing(Tracing)}. */ public Tracing newTracing() { - return new OpenTelemetryTracing(tracer, sanitizer, metrics); + return new OpenTelemetryTracing(tracer, sanitizer, metrics, instrumenter); } } diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java index 58a67d6dc041..7fd4f7822be2 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java @@ -29,6 +29,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.incubator.semconv.db.RedisCommandSanitizer; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.OperationListener; import io.opentelemetry.instrumentation.api.internal.SemconvStability; import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesExtractor; @@ -54,13 +55,20 @@ final class OpenTelemetryTracing implements Tracing { ServerAttributesExtractor.create(new LettuceServerAttributesGetter()); private static final AttributesExtractor networkAttributesExtractor = NetworkAttributesExtractor.create(new LettuceServerAttributesGetter()); + + // Simple request object for shouldStart checks when we don't have full RedisCommand details + private static final Object REDIS_OPERATION_REQUEST = new Object(); + private final TracerProvider tracerProvider; + private final Instrumenter instrumenter; OpenTelemetryTracing( io.opentelemetry.api.trace.Tracer tracer, RedisCommandSanitizer sanitizer, - OperationListener metrics) { - this.tracerProvider = new OpenTelemetryTracerProvider(tracer, sanitizer, metrics); + OperationListener metrics, + Instrumenter instrumenter) { + this.tracerProvider = new OpenTelemetryTracerProvider(tracer, sanitizer, metrics, instrumenter); + this.instrumenter = instrumenter; } @Override @@ -100,8 +108,9 @@ private static class OpenTelemetryTracerProvider implements TracerProvider { OpenTelemetryTracerProvider( io.opentelemetry.api.trace.Tracer tracer, RedisCommandSanitizer sanitizer, - OperationListener metrics) { - openTelemetryTracer = new OpenTelemetryTracer(tracer, sanitizer, metrics); + OperationListener metrics, + Instrumenter instrumenter) { + openTelemetryTracer = new OpenTelemetryTracer(tracer, sanitizer, metrics, instrumenter); } @Override @@ -143,14 +152,17 @@ private static class OpenTelemetryTracer extends Tracer { private final io.opentelemetry.api.trace.Tracer tracer; private final RedisCommandSanitizer sanitizer; private final OperationListener metrics; + private final Instrumenter instrumenter; OpenTelemetryTracer( io.opentelemetry.api.trace.Tracer tracer, RedisCommandSanitizer sanitizer, - OperationListener metrics) { + OperationListener metrics, + Instrumenter instrumenter) { this.tracer = tracer; this.sanitizer = sanitizer; this.metrics = metrics; + this.instrumenter = instrumenter; } @Override @@ -179,7 +191,7 @@ private OpenTelemetrySpan nextSpan(Context context) { if (SemconvStability.emitOldDatabaseSemconv()) { spanBuilder.setAttribute(DB_SYSTEM, REDIS); } - return new OpenTelemetrySpan(context, spanBuilder, sanitizer, metrics); + return new OpenTelemetrySpan(context, spanBuilder, sanitizer, metrics, instrumenter); } } @@ -193,6 +205,7 @@ private static class OpenTelemetrySpan extends Tracer.Span { private final SpanBuilder spanBuilder; private final RedisCommandSanitizer sanitizer; private final OperationListener metrics; + private final Instrumenter instrumenter; @Nullable private String name; @Nullable private List events; @@ -207,11 +220,13 @@ private static class OpenTelemetrySpan extends Tracer.Span { Context context, SpanBuilder spanBuilder, RedisCommandSanitizer sanitizer, - OperationListener metrics) { + OperationListener metrics, + Instrumenter instrumenter) { this.context = context; this.spanBuilder = spanBuilder; this.sanitizer = sanitizer; this.metrics = metrics; + this.instrumenter = instrumenter; this.attributesBuilder = Attributes.builder(); if (SemconvStability.emitStableDatabaseSemconv()) { attributesBuilder.put(DB_SYSTEM_NAME, REDIS); @@ -261,7 +276,12 @@ private void fillEndpoint(OpenTelemetryEndpoint endpoint) { @CanIgnoreReturnValue @SuppressWarnings({"UnusedMethod", "EffectivelyPrivate"}) public synchronized Tracer.Span start(RedisCommand command) { - start(); + // Check if instrumentation should start for this command + if (!instrumenter.shouldStart(context, (Object) command)) { + return this; + } + + startSpanInternal(); long startNanos = System.nanoTime(); Span span = this.span; @@ -301,6 +321,15 @@ public synchronized Tracer.Span start(RedisCommand command) { @Override @CanIgnoreReturnValue public synchronized Tracer.Span start() { + // Check if instrumentation should start for generic redis operation + if (!instrumenter.shouldStart(context, REDIS_OPERATION_REQUEST)) { + return this; + } + + return startSpanInternal(); + } + + private synchronized Tracer.Span startSpanInternal() { span = spanBuilder.startSpan(); spanStartNanos = System.nanoTime(); if (name != null) { diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java b/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java new file mode 100644 index 000000000000..59495b203ad6 --- /dev/null +++ b/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java @@ -0,0 +1,113 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.lettuce.v5_1; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.lettuce.core.RedisClient; +import io.lettuce.core.api.sync.RedisCommands; +import io.lettuce.core.resource.ClientResources; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +class LettuceShouldStartTest { + @RegisterExtension + static final InstrumentationExtension testing = LibraryInstrumentationExtension.create(); + + @Container + static final GenericContainer redisServer = + new GenericContainer<>("redis:6.2.7-alpine").withExposedPorts(6379); + + static RedisClient redisClient; + static String redisUri; + + @BeforeAll + static void setUp() { + redisUri = "redis://" + redisServer.getHost() + ":" + redisServer.getFirstMappedPort() + "/0"; + } + + @AfterAll + static void cleanUp() { + if (redisClient != null) { + redisClient.shutdown(); + } + } + + @Test + void shouldNotCreateSpansWhenInstrumentationDisabled() { + // Create OpenTelemetry instance with instrumentation disabled + InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) + .build(); + + OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() + .setTracerProvider(tracerProvider) + .build(); + + // Create LettuceTelemetry with disabled instrumenter (this is a simplified test) + // In a real scenario, instrumentation would be disabled via configuration + LettuceTelemetry lettuceTelemetry = LettuceTelemetry.builder(openTelemetry) + .build(); + + redisClient = RedisClient.create( + ClientResources.builder() + .tracing(lettuceTelemetry.newTracing()) + .build(), + redisUri); + + RedisCommands sync = redisClient.connect().sync(); + + // Perform a Redis operation + sync.set("test-key", "test-value"); + String value = sync.get("test-key"); + + assertThat(value).isEqualTo("test-value"); + + // For this basic test, we just verify that operations work + // A more sophisticated test would involve actually disabling the instrumenter + // via configuration and verifying no spans are created + } + + @Test + void shouldCreateSpansWhenInstrumentationEnabled() { + LettuceTelemetry lettuceTelemetry = LettuceTelemetry.create(testing.getOpenTelemetry()); + + redisClient = RedisClient.create( + ClientResources.builder() + .tracing(lettuceTelemetry.newTracing()) + .build(), + redisUri); + + RedisCommands sync = redisClient.connect().sync(); + + // Clear any existing spans + testing.clearData(); + + // Perform a Redis operation + sync.set("test-key-2", "test-value-2"); + + // Verify spans were created + testing.waitAndAssertTraces( + trace -> trace.hasSpansSatisfyingExactly( + span -> span.hasName("SET").hasKind(SpanKind.CLIENT))); + } +} \ No newline at end of file From 60ac4bfd99b1d27cb992812eca6aa92444767400 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 17:07:48 +0000 Subject: [PATCH 3/7] Add instrumentationEnabled configuration option and improve shouldStart implementation Co-authored-by: trask <218610+trask@users.noreply.github.com> --- .../lettuce/v5_1/LettuceTelemetry.java | 7 +++++-- .../lettuce/v5_1/LettuceTelemetryBuilder.java | 12 ++++++++++++ .../lettuce/v5_1/LettuceShouldStartTest.java | 11 +++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java index c49d7da21b95..2ef67db7c160 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java @@ -40,6 +40,7 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { LettuceTelemetry( OpenTelemetry openTelemetry, boolean statementSanitizationEnabled, + boolean instrumentationEnabled, OperationListener metrics) { this.metrics = metrics; TracerBuilder tracerBuilder = openTelemetry.tracerBuilder(INSTRUMENTATION_NAME); @@ -50,9 +51,11 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { tracer = tracerBuilder.build(); sanitizer = RedisCommandSanitizer.create(statementSanitizationEnabled); - // Create instrumenter for shouldStart checks + // Create minimal instrumenter only for shouldStart checks + // The actual span creation is handled by the existing SpanBuilder mechanism instrumenter = Instrumenter.builder(openTelemetry, INSTRUMENTATION_NAME, req -> "redis") - .buildInstrumenter(SpanKindExtractor.alwaysInternal()); + .setEnabled(instrumentationEnabled) + .buildInstrumenter(); } /** diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java index d44ab73e0586..6d7eeec4d478 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java @@ -17,6 +17,7 @@ public final class LettuceTelemetryBuilder { private final OpenTelemetry openTelemetry; private boolean statementSanitizationEnabled = true; + private boolean instrumentationEnabled = true; LettuceTelemetryBuilder(OpenTelemetry openTelemetry) { this.openTelemetry = openTelemetry; @@ -34,6 +35,16 @@ public LettuceTelemetryBuilder setStatementSanitizationEnabled( return this; } + /** + * Sets whether instrumentation should be enabled. If set to {@code false}, no spans will be + * created by the constructed {@link LettuceTelemetry}. Enabled by default. + */ + @CanIgnoreReturnValue + public LettuceTelemetryBuilder setInstrumentationEnabled(boolean instrumentationEnabled) { + this.instrumentationEnabled = instrumentationEnabled; + return this; + } + /** * Returns a new {@link LettuceTelemetry} with the settings of this {@link * LettuceTelemetryBuilder}. @@ -42,6 +53,7 @@ public LettuceTelemetry build() { return new LettuceTelemetry( openTelemetry, statementSanitizationEnabled, + instrumentationEnabled, DbClientMetrics.get().create(openTelemetry.getMeterProvider().get(INSTRUMENTATION_NAME))); } } diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java b/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java index 59495b203ad6..fbc7dc071979 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java @@ -52,7 +52,7 @@ static void cleanUp() { @Test void shouldNotCreateSpansWhenInstrumentationDisabled() { - // Create OpenTelemetry instance with instrumentation disabled + // Create OpenTelemetry instance InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); SdkTracerProvider tracerProvider = SdkTracerProvider.builder() @@ -63,9 +63,9 @@ void shouldNotCreateSpansWhenInstrumentationDisabled() { .setTracerProvider(tracerProvider) .build(); - // Create LettuceTelemetry with disabled instrumenter (this is a simplified test) - // In a real scenario, instrumentation would be disabled via configuration + // Create LettuceTelemetry with instrumentation disabled LettuceTelemetry lettuceTelemetry = LettuceTelemetry.builder(openTelemetry) + .setInstrumentationEnabled(false) .build(); redisClient = RedisClient.create( @@ -82,9 +82,8 @@ void shouldNotCreateSpansWhenInstrumentationDisabled() { assertThat(value).isEqualTo("test-value"); - // For this basic test, we just verify that operations work - // A more sophisticated test would involve actually disabling the instrumenter - // via configuration and verifying no spans are created + // Verify no spans were created due to disabled instrumentation + assertThat(spanExporter.getFinishedSpanItems()).isEmpty(); } @Test From 61598910fe246504c26febb6236538df0cd3563e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 17:30:33 +0000 Subject: [PATCH 4/7] Fix shouldStart pattern in lettuce-4.0 and lettuce-5.0 javaagent instrumentations Co-authored-by: trask <218610+trask@users.noreply.github.com> --- .../v4_0/LettuceAsyncCommandsInstrumentation.java | 8 +++++++- .../lettuce/v4_0/LettuceConnectInstrumentation.java | 11 +++++++++-- .../v5_0/LettuceAsyncCommandsInstrumentation.java | 8 +++++++- .../lettuce/v5_0/LettuceClientInstrumentation.java | 11 +++++++++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java index a16468a35cd5..a4a3d8c4e7b4 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java @@ -63,6 +63,10 @@ public void end( public static AdviceScope onEnter(@Advice.Argument(0) RedisCommand command) { Context parentContext = currentContext(); + if (!instrumenter().shouldStart(parentContext, command)) { + return null; + } + Context context = instrumenter().start(parentContext, command); // remember the context that called dispatch, it is used in LettuceAsyncCommandInstrumentation context = context.with(LettuceSingletons.COMMAND_CONTEXT_KEY, parentContext); @@ -75,7 +79,9 @@ public static void onExit( @Advice.Thrown Throwable throwable, @Advice.Return AsyncCommand asyncCommand, @Advice.Enter AdviceScope adviceScope) { - adviceScope.end(throwable, command, asyncCommand); + if (adviceScope != null) { + adviceScope.end(throwable, command, asyncCommand); + } } } } diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java index aa1d094f946d..d6430b51c152 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java @@ -54,7 +54,12 @@ public void end(Throwable throwable, RedisURI redisUri) { @Advice.OnMethodEnter(suppress = Throwable.class) public static AdviceScope onEnter(@Advice.Argument(1) RedisURI redisUri) { - Context context = connectInstrumenter().start(currentContext(), redisUri); + Context parentContext = currentContext(); + if (!connectInstrumenter().shouldStart(parentContext, redisUri)) { + return null; + } + + Context context = connectInstrumenter().start(parentContext, redisUri); return new AdviceScope(context, context.makeCurrent()); } @@ -63,7 +68,9 @@ public static void onExit( @Advice.Argument(1) RedisURI redisUri, @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter AdviceScope adviceScope) { - adviceScope.end(throwable, redisUri); + if (adviceScope != null) { + adviceScope.end(throwable, redisUri); + } } } } diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java index 3b395f5f89ee..bc78ff87a24b 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java @@ -75,6 +75,10 @@ public void end( public static AdviceScope onEnter(@Advice.Argument(0) RedisCommand command) { Context parentContext = currentContext(); + if (!instrumenter().shouldStart(parentContext, command)) { + return null; + } + Context context = instrumenter().start(parentContext, command); // remember the context that called dispatch, it is used in LettuceAsyncCommandInstrumentation context = context.with(LettuceSingletons.COMMAND_CONTEXT_KEY, parentContext); @@ -88,7 +92,9 @@ public static void stopSpan( @Advice.Return AsyncCommand asyncCommand, @Advice.Enter AdviceScope adviceScope) { - adviceScope.end(throwable, command, asyncCommand); + if (adviceScope != null) { + adviceScope.end(throwable, command, asyncCommand); + } } } } diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java index c8d697023f22..89655468da19 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java @@ -72,7 +72,12 @@ public void end( @Advice.OnMethodEnter(suppress = Throwable.class) public static AdviceScope onEnter(@Advice.Argument(1) RedisURI redisUri) { - Context context = connectInstrumenter().start(currentContext(), redisUri); + Context parentContext = currentContext(); + if (!connectInstrumenter().shouldStart(parentContext, redisUri)) { + return null; + } + + Context context = connectInstrumenter().start(parentContext, redisUri); return new AdviceScope(context, context.makeCurrent()); } @@ -82,7 +87,9 @@ public static void stopSpan( @Advice.Thrown @Nullable Throwable throwable, @Advice.Return ConnectionFuture connectionFuture, @Advice.Enter AdviceScope adviceScope) { - adviceScope.end(throwable, redisUri, connectionFuture); + if (adviceScope != null) { + adviceScope.end(throwable, redisUri, connectionFuture); + } } } } From d95c3acee68ed2a7e387d217d3bfa052aa448a01 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 17:48:19 +0000 Subject: [PATCH 5/7] Revert lettuce-5.1 changes as requested Co-authored-by: trask <218610+trask@users.noreply.github.com> --- .../lettuce/v5_1/LettuceTelemetry.java | 12 +- .../lettuce/v5_1/LettuceTelemetryBuilder.java | 12 -- .../lettuce/v5_1/OpenTelemetryTracing.java | 45 ++----- .../lettuce/v5_1/LettuceShouldStartTest.java | 112 ------------------ 4 files changed, 9 insertions(+), 172 deletions(-) delete mode 100644 instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java index 2ef67db7c160..3dbf0234ea53 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetry.java @@ -10,9 +10,7 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.TracerBuilder; import io.opentelemetry.instrumentation.api.incubator.semconv.db.RedisCommandSanitizer; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.OperationListener; -import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; /** Entrypoint for instrumenting Lettuce or clients. */ @@ -35,12 +33,10 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { private final Tracer tracer; private final RedisCommandSanitizer sanitizer; private final OperationListener metrics; - private final Instrumenter instrumenter; LettuceTelemetry( OpenTelemetry openTelemetry, boolean statementSanitizationEnabled, - boolean instrumentationEnabled, OperationListener metrics) { this.metrics = metrics; TracerBuilder tracerBuilder = openTelemetry.tracerBuilder(INSTRUMENTATION_NAME); @@ -50,12 +46,6 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { } tracer = tracerBuilder.build(); sanitizer = RedisCommandSanitizer.create(statementSanitizationEnabled); - - // Create minimal instrumenter only for shouldStart checks - // The actual span creation is handled by the existing SpanBuilder mechanism - instrumenter = Instrumenter.builder(openTelemetry, INSTRUMENTATION_NAME, req -> "redis") - .setEnabled(instrumentationEnabled) - .buildInstrumenter(); } /** @@ -63,6 +53,6 @@ public static LettuceTelemetryBuilder builder(OpenTelemetry openTelemetry) { * io.lettuce.core.resource.ClientResources.Builder#tracing(Tracing)}. */ public Tracing newTracing() { - return new OpenTelemetryTracing(tracer, sanitizer, metrics, instrumenter); + return new OpenTelemetryTracing(tracer, sanitizer, metrics); } } diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java index 6d7eeec4d478..d44ab73e0586 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceTelemetryBuilder.java @@ -17,7 +17,6 @@ public final class LettuceTelemetryBuilder { private final OpenTelemetry openTelemetry; private boolean statementSanitizationEnabled = true; - private boolean instrumentationEnabled = true; LettuceTelemetryBuilder(OpenTelemetry openTelemetry) { this.openTelemetry = openTelemetry; @@ -35,16 +34,6 @@ public LettuceTelemetryBuilder setStatementSanitizationEnabled( return this; } - /** - * Sets whether instrumentation should be enabled. If set to {@code false}, no spans will be - * created by the constructed {@link LettuceTelemetry}. Enabled by default. - */ - @CanIgnoreReturnValue - public LettuceTelemetryBuilder setInstrumentationEnabled(boolean instrumentationEnabled) { - this.instrumentationEnabled = instrumentationEnabled; - return this; - } - /** * Returns a new {@link LettuceTelemetry} with the settings of this {@link * LettuceTelemetryBuilder}. @@ -53,7 +42,6 @@ public LettuceTelemetry build() { return new LettuceTelemetry( openTelemetry, statementSanitizationEnabled, - instrumentationEnabled, DbClientMetrics.get().create(openTelemetry.getMeterProvider().get(INSTRUMENTATION_NAME))); } } diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java index 7fd4f7822be2..58a67d6dc041 100644 --- a/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java +++ b/instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java @@ -29,7 +29,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.incubator.semconv.db.RedisCommandSanitizer; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.OperationListener; import io.opentelemetry.instrumentation.api.internal.SemconvStability; import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesExtractor; @@ -55,20 +54,13 @@ final class OpenTelemetryTracing implements Tracing { ServerAttributesExtractor.create(new LettuceServerAttributesGetter()); private static final AttributesExtractor networkAttributesExtractor = NetworkAttributesExtractor.create(new LettuceServerAttributesGetter()); - - // Simple request object for shouldStart checks when we don't have full RedisCommand details - private static final Object REDIS_OPERATION_REQUEST = new Object(); - private final TracerProvider tracerProvider; - private final Instrumenter instrumenter; OpenTelemetryTracing( io.opentelemetry.api.trace.Tracer tracer, RedisCommandSanitizer sanitizer, - OperationListener metrics, - Instrumenter instrumenter) { - this.tracerProvider = new OpenTelemetryTracerProvider(tracer, sanitizer, metrics, instrumenter); - this.instrumenter = instrumenter; + OperationListener metrics) { + this.tracerProvider = new OpenTelemetryTracerProvider(tracer, sanitizer, metrics); } @Override @@ -108,9 +100,8 @@ private static class OpenTelemetryTracerProvider implements TracerProvider { OpenTelemetryTracerProvider( io.opentelemetry.api.trace.Tracer tracer, RedisCommandSanitizer sanitizer, - OperationListener metrics, - Instrumenter instrumenter) { - openTelemetryTracer = new OpenTelemetryTracer(tracer, sanitizer, metrics, instrumenter); + OperationListener metrics) { + openTelemetryTracer = new OpenTelemetryTracer(tracer, sanitizer, metrics); } @Override @@ -152,17 +143,14 @@ private static class OpenTelemetryTracer extends Tracer { private final io.opentelemetry.api.trace.Tracer tracer; private final RedisCommandSanitizer sanitizer; private final OperationListener metrics; - private final Instrumenter instrumenter; OpenTelemetryTracer( io.opentelemetry.api.trace.Tracer tracer, RedisCommandSanitizer sanitizer, - OperationListener metrics, - Instrumenter instrumenter) { + OperationListener metrics) { this.tracer = tracer; this.sanitizer = sanitizer; this.metrics = metrics; - this.instrumenter = instrumenter; } @Override @@ -191,7 +179,7 @@ private OpenTelemetrySpan nextSpan(Context context) { if (SemconvStability.emitOldDatabaseSemconv()) { spanBuilder.setAttribute(DB_SYSTEM, REDIS); } - return new OpenTelemetrySpan(context, spanBuilder, sanitizer, metrics, instrumenter); + return new OpenTelemetrySpan(context, spanBuilder, sanitizer, metrics); } } @@ -205,7 +193,6 @@ private static class OpenTelemetrySpan extends Tracer.Span { private final SpanBuilder spanBuilder; private final RedisCommandSanitizer sanitizer; private final OperationListener metrics; - private final Instrumenter instrumenter; @Nullable private String name; @Nullable private List events; @@ -220,13 +207,11 @@ private static class OpenTelemetrySpan extends Tracer.Span { Context context, SpanBuilder spanBuilder, RedisCommandSanitizer sanitizer, - OperationListener metrics, - Instrumenter instrumenter) { + OperationListener metrics) { this.context = context; this.spanBuilder = spanBuilder; this.sanitizer = sanitizer; this.metrics = metrics; - this.instrumenter = instrumenter; this.attributesBuilder = Attributes.builder(); if (SemconvStability.emitStableDatabaseSemconv()) { attributesBuilder.put(DB_SYSTEM_NAME, REDIS); @@ -276,12 +261,7 @@ private void fillEndpoint(OpenTelemetryEndpoint endpoint) { @CanIgnoreReturnValue @SuppressWarnings({"UnusedMethod", "EffectivelyPrivate"}) public synchronized Tracer.Span start(RedisCommand command) { - // Check if instrumentation should start for this command - if (!instrumenter.shouldStart(context, (Object) command)) { - return this; - } - - startSpanInternal(); + start(); long startNanos = System.nanoTime(); Span span = this.span; @@ -321,15 +301,6 @@ public synchronized Tracer.Span start(RedisCommand command) { @Override @CanIgnoreReturnValue public synchronized Tracer.Span start() { - // Check if instrumentation should start for generic redis operation - if (!instrumenter.shouldStart(context, REDIS_OPERATION_REQUEST)) { - return this; - } - - return startSpanInternal(); - } - - private synchronized Tracer.Span startSpanInternal() { span = spanBuilder.startSpan(); spanStartNanos = System.nanoTime(); if (name != null) { diff --git a/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java b/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java deleted file mode 100644 index fbc7dc071979..000000000000 --- a/instrumentation/lettuce/lettuce-5.1/library/src/test/java/io/opentelemetry/instrumentation/lettuce/v5_1/LettuceShouldStartTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.lettuce.v5_1; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.api.sync.RedisCommands; -import io.lettuce.core.resource.ClientResources; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers -class LettuceShouldStartTest { - @RegisterExtension - static final InstrumentationExtension testing = LibraryInstrumentationExtension.create(); - - @Container - static final GenericContainer redisServer = - new GenericContainer<>("redis:6.2.7-alpine").withExposedPorts(6379); - - static RedisClient redisClient; - static String redisUri; - - @BeforeAll - static void setUp() { - redisUri = "redis://" + redisServer.getHost() + ":" + redisServer.getFirstMappedPort() + "/0"; - } - - @AfterAll - static void cleanUp() { - if (redisClient != null) { - redisClient.shutdown(); - } - } - - @Test - void shouldNotCreateSpansWhenInstrumentationDisabled() { - // Create OpenTelemetry instance - InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); - SdkTracerProvider tracerProvider = - SdkTracerProvider.builder() - .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) - .build(); - - OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setTracerProvider(tracerProvider) - .build(); - - // Create LettuceTelemetry with instrumentation disabled - LettuceTelemetry lettuceTelemetry = LettuceTelemetry.builder(openTelemetry) - .setInstrumentationEnabled(false) - .build(); - - redisClient = RedisClient.create( - ClientResources.builder() - .tracing(lettuceTelemetry.newTracing()) - .build(), - redisUri); - - RedisCommands sync = redisClient.connect().sync(); - - // Perform a Redis operation - sync.set("test-key", "test-value"); - String value = sync.get("test-key"); - - assertThat(value).isEqualTo("test-value"); - - // Verify no spans were created due to disabled instrumentation - assertThat(spanExporter.getFinishedSpanItems()).isEmpty(); - } - - @Test - void shouldCreateSpansWhenInstrumentationEnabled() { - LettuceTelemetry lettuceTelemetry = LettuceTelemetry.create(testing.getOpenTelemetry()); - - redisClient = RedisClient.create( - ClientResources.builder() - .tracing(lettuceTelemetry.newTracing()) - .build(), - redisUri); - - RedisCommands sync = redisClient.connect().sync(); - - // Clear any existing spans - testing.clearData(); - - // Perform a Redis operation - sync.set("test-key-2", "test-value-2"); - - // Verify spans were created - testing.waitAndAssertTraces( - trace -> trace.hasSpansSatisfyingExactly( - span -> span.hasName("SET").hasKind(SpanKind.CLIENT))); - } -} \ No newline at end of file From d308b2b84485916af076b679ae2fea574c8096d0 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 17 Sep 2025 07:10:24 -0700 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> --- .../lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java | 6 +++--- .../lettuce/v4_0/LettuceConnectInstrumentation.java | 2 +- .../lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java | 4 ++-- .../lettuce/v5_0/LettuceClientInstrumentation.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java index a4a3d8c4e7b4..37d9850d2a57 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsInstrumentation.java @@ -76,9 +76,9 @@ public static AdviceScope onEnter(@Advice.Argument(0) RedisCommand comm @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( @Advice.Argument(0) RedisCommand command, - @Advice.Thrown Throwable throwable, - @Advice.Return AsyncCommand asyncCommand, - @Advice.Enter AdviceScope adviceScope) { + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Return @Nullable AsyncCommand asyncCommand, + @Advice.Enter @Nullable AdviceScope adviceScope) { if (adviceScope != null) { adviceScope.end(throwable, command, asyncCommand); } diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java index d6430b51c152..ba427ebc1f4d 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java @@ -67,7 +67,7 @@ public static AdviceScope onEnter(@Advice.Argument(1) RedisURI redisUri) { public static void onExit( @Advice.Argument(1) RedisURI redisUri, @Advice.Thrown @Nullable Throwable throwable, - @Advice.Enter AdviceScope adviceScope) { + @Advice.Enter @Nullable AdviceScope adviceScope) { if (adviceScope != null) { adviceScope.end(throwable, redisUri); } diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java index bc78ff87a24b..9c1f62655a4d 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceAsyncCommandsInstrumentation.java @@ -89,8 +89,8 @@ public static AdviceScope onEnter(@Advice.Argument(0) RedisCommand comm public static void stopSpan( @Advice.Argument(0) RedisCommand command, @Advice.Thrown @Nullable Throwable throwable, - @Advice.Return AsyncCommand asyncCommand, - @Advice.Enter AdviceScope adviceScope) { + @Advice.Return @Nullable AsyncCommand asyncCommand, + @Advice.Enter @Nullable AdviceScope adviceScope) { if (adviceScope != null) { adviceScope.end(throwable, command, asyncCommand); diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java index 89655468da19..54eabdc94212 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceClientInstrumentation.java @@ -85,8 +85,8 @@ public static AdviceScope onEnter(@Advice.Argument(1) RedisURI redisUri) { public static void stopSpan( @Advice.Argument(1) RedisURI redisUri, @Advice.Thrown @Nullable Throwable throwable, - @Advice.Return ConnectionFuture connectionFuture, - @Advice.Enter AdviceScope adviceScope) { + @Advice.Return @Nullable ConnectionFuture connectionFuture, + @Advice.Enter @Nullable AdviceScope adviceScope) { if (adviceScope != null) { adviceScope.end(throwable, redisUri, connectionFuture); } From 67500080c6d470395da48757d46ac93c6e959b1d Mon Sep 17 00:00:00 2001 From: otelbot <197425009+otelbot@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:16:11 +0000 Subject: [PATCH 7/7] ./gradlew spotlessApply --- .../lettuce/v4_0/LettuceConnectInstrumentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java index ba427ebc1f4d..62851588ed98 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectInstrumentation.java @@ -58,7 +58,7 @@ public static AdviceScope onEnter(@Advice.Argument(1) RedisURI redisUri) { if (!connectInstrumenter().shouldStart(parentContext, redisUri)) { return null; } - + Context context = connectInstrumenter().start(parentContext, redisUri); return new AdviceScope(context, context.makeCurrent()); }