diff --git a/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonDbAttributesGetter.java b/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonDbAttributesGetter.java index e9aa30f0921c..76463f8dac0b 100644 --- a/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonDbAttributesGetter.java +++ b/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonDbAttributesGetter.java @@ -35,6 +35,12 @@ public String getDbOperationName(RedissonRequest request) { return request.getOperationName(); } + @Nullable + @Override + public Long getDbOperationBatchSize(RedissonRequest request) { + return request.getOperationBatchSize(); + } + @Override @Nullable public InetSocketAddress getNetworkPeerInetSocketAddress( diff --git a/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonRequest.java b/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonRequest.java index 6784bac6794b..bad2c1915961 100644 --- a/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonRequest.java +++ b/instrumentation/redisson/redisson-common-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/common/v3_0/RedissonRequest.java @@ -99,6 +99,24 @@ public String getOperationName() { return null; } + @Nullable + public Long getOperationBatchSize() { + Object command = getCommand(); + if (!(command instanceof CommandsData)) { + return null; + } + List> commands = ((CommandsData) command).getCommands(); + if (commands.isEmpty()) { + return null; + } + int batchSize = commands.size(); + if (commands.get(0).getCommand().getName().equals(MULTI)) { + // MULTI is a transaction wrapper command, not a user operation in the batch. + batchSize--; + } + return batchSize > 1 ? (long) batchSize : null; + } + @Nullable private static String getBatchOperationName(List> commands) { if (commands.size() < 2) { diff --git a/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonAsyncClientTest.java b/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonAsyncClientTest.java index fb752b3cdec3..9f37859778d7 100644 --- a/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonAsyncClientTest.java +++ b/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonAsyncClientTest.java @@ -256,6 +256,9 @@ void atomicBatchCommand() { equalTo( DB_OPERATION_NAME, emitStableDatabaseSemconv() ? "MULTI SET" : null), + // db.operation.batch.size is not emitted because MULTI transaction + // telemetry is split across wrapper and command spans, so this span + // does not represent the full logical batch. equalTo(maybeStable(DB_STATEMENT), "MULTI;SET batch1 ?")) .hasParent(trace.getSpan(0)), span -> diff --git a/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonClientTest.java b/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonClientTest.java index 4f72444adb31..abd694d9e56e 100644 --- a/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonClientTest.java +++ b/instrumentation/redisson/redisson-common-3.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/redisson/AbstractRedissonClientTest.java @@ -16,6 +16,7 @@ import static io.opentelemetry.instrumentation.testing.util.TestLatestDeps.testLatestDeps; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_BATCH_SIZE; import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PEER_ADDRESS; import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PEER_PORT; import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_TYPE; @@ -268,6 +269,8 @@ void batchCommand() throws ReflectiveOperationException { equalTo( DB_OPERATION_NAME, emitStableDatabaseSemconv() ? "PIPELINE SET" : null), + equalTo( + DB_OPERATION_BATCH_SIZE, emitStableDatabaseSemconv() ? 2L : null), equalTo(maybeStable(DB_STATEMENT), "SET batch1 ?;SET batch2 ?")))); } @@ -297,6 +300,8 @@ void mixedBatchCommand() throws ReflectiveOperationException { equalTo(maybeStable(DB_SYSTEM), REDIS), equalTo( DB_OPERATION_NAME, emitStableDatabaseSemconv() ? "PIPELINE" : null), + equalTo( + DB_OPERATION_BATCH_SIZE, emitStableDatabaseSemconv() ? 2L : null), equalTo(maybeStable(DB_STATEMENT), "SET batch1 ?;GET batch1")))); } @@ -330,6 +335,8 @@ void largeBatchCommand() throws ReflectiveOperationException { equalTo( DB_OPERATION_NAME, emitStableDatabaseSemconv() ? "PIPELINE SET" : null), + equalTo( + DB_OPERATION_BATCH_SIZE, emitStableDatabaseSemconv() ? 4L : null), equalTo( maybeStable(DB_STATEMENT), "SET " + bucketName + " ?;SET " + bucketName + " ?")))); @@ -370,6 +377,9 @@ void atomicBatchCommand() { equalTo( DB_OPERATION_NAME, emitStableDatabaseSemconv() ? "MULTI SET" : null), + // db.operation.batch.size is not emitted because MULTI transaction + // telemetry is split across wrapper and command spans, so this span + // does not represent the full logical batch. equalTo(maybeStable(DB_STATEMENT), "MULTI;SET batch1 ?")) .hasParent(trace.getSpan(0)), span ->