Skip to content

Commit b3df635

Browse files
authored
gRPC Metadata (#14573)
1 parent dc4cbae commit b3df635

File tree

8 files changed

+386
-1
lines changed

8 files changed

+386
-1
lines changed

docs/instrumentation-list.yaml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3236,6 +3236,8 @@ libraries:
32363236
type: STRING
32373237
grpc:
32383238
- name: grpc-1.6
3239+
description: This instrumentation enables RPC CLIENT and SERVER spans and metrics
3240+
for gRPC version 1.6 and above.
32393241
source_path: instrumentation/grpc-1.6
32403242
scope:
32413243
name: io.opentelemetry.grpc-1.6
@@ -3244,6 +3246,182 @@ libraries:
32443246
- io.grpc:grpc-core:[1.6.0,)
32453247
library:
32463248
- io.grpc:grpc-core:1.6.0
3249+
configurations:
3250+
- name: otel.instrumentation.grpc.emit-message-events
3251+
description: Determines whether to emit a span event for each individual message
3252+
received and sent.
3253+
type: boolean
3254+
default: true
3255+
- name: otel.instrumentation.grpc.experimental-span-attributes
3256+
description: |
3257+
Enable the capture of experimental span attributes `grpc.received.message_count`, `grpc.sent.message_count` and `grpc.canceled`.
3258+
type: boolean
3259+
default: false
3260+
- name: otel.instrumentation.grpc.capture-metadata.client.request
3261+
description: |
3262+
A comma-separated list of request metadata keys. gRPC client instrumentation will capture metadata values corresponding to configured keys as span attributes.
3263+
type: list
3264+
default: ''
3265+
- name: otel.instrumentation.grpc.capture-metadata.server.request
3266+
description: |
3267+
A comma-separated list of request metadata keys. gRPC server instrumentation will capture metadata values corresponding to configured keys as span attributes.
3268+
type: list
3269+
default: ''
3270+
telemetry:
3271+
- when: default
3272+
metrics:
3273+
- name: rpc.client.duration
3274+
description: The duration of an outbound RPC invocation.
3275+
type: HISTOGRAM
3276+
unit: ms
3277+
attributes:
3278+
- name: rpc.grpc.status_code
3279+
type: LONG
3280+
- name: rpc.method
3281+
type: STRING
3282+
- name: rpc.service
3283+
type: STRING
3284+
- name: rpc.system
3285+
type: STRING
3286+
- name: server.address
3287+
type: STRING
3288+
- name: server.port
3289+
type: LONG
3290+
- name: rpc.server.duration
3291+
description: The duration of an inbound RPC invocation.
3292+
type: HISTOGRAM
3293+
unit: ms
3294+
attributes:
3295+
- name: network.type
3296+
type: STRING
3297+
- name: rpc.grpc.status_code
3298+
type: LONG
3299+
- name: rpc.method
3300+
type: STRING
3301+
- name: rpc.service
3302+
type: STRING
3303+
- name: rpc.system
3304+
type: STRING
3305+
- name: server.address
3306+
type: STRING
3307+
- name: server.port
3308+
type: LONG
3309+
spans:
3310+
- span_kind: CLIENT
3311+
attributes:
3312+
- name: rpc.grpc.status_code
3313+
type: LONG
3314+
- name: rpc.method
3315+
type: STRING
3316+
- name: rpc.service
3317+
type: STRING
3318+
- name: rpc.system
3319+
type: STRING
3320+
- name: server.address
3321+
type: STRING
3322+
- name: server.port
3323+
type: LONG
3324+
- span_kind: SERVER
3325+
attributes:
3326+
- name: network.peer.address
3327+
type: STRING
3328+
- name: network.peer.port
3329+
type: LONG
3330+
- name: network.type
3331+
type: STRING
3332+
- name: rpc.grpc.status_code
3333+
type: LONG
3334+
- name: rpc.method
3335+
type: STRING
3336+
- name: rpc.service
3337+
type: STRING
3338+
- name: rpc.system
3339+
type: STRING
3340+
- name: server.address
3341+
type: STRING
3342+
- name: server.port
3343+
type: LONG
3344+
- when: otel.instrumentation.grpc.experimental-span-attributes=true
3345+
metrics:
3346+
- name: rpc.client.duration
3347+
description: The duration of an outbound RPC invocation.
3348+
type: HISTOGRAM
3349+
unit: ms
3350+
attributes:
3351+
- name: rpc.grpc.status_code
3352+
type: LONG
3353+
- name: rpc.method
3354+
type: STRING
3355+
- name: rpc.service
3356+
type: STRING
3357+
- name: rpc.system
3358+
type: STRING
3359+
- name: server.address
3360+
type: STRING
3361+
- name: server.port
3362+
type: LONG
3363+
- name: rpc.server.duration
3364+
description: The duration of an inbound RPC invocation.
3365+
type: HISTOGRAM
3366+
unit: ms
3367+
attributes:
3368+
- name: network.type
3369+
type: STRING
3370+
- name: rpc.grpc.status_code
3371+
type: LONG
3372+
- name: rpc.method
3373+
type: STRING
3374+
- name: rpc.service
3375+
type: STRING
3376+
- name: rpc.system
3377+
type: STRING
3378+
- name: server.address
3379+
type: STRING
3380+
- name: server.port
3381+
type: LONG
3382+
spans:
3383+
- span_kind: CLIENT
3384+
attributes:
3385+
- name: grpc.received.message_count
3386+
type: LONG
3387+
- name: grpc.sent.message_count
3388+
type: LONG
3389+
- name: rpc.grpc.status_code
3390+
type: LONG
3391+
- name: rpc.method
3392+
type: STRING
3393+
- name: rpc.service
3394+
type: STRING
3395+
- name: rpc.system
3396+
type: STRING
3397+
- name: server.address
3398+
type: STRING
3399+
- name: server.port
3400+
type: LONG
3401+
- span_kind: SERVER
3402+
attributes:
3403+
- name: grpc.received.message_count
3404+
type: LONG
3405+
- name: grpc.sent.message_count
3406+
type: LONG
3407+
- name: network.peer.address
3408+
type: STRING
3409+
- name: network.peer.port
3410+
type: LONG
3411+
- name: network.type
3412+
type: STRING
3413+
- name: rpc.grpc.status_code
3414+
type: LONG
3415+
- name: rpc.method
3416+
type: STRING
3417+
- name: rpc.service
3418+
type: STRING
3419+
- name: rpc.system
3420+
type: STRING
3421+
- name: server.address
3422+
type: STRING
3423+
- name: server.port
3424+
type: LONG
32473425
guava:
32483426
- name: guava-10.0
32493427
source_path: instrumentation/guava-10.0

instrumentation-docs/instrumentations.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ readonly INSTRUMENTATIONS=(
141141
"graphql-java:graphql-java-12.0:javaagent:test"
142142
"graphql-java:graphql-java-20.0:javaagent:test"
143143
"graphql-java:graphql-java-20.0:javaagent:testDataFetcher"
144+
"grpc-1.6:javaagent:test"
145+
"grpc-1.6:javaagent:testExperimental"
144146
)
145147

146148
# Some instrumentation test suites don't run ARM, so we use colima to run them in an x86_64

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/SpanParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class SpanParser {
2525

2626
// We want to ignore test related attributes
2727
private static final List<String> EXCLUDED_ATTRIBUTES =
28-
List.of("x-test-", "test-baggage-", "test_message");
28+
List.of("x-test-", "test-baggage-", "test_message", "some-client-key", "some-server-key");
2929

3030
/**
3131
* Pull spans from the `.telemetry` directory, filter them by scope, and set them in the module.

instrumentation/grpc-1.6/javaagent/build.gradle.kts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ dependencies {
2828
testImplementation(project(":instrumentation:grpc-1.6:testing"))
2929
}
3030

31+
val collectMetadata = findProperty("collectMetadata")?.toString() ?: "false"
32+
3133
tasks {
3234
test {
3335
systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean)
@@ -46,6 +48,34 @@ tasks {
4648
classpath = classpath.filter {
4749
!it.absolutePath.contains("opentelemetry-grpc-1.6")
4850
}
51+
52+
systemProperty("collectMetadata", collectMetadata)
53+
}
54+
55+
val testExperimental by registering(Test::class) {
56+
testClassesDirs = sourceSets.test.get().output.classesDirs
57+
classpath = sourceSets.test.get().runtimeClasspath
58+
59+
// replicated base config from standard test task
60+
systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean)
61+
jvmArgs("-Dotel.javaagent.experimental.thread-propagation-debugger.enabled=false")
62+
jvmArgs("-Dotel.instrumentation.grpc.capture-metadata.client.request=some-client-key")
63+
jvmArgs("-Dotel.instrumentation.grpc.capture-metadata.server.request=some-server-key")
64+
jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true")
65+
66+
// exclude our grpc library instrumentation, the ContextStorageOverride contained within it
67+
// breaks the tests
68+
classpath = classpath.filter {
69+
!it.absolutePath.contains("opentelemetry-grpc-1.6")
70+
}
71+
72+
systemProperty("collectMetadata", collectMetadata)
73+
systemProperty("metadataConfig", "otel.instrumentation.grpc.experimental-span-attributes=true")
74+
jvmArgs("-Dotel.instrumentation.grpc.experimental-span-attributes=true")
75+
}
76+
77+
check {
78+
dependsOn(testExperimental)
4979
}
5080
}
5181

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
description: This instrumentation enables RPC CLIENT and SERVER spans and metrics for gRPC version 1.6 and above.
2+
configurations:
3+
- name: otel.instrumentation.grpc.emit-message-events
4+
type: boolean
5+
description: Determines whether to emit a span event for each individual message received and sent.
6+
default: true
7+
- name: otel.instrumentation.grpc.experimental-span-attributes
8+
type: boolean
9+
description: >
10+
Enable the capture of experimental span attributes `grpc.received.message_count`,
11+
`grpc.sent.message_count` and `grpc.canceled`.
12+
default: false
13+
- name: otel.instrumentation.grpc.capture-metadata.client.request
14+
type: list
15+
description: >
16+
A comma-separated list of request metadata keys. gRPC client instrumentation will capture
17+
metadata values corresponding to configured keys as span attributes.
18+
default: ''
19+
- name: otel.instrumentation.grpc.capture-metadata.server.request
20+
type: list
21+
description: >
22+
A comma-separated list of request metadata keys. gRPC server instrumentation will capture
23+
metadata values corresponding to configured keys as span attributes.
24+
default: ''

instrumentation/grpc-1.6/testing/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
package io.opentelemetry.instrumentation.grpc.v1_6;
77

88
import static io.opentelemetry.instrumentation.grpc.v1_6.AbstractGrpcTest.addExtraClientAttributes;
9+
import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.GRPC_RECEIVED_MESSAGE_COUNT;
10+
import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.GRPC_SENT_MESSAGE_COUNT;
11+
import static io.opentelemetry.instrumentation.grpc.v1_6.ExperimentalTestHelper.experimentalSatisfies;
912
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
1013
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
1114
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
@@ -223,6 +226,12 @@ public void onCompleted() {
223226
.hasNoParent()
224227
.hasAttributesSatisfyingExactly(
225228
addExtraClientAttributes(
229+
experimentalSatisfies(
230+
GRPC_RECEIVED_MESSAGE_COUNT,
231+
v -> assertThat(v).isGreaterThan(0)),
232+
experimentalSatisfies(
233+
GRPC_SENT_MESSAGE_COUNT,
234+
v -> assertThat(v).isGreaterThan(0)),
226235
equalTo(RPC_SYSTEM, "grpc"),
227236
equalTo(RPC_SERVICE, "example.Greeter"),
228237
equalTo(RPC_METHOD, "Conversation"),
@@ -238,6 +247,11 @@ public void onCompleted() {
238247
.hasKind(SpanKind.SERVER)
239248
.hasParent(trace.getSpan(0))
240249
.hasAttributesSatisfyingExactly(
250+
experimentalSatisfies(
251+
GRPC_RECEIVED_MESSAGE_COUNT,
252+
v -> assertThat(v).isGreaterThan(0)),
253+
experimentalSatisfies(
254+
GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)),
241255
equalTo(RPC_SYSTEM, "grpc"),
242256
equalTo(RPC_SERVICE, "example.Greeter"),
243257
equalTo(RPC_METHOD, "Conversation"),
@@ -246,6 +260,11 @@ public void onCompleted() {
246260
equalTo(SERVER_PORT, server.getPort()),
247261
equalTo(NETWORK_TYPE, "ipv4"),
248262
equalTo(NETWORK_PEER_ADDRESS, "127.0.0.1"),
263+
experimentalSatisfies(
264+
GRPC_RECEIVED_MESSAGE_COUNT,
265+
v -> assertThat(v).isGreaterThan(0)),
266+
experimentalSatisfies(
267+
GRPC_SENT_MESSAGE_COUNT, v -> assertThat(v).isGreaterThan(0)),
249268
satisfies(NETWORK_PEER_PORT, val -> val.isNotNull()))
250269
.satisfies(
251270
spanData ->

0 commit comments

Comments
 (0)