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 1f87084efab6..89d18a418e44 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 @@ -271,6 +271,12 @@ private void fillEndpoint(OpenTelemetryEndpoint endpoint) { @CanIgnoreReturnValue @SuppressWarnings({"UnusedMethod", "EffectivelyPrivate"}) public synchronized Tracer.Span start(RedisCommand command) { + // Extract args BEFORE calling start() so db.statement can include them + // when it's set on SpanBuilder (making it available to samplers) + if (command.getArgs() != null) { + argsList = OtelCommandArgsUtil.getCommandArgs(command.getArgs()); + } + start(); long startNanos = System.nanoTime(); @@ -280,10 +286,6 @@ public synchronized Tracer.Span start(RedisCommand command) { } span.updateName(command.getType().toString()); - if (command.getArgs() != null) { - argsList = OtelCommandArgsUtil.getCommandArgs(command.getArgs()); - } - if (command instanceof CompleteableCommand) { CompleteableCommand completeableCommand = (CompleteableCommand) command; completeableCommand.onComplete( @@ -311,8 +313,27 @@ public synchronized Tracer.Span start(RedisCommand command) { @Override @CanIgnoreReturnValue public synchronized Tracer.Span start() { + // Set db.statement on SpanBuilder before starting span so it's available to samplers + if (name != null) { + String statement = + sanitizer.sanitize(name, argsList != null ? argsList : splitArgs(argsString)); + if (statement != null) { + if (SemconvStability.emitStableDatabaseSemconv()) { + spanBuilder.setAttribute(DB_QUERY_TEXT, statement); + attributesBuilder.put(DB_QUERY_TEXT, statement); + } + if (SemconvStability.emitOldDatabaseSemconv()) { + spanBuilder.setAttribute(DB_STATEMENT, statement); + attributesBuilder.put(DB_STATEMENT, statement); + } + } + } + span = spanBuilder.startSpan(); spanStartNanos = System.nanoTime(); + // Note: Span name cannot be set on SpanBuilder because it's set during + // tracer.spanBuilder(name) call in nextSpan(), and we don't know the actual command name at + // that point. We have to update the name after the span starts. if (name != null) { span.updateName(name); } @@ -401,19 +422,11 @@ public synchronized void finish() { } private void finish(Span span, long startTime) { - if (name != null) { - String statement = - sanitizer.sanitize(name, argsList != null ? argsList : splitArgs(argsString)); - if (SemconvStability.emitStableDatabaseSemconv()) { - span.setAttribute(DB_QUERY_TEXT, statement); - metrics.onEnd( - metrics.onStart(Context.current(), Attributes.empty(), startTime), - attributesBuilder.build(), - System.nanoTime()); - } - if (SemconvStability.emitOldDatabaseSemconv()) { - span.setAttribute(DB_STATEMENT, statement); - } + if (SemconvStability.emitStableDatabaseSemconv()) { + metrics.onEnd( + metrics.onStart(Context.current(), Attributes.empty(), startTime), + attributesBuilder.build(), + System.nanoTime()); } span.end(); }