@@ -271,6 +271,12 @@ private void fillEndpoint(OpenTelemetryEndpoint endpoint) {
271271 @ CanIgnoreReturnValue
272272 @ SuppressWarnings ({"UnusedMethod" , "EffectivelyPrivate" })
273273 public synchronized Tracer .Span start (RedisCommand <?, ?, ?> command ) {
274+ // Extract args BEFORE calling start() so db.statement can include them
275+ // when it's set on SpanBuilder (making it available to samplers)
276+ if (command .getArgs () != null ) {
277+ argsList = OtelCommandArgsUtil .getCommandArgs (command .getArgs ());
278+ }
279+
274280 start ();
275281 long startNanos = System .nanoTime ();
276282
@@ -280,10 +286,6 @@ public synchronized Tracer.Span start(RedisCommand<?, ?, ?> command) {
280286 }
281287 span .updateName (command .getType ().toString ());
282288
283- if (command .getArgs () != null ) {
284- argsList = OtelCommandArgsUtil .getCommandArgs (command .getArgs ());
285- }
286-
287289 if (command instanceof CompleteableCommand ) {
288290 CompleteableCommand <?> completeableCommand = (CompleteableCommand <?>) command ;
289291 completeableCommand .onComplete (
@@ -311,8 +313,27 @@ public synchronized Tracer.Span start(RedisCommand<?, ?, ?> command) {
311313 @ Override
312314 @ CanIgnoreReturnValue
313315 public synchronized Tracer .Span start () {
316+ // Set db.statement on SpanBuilder before starting span so it's available to samplers
317+ if (name != null ) {
318+ String statement =
319+ sanitizer .sanitize (name , argsList != null ? argsList : splitArgs (argsString ));
320+ if (statement != null ) {
321+ if (SemconvStability .emitStableDatabaseSemconv ()) {
322+ spanBuilder .setAttribute (DB_QUERY_TEXT , statement );
323+ attributesBuilder .put (DB_QUERY_TEXT , statement );
324+ }
325+ if (SemconvStability .emitOldDatabaseSemconv ()) {
326+ spanBuilder .setAttribute (DB_STATEMENT , statement );
327+ attributesBuilder .put (DB_STATEMENT , statement );
328+ }
329+ }
330+ }
331+
314332 span = spanBuilder .startSpan ();
315333 spanStartNanos = System .nanoTime ();
334+ // Note: Span name cannot be set on SpanBuilder because it's set during
335+ // tracer.spanBuilder(name) call in nextSpan(), and we don't know the actual command name at
336+ // that point. We have to update the name after the span starts.
316337 if (name != null ) {
317338 span .updateName (name );
318339 }
@@ -401,19 +422,11 @@ public synchronized void finish() {
401422 }
402423
403424 private void finish (Span span , long startTime ) {
404- if (name != null ) {
405- String statement =
406- sanitizer .sanitize (name , argsList != null ? argsList : splitArgs (argsString ));
407- if (SemconvStability .emitStableDatabaseSemconv ()) {
408- span .setAttribute (DB_QUERY_TEXT , statement );
409- metrics .onEnd (
410- metrics .onStart (Context .current (), Attributes .empty (), startTime ),
411- attributesBuilder .build (),
412- System .nanoTime ());
413- }
414- if (SemconvStability .emitOldDatabaseSemconv ()) {
415- span .setAttribute (DB_STATEMENT , statement );
416- }
425+ if (SemconvStability .emitStableDatabaseSemconv ()) {
426+ metrics .onEnd (
427+ metrics .onStart (Context .current (), Attributes .empty (), startTime ),
428+ attributesBuilder .build (),
429+ System .nanoTime ());
417430 }
418431 span .end ();
419432 }
0 commit comments