diff --git a/instrumentation/armeria/armeria-grpc-1.14/javaagent/build.gradle.kts b/instrumentation/armeria/armeria-grpc-1.14/javaagent/build.gradle.kts index 118a3a579133..1b1c7cef52fe 100644 --- a/instrumentation/armeria/armeria-grpc-1.14/javaagent/build.gradle.kts +++ b/instrumentation/armeria/armeria-grpc-1.14/javaagent/build.gradle.kts @@ -59,8 +59,21 @@ afterEvaluate { } } -tasks.test { - systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") +tasks { + withType().configureEach { + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + } + + val testStableSemconv by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + jvmArgs("-Dotel.semconv-stability.opt-in=rpc") + systemProperty("metadataConfig", "otel.semconv-stability.opt-in=rpc") + } + + check { + dependsOn(testStableSemconv) + } } if (findProperty("denyUnsafe") as Boolean) { diff --git a/instrumentation/armeria/armeria-grpc-1.14/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/grpc/v1_14/ArmeriaGrpcTest.java b/instrumentation/armeria/armeria-grpc-1.14/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/grpc/v1_14/ArmeriaGrpcTest.java index c5c5394370ef..9fe9a7db9b7d 100644 --- a/instrumentation/armeria/armeria-grpc-1.14/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/grpc/v1_14/ArmeriaGrpcTest.java +++ b/instrumentation/armeria/armeria-grpc-1.14/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/grpc/v1_14/ArmeriaGrpcTest.java @@ -5,6 +5,9 @@ package io.opentelemetry.javaagent.instrumentation.armeria.grpc.v1_14; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldRpcSemconv; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableRpcSemconv; +import static io.opentelemetry.instrumentation.testing.junit.rpc.SemconvRpcStabilityUtil.maybeStable; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; @@ -12,6 +15,7 @@ import static io.opentelemetry.semconv.incubating.MessageIncubatingAttributes.MESSAGE_TYPE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_GRPC_STATUS_CODE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD; +import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_RESPONSE_STATUS_CODE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM; import static org.assertj.core.api.Assertions.assertThat; @@ -78,10 +82,17 @@ void grpcInstrumentation() { .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) .hasAttributesSatisfyingExactly( - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(maybeStable(RPC_SYSTEM), "grpc"), + equalTo(RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() ? "example.Greeter/SayHello" : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "127.0.0.1"), equalTo(SERVER_PORT, (long) server.httpPort())) .hasEventsSatisfyingExactly( @@ -101,10 +112,17 @@ void grpcInstrumentation() { .hasKind(SpanKind.SERVER) .hasParent(trace.getSpan(1)) .hasAttributesSatisfyingExactly( - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(maybeStable(RPC_SYSTEM), "grpc"), + equalTo(RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() ? "example.Greeter/SayHello" : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "127.0.0.1"), equalTo(SERVER_PORT, server.httpPort())) .hasEventsSatisfyingExactly( diff --git a/instrumentation/grpc-1.6/javaagent/build.gradle.kts b/instrumentation/grpc-1.6/javaagent/build.gradle.kts index d4eca5080f1d..d3b786eacbd1 100644 --- a/instrumentation/grpc-1.6/javaagent/build.gradle.kts +++ b/instrumentation/grpc-1.6/javaagent/build.gradle.kts @@ -31,7 +31,7 @@ dependencies { val collectMetadata = findProperty("collectMetadata")?.toString() ?: "false" tasks { - test { + withType().configureEach { systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) // The agent context debug mechanism isn't compatible with the bridge approach which may add a // gRPC context to the root. @@ -56,26 +56,46 @@ tasks { testClassesDirs = sourceSets.test.get().output.classesDirs classpath = sourceSets.test.get().runtimeClasspath - // replicated base config from standard test task - systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) - jvmArgs("-Dotel.javaagent.experimental.thread-propagation-debugger.enabled=false") - jvmArgs("-Dotel.instrumentation.grpc.capture-metadata.client.request=some-client-key") - jvmArgs("-Dotel.instrumentation.grpc.capture-metadata.server.request=some-server-key") - jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true") - // exclude our grpc library instrumentation, the ContextStorageOverride contained within it // breaks the tests classpath = classpath.filter { !it.absolutePath.contains("opentelemetry-grpc-1.6") } - systemProperty("collectMetadata", collectMetadata) systemProperty("metadataConfig", "otel.instrumentation.grpc.experimental-span-attributes=true") jvmArgs("-Dotel.instrumentation.grpc.experimental-span-attributes=true") } + val testStableSemconv by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + + // exclude our grpc library instrumentation, the ContextStorageOverride contained within it + // breaks the tests + classpath = classpath.filter { + !it.absolutePath.contains("opentelemetry-grpc-1.6") + } + + jvmArgs("-Dotel.semconv-stability.opt-in=rpc") + systemProperty("metadataConfig", "otel.semconv-stability.opt-in=rpc") + } + + val testBothSemconv by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + + // exclude our grpc library instrumentation, the ContextStorageOverride contained within it + // breaks the tests + classpath = classpath.filter { + !it.absolutePath.contains("opentelemetry-grpc-1.6") + } + + jvmArgs("-Dotel.semconv-stability.opt-in=rpc/dup") + systemProperty("metadataConfig", "otel.semconv-stability.opt-in=rpc/dup") + } + check { - dependsOn(testExperimental) + dependsOn(testExperimental, testStableSemconv, testBothSemconv) } } diff --git a/instrumentation/grpc-1.6/library/build.gradle.kts b/instrumentation/grpc-1.6/library/build.gradle.kts index 00ace4566efb..4d981a56fbc6 100644 --- a/instrumentation/grpc-1.6/library/build.gradle.kts +++ b/instrumentation/grpc-1.6/library/build.gradle.kts @@ -17,13 +17,34 @@ dependencies { } tasks { - test { + withType().configureEach { systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) - jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true") // latest dep test occasionally fails because network type is ipv6 instead of the expected ipv4 // and peer address is 0:0:0:0:0:0:0:1 instead of 127.0.0.1 jvmArgs("-Djava.net.preferIPv4Stack=true") } + + test { + jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true") + } + + val testStableSemconv by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + + jvmArgs("-Dotel.semconv-stability.opt-in=rpc") + } + + val testBothSemconv by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + + jvmArgs("-Dotel.semconv-stability.opt-in=rpc/dup") + } + + check { + dependsOn(testStableSemconv, testBothSemconv) + } } if (!(findProperty("testLatestDeps") as Boolean)) { diff --git a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/CapturedGrpcMetadataUtil.java b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/CapturedGrpcMetadataUtil.java index 5c39d4c228f9..9cb5f3d7bac8 100644 --- a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/CapturedGrpcMetadataUtil.java +++ b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/CapturedGrpcMetadataUtil.java @@ -17,8 +17,12 @@ final class CapturedGrpcMetadataUtil { private static final String RPC_REQUEST_METADATA_KEY_ATTRIBUTE_PREFIX = "rpc.grpc.request.metadata."; + private static final String RPC_STABLE_REQUEST_METADATA_KEY_ATTRIBUTE_PREFIX = + "rpc.request.metadata."; private static final ConcurrentMap>> requestKeysCache = new ConcurrentHashMap<>(); + private static final ConcurrentMap>> stableRequestKeysCache = + new ConcurrentHashMap<>(); static List lowercase(List names) { return unmodifiableList(names.stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(toList())); @@ -29,9 +33,19 @@ static AttributeKey> requestAttributeKey(String metadataKey) { metadataKey, CapturedGrpcMetadataUtil::createRequestKey); } + static AttributeKey> stableRequestAttributeKey(String metadataKey) { + return stableRequestKeysCache.computeIfAbsent( + metadataKey, CapturedGrpcMetadataUtil::createStableRequestKey); + } + private static AttributeKey> createRequestKey(String metadataKey) { return AttributeKey.stringArrayKey(RPC_REQUEST_METADATA_KEY_ATTRIBUTE_PREFIX + metadataKey); } + private static AttributeKey> createStableRequestKey(String metadataKey) { + return AttributeKey.stringArrayKey( + RPC_STABLE_REQUEST_METADATA_KEY_ATTRIBUTE_PREFIX + metadataKey); + } + private CapturedGrpcMetadataUtil() {} } diff --git a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcAttributesExtractor.java b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcAttributesExtractor.java index 1e4f6ee406ea..23aea85c86d2 100644 --- a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcAttributesExtractor.java +++ b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcAttributesExtractor.java @@ -5,8 +5,11 @@ package io.opentelemetry.instrumentation.grpc.v1_6; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldRpcSemconv; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableRpcSemconv; import static io.opentelemetry.instrumentation.grpc.v1_6.CapturedGrpcMetadataUtil.lowercase; import static io.opentelemetry.instrumentation.grpc.v1_6.CapturedGrpcMetadataUtil.requestAttributeKey; +import static io.opentelemetry.instrumentation.grpc.v1_6.CapturedGrpcMetadataUtil.stableRequestAttributeKey; import io.grpc.Status; import io.opentelemetry.api.common.AttributeKey; @@ -21,6 +24,8 @@ final class GrpcAttributesExtractor implements AttributesExtractor RPC_GRPC_STATUS_CODE = AttributeKey.longKey("rpc.grpc.status_code"); + private static final AttributeKey RPC_RESPONSE_STATUS_CODE = + AttributeKey.stringKey("rpc.response.status_code"); private final GrpcRpcAttributesGetter getter; private final List capturedRequestMetadata; @@ -44,12 +49,22 @@ public void onEnd( @Nullable Status status, @Nullable Throwable error) { if (status != null) { - attributes.put(RPC_GRPC_STATUS_CODE, status.getCode().value()); + if (emitOldRpcSemconv()) { + attributes.put(RPC_GRPC_STATUS_CODE, status.getCode().value()); + } + if (emitStableRpcSemconv()) { + attributes.put(RPC_RESPONSE_STATUS_CODE, status.getCode().name()); + } } for (String key : capturedRequestMetadata) { List value = getter.metadataValue(request, key); if (!value.isEmpty()) { - attributes.put(requestAttributeKey(key), value); + if (emitOldRpcSemconv()) { + attributes.put(requestAttributeKey(key), value); + } + if (emitStableRpcSemconv()) { + attributes.put(stableRequestAttributeKey(key), value); + } } } } diff --git a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcRpcAttributesGetter.java b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcRpcAttributesGetter.java index 250aac6773d9..99f5d4fba3e1 100644 --- a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcRpcAttributesGetter.java +++ b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcRpcAttributesGetter.java @@ -46,6 +46,11 @@ public String getMethod(GrpcRequest request) { return fullMethodName.substring(slashIndex + 1); } + @Override + public String getRpcMethod(GrpcRequest request) { + return request.getMethod().getFullMethodName(); + } + @Override @Nullable public Long getRequestSize(GrpcRequest request) { diff --git a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcTelemetryBuilder.java b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcTelemetryBuilder.java index 703a93496a52..a1eee0767fbf 100644 --- a/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcTelemetryBuilder.java +++ b/instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcTelemetryBuilder.java @@ -12,6 +12,7 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.incubator.semconv.rpc.RpcClientAttributesExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.rpc.RpcClientMetrics; +import io.opentelemetry.instrumentation.api.incubator.semconv.rpc.RpcMetricsContextCustomizers; import io.opentelemetry.instrumentation.api.incubator.semconv.rpc.RpcServerAttributesExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.rpc.RpcServerMetrics; import io.opentelemetry.instrumentation.api.incubator.semconv.rpc.RpcSizeAttributesExtractor; @@ -151,6 +152,7 @@ public GrpcTelemetryBuilder setCapturedServerRequestMetadata( } /** Returns a new {@link GrpcTelemetry} with the settings of this {@link GrpcTelemetryBuilder}. */ + @SuppressWarnings("deprecation") // RpcMetricsContextCustomizers is deprecated for removal in 3.0 public GrpcTelemetry build() { SpanNameExtractor originalSpanNameExtractor = new GrpcSpanNameExtractor(); SpanNameExtractor clientSpanNameExtractor = @@ -179,7 +181,9 @@ public GrpcTelemetry build() { .addAttributesExtractor( new GrpcAttributesExtractor( GrpcRpcAttributesGetter.INSTANCE, capturedClientRequestMetadata)) - .addOperationMetrics(RpcClientMetrics.get()); + .addOperationMetrics(RpcClientMetrics.get()) + .addContextCustomizer( + RpcMetricsContextCustomizers.dualEmitContextCustomizer(rpcAttributesGetter)); Experimental.addOperationListenerAttributesExtractor( clientInstrumenterBuilder, RpcSizeAttributesExtractor.create(rpcAttributesGetter)); serverInstrumenterBuilder @@ -192,7 +196,9 @@ public GrpcTelemetry build() { new GrpcAttributesExtractor( GrpcRpcAttributesGetter.INSTANCE, capturedServerRequestMetadata)) .addAttributesExtractors(additionalServerExtractors) - .addOperationMetrics(RpcServerMetrics.get()); + .addOperationMetrics(RpcServerMetrics.get()) + .addContextCustomizer( + RpcMetricsContextCustomizers.dualEmitContextCustomizer(rpcAttributesGetter)); Experimental.addOperationListenerAttributesExtractor( serverInstrumenterBuilder, RpcSizeAttributesExtractor.create(rpcAttributesGetter)); diff --git a/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.java b/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.java index 972f8353800b..d828ebb737fe 100644 --- a/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.java +++ b/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.grpc.v1_6; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldRpcSemconv; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableRpcSemconv; import static io.opentelemetry.instrumentation.grpc.v1_6.AbstractGrpcTest.addExtraClientAttributes; import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.GRPC_RECEIVED_MESSAGE_COUNT; import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.GRPC_SENT_MESSAGE_COUNT; @@ -21,8 +23,10 @@ import static io.opentelemetry.semconv.incubating.MessageIncubatingAttributes.MESSAGE_TYPE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_GRPC_STATUS_CODE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD; +import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_RESPONSE_STATUS_CODE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM; +import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM_NAME; import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.stream.Collectors.toList; @@ -243,10 +247,23 @@ public void onCompleted() { experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "Conversation"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/Conversation" + : "Conversation"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .satisfies( @@ -263,10 +280,21 @@ public void onCompleted() { v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "Conversation"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/Conversation" + : "Conversation"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -285,49 +313,100 @@ public void onCompleted() { span.hasName("clientOnNext") .hasKind(SpanKind.INTERNAL) .hasParent(trace.getSpan(0)))); - testing() - .waitAndAssertMetrics( - "io.opentelemetry.grpc-1.6", - "rpc.server.duration", - metrics -> - metrics.anySatisfy( - metric -> - assertThat(metric) - .hasUnit("ms") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfying( - equalTo(SERVER_ADDRESS, "localhost"), - equalTo(RPC_METHOD, "Conversation"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_SYSTEM, "grpc"), - equalTo( - RPC_GRPC_STATUS_CODE, - (long) Status.Code.OK.value())))))); - testing() - .waitAndAssertMetrics( - "io.opentelemetry.grpc-1.6", - "rpc.client.duration", - metrics -> - metrics.anySatisfy( - metric -> - assertThat(metric) - .hasUnit("ms") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfying( - equalTo(SERVER_ADDRESS, "localhost"), - equalTo(SERVER_PORT, server.getPort()), - equalTo(RPC_METHOD, "Conversation"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_SYSTEM, "grpc"), - equalTo( - RPC_GRPC_STATUS_CODE, - (long) Status.Code.OK.value())))))); + if (emitOldRpcSemconv()) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.server.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("ms") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfying( + equalTo(SERVER_ADDRESS, "localhost"), + equalTo(RPC_METHOD, "Conversation"), + equalTo(RPC_SERVICE, "example.Greeter"), + equalTo(RPC_SYSTEM, "grpc"), + equalTo( + RPC_GRPC_STATUS_CODE, + (long) Status.Code.OK.value())))))); + } + if (emitStableRpcSemconv()) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.server.call.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("s") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfying( + equalTo(RPC_SYSTEM_NAME, "grpc"), + equalTo(SERVER_ADDRESS, "localhost"), + equalTo( + RPC_METHOD, "example.Greeter/Conversation"), + equalTo( + RPC_RESPONSE_STATUS_CODE, + Status.Code.OK.name())))))); + } + if (emitOldRpcSemconv()) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.client.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("ms") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfying( + equalTo(SERVER_ADDRESS, "localhost"), + equalTo(SERVER_PORT, server.getPort()), + equalTo(RPC_METHOD, "Conversation"), + equalTo(RPC_SERVICE, "example.Greeter"), + equalTo(RPC_SYSTEM, "grpc"), + equalTo( + RPC_GRPC_STATUS_CODE, + (long) Status.Code.OK.value())))))); + } + if (emitStableRpcSemconv()) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.client.call.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("s") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfying( + equalTo(RPC_SYSTEM_NAME, "grpc"), + equalTo(SERVER_ADDRESS, "localhost"), + equalTo(SERVER_PORT, server.getPort()), + equalTo( + RPC_METHOD, "example.Greeter/Conversation"), + equalTo( + RPC_RESPONSE_STATUS_CODE, + Status.Code.OK.name())))))); + } } @Test diff --git a/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcTest.java b/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcTest.java index 32aec3bc7bca..1b01a27424c9 100644 --- a/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcTest.java +++ b/instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcTest.java @@ -5,12 +5,15 @@ package io.opentelemetry.instrumentation.grpc.v1_6; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldRpcSemconv; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableRpcSemconv; import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.GRPC_RECEIVED_MESSAGE_COUNT; import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.GRPC_SENT_MESSAGE_COUNT; import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.experimentalSatisfies; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; 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; @@ -20,8 +23,10 @@ import static io.opentelemetry.semconv.incubating.MessageIncubatingAttributes.MESSAGE_TYPE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_GRPC_STATUS_CODE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_METHOD; +import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_RESPONSE_STATUS_CODE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SERVICE; import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM; +import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM_NAME; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -151,10 +156,23 @@ public void sayHello( experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -179,10 +197,21 @@ public void sayHello( v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -269,10 +298,23 @@ public void sayHello( experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -297,10 +339,21 @@ public void sayHello( v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -399,10 +452,23 @@ public void onCompleted() { experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -427,10 +493,21 @@ public void onCompleted() { v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -502,10 +579,25 @@ public void sayHello( experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) status.getCode().value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() + ? (long) status.getCode().value() + : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? status.getCode().name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -526,10 +618,26 @@ public void sayHello( v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isEqualTo(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) status.getCode().value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + ERROR_TYPE, + emitStableRpcSemconv() && status.getCause() != null + ? status.getCause().getClass().getName() + : null), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) status.getCode().value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? status.getCode().name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -606,12 +714,27 @@ public void sayHello( experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), equalTo( RPC_GRPC_STATUS_CODE, - (long) Status.UNKNOWN.getCode().value()), + emitOldRpcSemconv() + ? (long) Status.UNKNOWN.getCode().value() + : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() + ? Status.UNKNOWN.getCode().name() + : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -627,10 +750,28 @@ public void sayHello( .hasParent(trace.getSpan(0)) .hasStatus(StatusData.error()) .hasAttributesSatisfyingExactly( - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.UNKNOWN.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + ERROR_TYPE, + emitStableRpcSemconv() + ? StatusRuntimeException.class.getName() + : null), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() + ? (long) Status.Code.UNKNOWN.value() + : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.UNKNOWN.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -803,10 +944,23 @@ public void onCompleted() { experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -831,10 +985,21 @@ public void onCompleted() { v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -927,11 +1092,32 @@ public void onCompleted() { experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayMultipleHello"), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayMultipleHello" + : "SayMultipleHello"), equalTo( - RPC_GRPC_STATUS_CODE, (long) Status.Code.CANCELLED.value()), + ERROR_TYPE, + emitStableRpcSemconv() + ? thrown.getClass().getName() + : null), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() + ? (long) Status.Code.CANCELLED.value() + : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() + ? Status.Code.CANCELLED.name() + : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfying( @@ -958,10 +1144,23 @@ public void onCompleted() { v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayMultipleHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.CANCELLED.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayMultipleHello" + : "SayMultipleHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() + ? (long) Status.Code.CANCELLED.value() + : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.CANCELLED.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -1049,11 +1248,25 @@ public void onCompleted() { experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), equalTo( - RPC_SERVICE, "grpc.reflection.v1alpha.ServerReflection"), - equalTo(RPC_METHOD, "ServerReflectionInfo"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + RPC_SERVICE, + emitOldRpcSemconv() + ? "grpc.reflection.v1alpha.ServerReflection" + : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo" + : "ServerReflectionInfo"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -1079,10 +1292,24 @@ public void onCompleted() { v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "grpc.reflection.v1alpha.ServerReflection"), - equalTo(RPC_METHOD, "ServerReflectionInfo"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() + ? "grpc.reflection.v1alpha.ServerReflection" + : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo" + : "ServerReflectionInfo"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -1153,10 +1380,23 @@ public void sayHello( experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, + emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, (long) server.getPort()))) .hasEventsSatisfyingExactly( @@ -1181,10 +1421,21 @@ public void sayHello( v -> assertThat(v).isGreaterThan(0)), experimentalSatisfies( GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)), - equalTo(RPC_SYSTEM, "grpc"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_GRPC_STATUS_CODE, (long) Status.Code.OK.value()), + equalTo(RPC_SYSTEM, emitOldRpcSemconv() ? "grpc" : null), + equalTo(RPC_SYSTEM_NAME, emitStableRpcSemconv() ? "grpc" : null), + equalTo( + RPC_SERVICE, emitOldRpcSemconv() ? "example.Greeter" : null), + equalTo( + RPC_METHOD, + emitStableRpcSemconv() + ? "example.Greeter/SayHello" + : "SayHello"), + equalTo( + RPC_GRPC_STATUS_CODE, + emitOldRpcSemconv() ? (long) Status.Code.OK.value() : null), + equalTo( + RPC_RESPONSE_STATUS_CODE, + emitStableRpcSemconv() ? Status.Code.OK.name() : null), equalTo(SERVER_ADDRESS, "localhost"), equalTo(SERVER_PORT, server.getPort()), equalTo(NETWORK_TYPE, "ipv4"), @@ -1352,11 +1603,16 @@ public void sayHello( @Test void setCapturedRequestMetadata() throws Exception { - String metadataAttributePrefix = "rpc.grpc.request.metadata."; - AttributeKey> clientAttributeKey = - AttributeKey.stringArrayKey(metadataAttributePrefix + CLIENT_REQUEST_METADATA_KEY); - AttributeKey> serverAttributeKey = - AttributeKey.stringArrayKey(metadataAttributePrefix + SERVER_REQUEST_METADATA_KEY); + String oldMetadataAttributePrefix = "rpc.grpc.request.metadata."; + String stableMetadataAttributePrefix = "rpc.request.metadata."; + AttributeKey> oldClientAttributeKey = + AttributeKey.stringArrayKey(oldMetadataAttributePrefix + CLIENT_REQUEST_METADATA_KEY); + AttributeKey> stableClientAttributeKey = + AttributeKey.stringArrayKey(stableMetadataAttributePrefix + CLIENT_REQUEST_METADATA_KEY); + AttributeKey> oldServerAttributeKey = + AttributeKey.stringArrayKey(oldMetadataAttributePrefix + SERVER_REQUEST_METADATA_KEY); + AttributeKey> stableServerAttributeKey = + AttributeKey.stringArrayKey(stableMetadataAttributePrefix + SERVER_REQUEST_METADATA_KEY); String serverMetadataValue = "server-value"; String clientMetadataValue = "client-value"; @@ -1401,16 +1657,32 @@ public void sayHello( trace -> trace.hasSpansSatisfyingExactly( span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), - span -> - span.hasName("example.Greeter/SayHello") - .hasKind(SpanKind.CLIENT) - .hasParent(trace.getSpan(0)) - .hasAttribute(clientAttributeKey, singletonList(clientMetadataValue)), - span -> - span.hasName("example.Greeter/SayHello") - .hasKind(SpanKind.SERVER) - .hasParent(trace.getSpan(1)) - .hasAttribute(serverAttributeKey, singletonList(serverMetadataValue)))); + span -> { + span.hasName("example.Greeter/SayHello") + .hasKind(SpanKind.CLIENT) + .hasParent(trace.getSpan(0)); + if (emitOldRpcSemconv()) { + span.hasAttribute( + oldClientAttributeKey, singletonList(clientMetadataValue)); + } + if (emitStableRpcSemconv()) { + span.hasAttribute( + stableClientAttributeKey, singletonList(clientMetadataValue)); + } + }, + span -> { + span.hasName("example.Greeter/SayHello") + .hasKind(SpanKind.SERVER) + .hasParent(trace.getSpan(1)); + if (emitOldRpcSemconv()) { + span.hasAttribute( + oldServerAttributeKey, singletonList(serverMetadataValue)); + } + if (emitStableRpcSemconv()) { + span.hasAttribute( + stableServerAttributeKey, singletonList(serverMetadataValue)); + } + })); } private ManagedChannel createChannel(Server server) throws Exception { @@ -1449,41 +1721,16 @@ static List addExtraClientAttributes(AttributeAssertion... a private void assertMetrics(Server server, Status.Code statusCode) { boolean hasSizeMetric = statusCode == Status.Code.OK; - testing() - .waitAndAssertMetrics( - "io.opentelemetry.grpc-1.6", - "rpc.server.duration", - metrics -> - metrics.anySatisfy( - metric -> - assertThat(metric) - .hasUnit("ms") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(SERVER_ADDRESS, "localhost"), - satisfies( - SERVER_PORT, k -> k.isInstanceOf(Long.class)), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_SYSTEM, "grpc"), - equalTo( - RPC_GRPC_STATUS_CODE, - (long) statusCode.value()), - equalTo(NETWORK_TYPE, "ipv4")))))); - - if (hasSizeMetric) { + if (emitOldRpcSemconv()) { testing() .waitAndAssertMetrics( "io.opentelemetry.grpc-1.6", - "rpc.server.request.size", + "rpc.server.duration", metrics -> metrics.anySatisfy( metric -> assertThat(metric) - .hasUnit("By") + .hasUnit("ms") .hasHistogramSatisfying( histogram -> histogram.hasPointsSatisfying( @@ -1499,82 +1746,87 @@ private void assertMetrics(Server server, Status.Code statusCode) { RPC_GRPC_STATUS_CODE, (long) statusCode.value()), equalTo(NETWORK_TYPE, "ipv4")))))); + + if (hasSizeMetric) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.server.request.size", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("By") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfyingExactly( + equalTo(SERVER_ADDRESS, "localhost"), + satisfies( + SERVER_PORT, + k -> k.isInstanceOf(Long.class)), + equalTo(RPC_METHOD, "SayHello"), + equalTo(RPC_SERVICE, "example.Greeter"), + equalTo(RPC_SYSTEM, "grpc"), + equalTo( + RPC_GRPC_STATUS_CODE, + (long) statusCode.value()), + equalTo(NETWORK_TYPE, "ipv4")))))); + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.server.response.size", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("By") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfyingExactly( + equalTo(SERVER_ADDRESS, "localhost"), + satisfies( + SERVER_PORT, + k -> k.isInstanceOf(Long.class)), + equalTo(RPC_METHOD, "SayHello"), + equalTo(RPC_SERVICE, "example.Greeter"), + equalTo(RPC_SYSTEM, "grpc"), + equalTo( + RPC_GRPC_STATUS_CODE, + (long) statusCode.value()), + equalTo(NETWORK_TYPE, "ipv4")))))); + } + testing() .waitAndAssertMetrics( "io.opentelemetry.grpc-1.6", - "rpc.server.response.size", + "rpc.client.duration", metrics -> metrics.anySatisfy( metric -> assertThat(metric) - .hasUnit("By") + .hasUnit("ms") .hasHistogramSatisfying( histogram -> histogram.hasPointsSatisfying( point -> - point.hasAttributesSatisfyingExactly( + point.hasAttributesSatisfying( equalTo(SERVER_ADDRESS, "localhost"), - satisfies( - SERVER_PORT, k -> k.isInstanceOf(Long.class)), + equalTo(SERVER_PORT, server.getPort()), equalTo(RPC_METHOD, "SayHello"), equalTo(RPC_SERVICE, "example.Greeter"), equalTo(RPC_SYSTEM, "grpc"), equalTo( RPC_GRPC_STATUS_CODE, - (long) statusCode.value()), - equalTo(NETWORK_TYPE, "ipv4")))))); - } - - testing() - .waitAndAssertMetrics( - "io.opentelemetry.grpc-1.6", - "rpc.client.duration", - metrics -> - metrics.anySatisfy( - metric -> - assertThat(metric) - .hasUnit("ms") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfying( - equalTo(SERVER_ADDRESS, "localhost"), - equalTo(SERVER_PORT, server.getPort()), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_SYSTEM, "grpc"), - equalTo( - RPC_GRPC_STATUS_CODE, - (long) statusCode.value())))))); + (long) statusCode.value())))))); - testing() - .waitAndAssertMetrics( - "io.opentelemetry.grpc-1.6", - "rpc.client.request.size", - metrics -> - metrics.anySatisfy( - metric -> - assertThat(metric) - .hasUnit("By") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfying( - equalTo(SERVER_ADDRESS, "localhost"), - equalTo(SERVER_PORT, server.getPort()), - equalTo(RPC_METHOD, "SayHello"), - equalTo(RPC_SERVICE, "example.Greeter"), - equalTo(RPC_SYSTEM, "grpc"), - equalTo( - RPC_GRPC_STATUS_CODE, - (long) statusCode.value())))))); - if (hasSizeMetric) { testing() .waitAndAssertMetrics( "io.opentelemetry.grpc-1.6", - "rpc.client.response.size", + "rpc.client.request.size", metrics -> metrics.anySatisfy( metric -> @@ -1593,6 +1845,75 @@ private void assertMetrics(Server server, Status.Code statusCode) { equalTo( RPC_GRPC_STATUS_CODE, (long) statusCode.value())))))); + if (hasSizeMetric) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.client.response.size", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("By") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfying( + equalTo(SERVER_ADDRESS, "localhost"), + equalTo(SERVER_PORT, server.getPort()), + equalTo(RPC_METHOD, "SayHello"), + equalTo(RPC_SERVICE, "example.Greeter"), + equalTo(RPC_SYSTEM, "grpc"), + equalTo( + RPC_GRPC_STATUS_CODE, + (long) statusCode.value())))))); + } + } + if (emitStableRpcSemconv()) { + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.server.call.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("s") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfyingExactly( + equalTo(RPC_SYSTEM_NAME, "grpc"), + equalTo(SERVER_ADDRESS, "localhost"), + satisfies( + SERVER_PORT, k -> k.isInstanceOf(Long.class)), + equalTo(RPC_METHOD, "example.Greeter/SayHello"), + equalTo( + RPC_RESPONSE_STATUS_CODE, + statusCode.name())))))); + testing() + .waitAndAssertMetrics( + "io.opentelemetry.grpc-1.6", + "rpc.client.call.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasUnit("s") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point.hasAttributesSatisfying( + equalTo(RPC_SYSTEM_NAME, "grpc"), + equalTo(SERVER_ADDRESS, "localhost"), + equalTo(SERVER_PORT, server.getPort()), + equalTo(RPC_METHOD, "example.Greeter/SayHello"), + equalTo( + RPC_RESPONSE_STATUS_CODE, + statusCode.name())))))); } } } diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/rpc/SemconvRpcStabilityUtil.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/rpc/SemconvRpcStabilityUtil.java new file mode 100644 index 000000000000..bd492bd9760b --- /dev/null +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/rpc/SemconvRpcStabilityUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.testing.junit.rpc; + +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableRpcSemconv; +import static io.opentelemetry.semconv.incubating.RpcIncubatingAttributes.RPC_SYSTEM; + +import io.opentelemetry.api.common.AttributeKey; +import java.util.HashMap; +import java.util.Map; + +// until old rpc semconv are dropped in 3.0 +@SuppressWarnings("deprecation") // using deprecated semconv +public final class SemconvRpcStabilityUtil { + + private static final AttributeKey RPC_SYSTEM_NAME = + AttributeKey.stringKey("rpc.system.name"); + + private static final Map, AttributeKey> oldToNewMap = buildMap(); + + private static Map, AttributeKey> buildMap() { + Map, AttributeKey> map = new HashMap<>(); + map.put(RPC_SYSTEM, RPC_SYSTEM_NAME); + return map; + } + + private SemconvRpcStabilityUtil() {} + + @SuppressWarnings("unchecked") + public static AttributeKey maybeStable(AttributeKey oldKey) { + // not testing rpc/dup + if (emitStableRpcSemconv()) { + return (AttributeKey) oldToNewMap.get(oldKey); + } + return oldKey; + } +}