Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

### ⚠️ Breaking changes

- Rename `otel.instrumentation.grpc.{client,server}.request-metadata.{included,excluded}` to
`otel.instrumentation.grpc.{client,server}.request-headers.{included,excluded}`.
- Replace gRPC request metadata/header selectors with exact-name lists:
`otel.instrumentation.grpc.{client,server}.request-captured-headers`,
declarative `java.grpc.{client,server}.request_captured_headers`, and
`GrpcTelemetryBuilder.set{Client,Server}RequestCapturedHeaders(Collection<String>)`.
Wildcard and exclusion selection are no longer supported; unset or empty lists capture no headers.
- Captured gRPC request attributes now use `rpc.request.header.<key>` instead of
`rpc.request.metadata.<key>`.
- Rename `messaging.system` to `messaging.system.name` (`aws_sqs` becomes `aws.sqs`) and adopt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.instrumentation.config.bridge;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -191,6 +192,38 @@ void testComponentConfigDoesNotUseInstrumentationSpecialCases() {
.isNull();
}

@ParameterizedTest
@ValueSource(strings = {"client", "server"})
void testGrpcRequestCapturedHeadersMapping(String side) {
DeclarativeConfigProperties config =
createConfig(
"otel.instrumentation.grpc." + side + ".request-captured-headers",
"X-Request-Id,some-*-key,some-?-key");

assertThat(
config
.getStructured("java")
.getStructured("grpc")
.getStructured(side)
.getScalarList("request_captured_headers", String.class))
.containsExactly("X-Request-Id", "some-*-key", "some-?-key");
}

@ParameterizedTest
@ValueSource(strings = {"client", "server"})
void testGrpcRequestCapturedHeadersEmpty(String side) {
DeclarativeConfigProperties config =
createConfig("otel.instrumentation.grpc." + side + ".request-captured-headers", "");

assertThat(
config
.getStructured("java")
.getStructured("grpc")
.getStructured(side)
.getScalarList("request_captured_headers", String.class, emptyList()))
.isEmpty();
}

@Test
void testMessagingHeadersSelectorMapping() {
Map<String, String> properties = new HashMap<>();
Expand Down
32 changes: 8 additions & 24 deletions docs/declarative-configuration-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,10 @@ instrumentation/development:
enabled: false
grpc:
client:
request_headers:
# A comma-separated list of ASCII request header key patterns to exclude from client
# spans. Excluded patterns take precedence over included patterns. Matching is
# case-insensitive. `?` matches one character and `*` matches zero or more characters. If
# included is not configured, all non-excluded ASCII headers are captured, which may
# expose sensitive information.
excluded: []

# A comma-separated list of ASCII request header key patterns to capture on client spans.
# Matching is case-insensitive. `?` matches one character and `*` matches zero or more
# characters.
included: []
# A comma-separated list of ASCII request header names to capture on client spans. Matching
# is case-insensitive and exact; wildcards are not supported. No headers are captured when
# unset or empty.
request_captured_headers: []

# Determines whether to emit a span event for each individual message received and sent.
emit_message_events: true
Expand All @@ -275,18 +267,10 @@ instrumentation/development:
# `grpc.sent.message_count` and `grpc.canceled`.
experimental_span_attributes/development: false
server:
request_headers:
# A comma-separated list of ASCII request header key patterns to exclude from server
# spans. Excluded patterns take precedence over included patterns. Matching is
# case-insensitive. `?` matches one character and `*` matches zero or more characters. If
# included is not configured, all non-excluded ASCII headers are captured, which may
# expose sensitive information.
excluded: []

# A comma-separated list of ASCII request header key patterns to capture on server spans.
# Matching is case-insensitive. `?` matches one character and `*` matches zero or more
# characters.
included: []
# A comma-separated list of ASCII request header names to capture on server spans. Matching
# is case-insensitive and exact; wildcards are not supported. No headers are captured when
# unset or empty.
request_captured_headers: []
guava:
# Enables experimental span attribute `guava.canceled` for cancelled operations.
experimental_span_attributes/development: false
Expand Down
14 changes: 6 additions & 8 deletions instrumentation/grpc-1.6/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# Settings for the gRPC instrumentation

| System property | Type | Default | Description |
| ----------------------------------------------------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `otel.instrumentation.grpc.emit-message-events` | Boolean | `true` | Determines whether to emit span event for each individual message received and sent. |
| `otel.instrumentation.grpc.experimental-span-attributes` | Boolean | `false` | Enable the capture of experimental span attributes. |
| `otel.instrumentation.grpc.client.request-headers.included` | String | | A comma-separated list of ASCII request header key patterns to capture on client spans. Matching is case-insensitive. `?` matches one character and `*` matches zero or more characters. |
| `otel.instrumentation.grpc.client.request-headers.excluded` | String | | A comma-separated list of ASCII request header key patterns to exclude from client spans. Excluded patterns take precedence over included patterns. Matching is case-insensitive. `?` matches one character and `*` matches zero or more characters. If included is not configured, all non-excluded ASCII headers are captured, which may expose sensitive information. |
| `otel.instrumentation.grpc.server.request-headers.included` | String | | A comma-separated list of ASCII request header key patterns to capture on server spans. Matching is case-insensitive. `?` matches one character and `*` matches zero or more characters. |
| `otel.instrumentation.grpc.server.request-headers.excluded` | String | | A comma-separated list of ASCII request header key patterns to exclude from server spans. Excluded patterns take precedence over included patterns. Matching is case-insensitive. `?` matches one character and `*` matches zero or more characters. If included is not configured, all non-excluded ASCII headers are captured, which may expose sensitive information. |
| System property | Type | Default | Description |
| ----------------------------------------------------------- | ------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `otel.instrumentation.grpc.emit-message-events` | Boolean | `true` | Determines whether to emit span event for each individual message received and sent. |
| `otel.instrumentation.grpc.experimental-span-attributes` | Boolean | `false` | Enable the capture of experimental span attributes. |
| `otel.instrumentation.grpc.client.request-captured-headers` | String | | A comma-separated list of ASCII request header names to capture on client spans. Matching is case-insensitive and exact; wildcards are not supported. No headers are captured when unset or empty. |
| `otel.instrumentation.grpc.server.request-captured-headers` | String | | A comma-separated list of ASCII request header names to capture on server spans. Matching is case-insensitive and exact; wildcards are not supported. No headers are captured when unset or empty. |

Captured headers use `rpc.request.header.<key>`, with lowercase keys and string-array values.
Binary metadata and HTTP/2 pseudo-headers are not captured.
6 changes: 2 additions & 4 deletions instrumentation/grpc-1.6/javaagent/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ testing {
// The agent context debug mechanism isn't compatible with the bridge approach which may add a
// gRPC context to the root.
jvmArgs("-Dotel.javaagent.experimental.thread-propagation-debugger.enabled=false")
jvmArgs("-Dotel.instrumentation.grpc.client.request-headers.included=some-*-key")
jvmArgs("-Dotel.instrumentation.grpc.client.request-headers.excluded=*-excluded-key")
jvmArgs("-Dotel.instrumentation.grpc.server.request-headers.included=some-*-key")
jvmArgs("-Dotel.instrumentation.grpc.server.request-headers.excluded=*-excluded-key")
jvmArgs("-Dotel.instrumentation.grpc.client.request-captured-headers=SOME-CLIENT-KEY,*,some-*-key,some-?lient-key")
jvmArgs("-Dotel.instrumentation.grpc.server.request-captured-headers=SOME-SERVER-KEY,*,some-*-key,some-?erver-key")
// 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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.instrumentation.api.config.IncludeExclude;
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.instrumentation.grpc.v1_6.GrpcTelemetry;
import io.opentelemetry.instrumentation.grpc.v1_6.GrpcTelemetryBuilder;
import io.opentelemetry.instrumentation.grpc.v1_6.internal.ContextStorageBridge;
import io.opentelemetry.instrumentation.grpc.v1_6.internal.Experimental;
import io.opentelemetry.instrumentation.grpc.v1_6.internal.GrpcConfig;
Expand Down Expand Up @@ -46,20 +44,13 @@ public class GrpcSingletons {
boolean experimentalSpanAttributes =
config.getBoolean("experimental_span_attributes/development", false);

GrpcTelemetryBuilder telemetryBuilder =
telemetry =
GrpcTelemetry.builder(openTelemetry)
.setEmitMessageEvents(emitMessageEvents)
.setCaptureExperimentalSpanAttributes(experimentalSpanAttributes);
IncludeExclude clientRequestHeaders = grpcConfig.getClientRequestHeaders();
if (clientRequestHeaders != null) {
telemetryBuilder.setClientRequestHeaders(clientRequestHeaders);
}

IncludeExclude serverRequestHeaders = grpcConfig.getServerRequestHeaders();
if (serverRequestHeaders != null) {
telemetryBuilder.setServerRequestHeaders(serverRequestHeaders);
}
telemetry = telemetryBuilder.build();
.setCaptureExperimentalSpanAttributes(experimentalSpanAttributes)
.setClientRequestCapturedHeaders(grpcConfig.getClientRequestCapturedHeaders())
.setServerRequestCapturedHeaders(grpcConfig.getServerRequestCapturedHeaders())
.build();
}

@Nullable
Expand Down

This file was deleted.

Loading
Loading