Skip to content

Commit 68a9c42

Browse files
committed
Capture gRPC UNKNOWN requests
1 parent 559882a commit 68a9c42

18 files changed

Lines changed: 349 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Unreleased
44

5+
### ⚠️ Breaking changes to non-stable APIs
6+
7+
- `GrpcRequest.getMethod()` now returns `@Nullable` to support unregistered-service requests where
8+
no `MethodDescriptor` is available
9+
([#16214](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/16214))
10+
511
## Version 2.25.0 (2026-02-13)
612

713
### ⚠️ Breaking changes to non-stable APIs

instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/rpc/RpcAttributesGetter.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ default String getRpcMethod(REQUEST request) {
6868
return null;
6969
}
7070

71+
/**
72+
* Returns the original method name when the method reported via {@link #getRpcMethod(REQUEST)} is
73+
* set to {@code _OTHER} because the method is not recognized by the RPC framework.
74+
*/
75+
@Nullable
76+
default String getRpcMethodOriginal(REQUEST request) {
77+
return null;
78+
}
79+
7180
/**
7281
* Returns a description of a class of error the operation ended with.
7382
*

instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/rpc/RpcCommonAttributesExtractor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ abstract class RpcCommonAttributesExtractor<REQUEST, RESPONSE>
1919
implements AttributesExtractor<REQUEST, RESPONSE> {
2020

2121
static final AttributeKey<String> RPC_METHOD = AttributeKey.stringKey("rpc.method");
22+
static final AttributeKey<String> RPC_METHOD_ORIGINAL =
23+
AttributeKey.stringKey("rpc.method_original");
2224

2325
// Stable semconv keys
2426
static final AttributeKey<String> RPC_SYSTEM_NAME = AttributeKey.stringKey("rpc.system.name");
@@ -42,6 +44,7 @@ public final void onStart(AttributesBuilder attributes, Context parentContext, R
4244
if (emitStableRpcSemconv()) {
4345
attributes.put(RPC_SYSTEM_NAME, getter.getRpcSystemName(request));
4446
attributes.put(RPC_METHOD, getter.getRpcMethod(request));
47+
attributes.put(RPC_METHOD_ORIGINAL, getter.getRpcMethodOriginal(request));
4548
}
4649

4750
if (emitOldRpcSemconv()) {

instrumentation/armeria/armeria-grpc-1.14/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/grpc/v1_14/ArmeriaGrpcServiceBuilderInstrumentation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.linecorp.armeria.server.grpc.GrpcServiceBuilder;
1313
import io.opentelemetry.api.GlobalOpenTelemetry;
1414
import io.opentelemetry.instrumentation.grpc.v1_6.GrpcTelemetry;
15+
import io.opentelemetry.instrumentation.grpc.v1_6.internal.Internal;
1516
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1617
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1718
import net.bytebuddy.asm.Advice;
@@ -36,7 +37,8 @@ public static class BuildAdvice {
3637

3738
@Advice.OnMethodEnter
3839
public static void onEnter(@Advice.This GrpcServiceBuilder builder) {
39-
builder.intercept(GrpcTelemetry.create(GlobalOpenTelemetry.get()).createServerInterceptor());
40+
GrpcTelemetry telemetry = GrpcTelemetry.create(GlobalOpenTelemetry.get());
41+
builder.intercept(Internal.createServerInterceptor(telemetry));
4042
}
4143
}
4244
}

instrumentation/grpc-1.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/grpc/v1_6/GrpcServerBuilderInstrumentation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static CallDepth onEnter(@Advice.This ServerBuilder<?> serverBuilder) {
5050
return callDepth;
5151
}
5252
if (!Boolean.TRUE.equals(SERVER_BUILDER_INSTRUMENTED.get(serverBuilder))) {
53-
serverBuilder.intercept(GrpcSingletons.SERVER_INTERCEPTOR);
53+
GrpcSingletons.configureServerBuilder(serverBuilder);
5454
SERVER_BUILDER_INSTRUMENTED.set(serverBuilder, true);
5555
}
5656
return callDepth;

instrumentation/grpc-1.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/grpc/v1_6/GrpcSingletons.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import io.grpc.Context;
1212
import io.grpc.ManagedChannelBuilder;
1313
import io.grpc.ServerBuilder;
14-
import io.grpc.ServerInterceptor;
1514
import io.opentelemetry.api.GlobalOpenTelemetry;
1615
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
1716
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
@@ -33,7 +32,7 @@ public final class GrpcSingletons {
3332

3433
public static final ClientInterceptor CLIENT_INTERCEPTOR;
3534

36-
public static final ServerInterceptor SERVER_INTERCEPTOR;
35+
private static final GrpcTelemetry GRPC_TELEMETRY;
3736

3837
private static final AtomicReference<Context.Storage> STORAGE_REFERENCE = new AtomicReference<>();
3938

@@ -56,16 +55,15 @@ public final class GrpcSingletons {
5655
.get("server")
5756
.getScalarList("request", String.class, emptyList());
5857

59-
GrpcTelemetry telemetry =
58+
GRPC_TELEMETRY =
6059
GrpcTelemetry.builder(GlobalOpenTelemetry.get())
6160
.setEmitMessageEvents(emitMessageEvents)
6261
.setCaptureExperimentalSpanAttributes(experimentalSpanAttributes)
6362
.setCapturedClientRequestMetadata(clientRequestMetadata)
6463
.setCapturedServerRequestMetadata(serverRequestMetadata)
6564
.build();
6665

67-
CLIENT_INTERCEPTOR = telemetry.createClientInterceptor();
68-
SERVER_INTERCEPTOR = telemetry.createServerInterceptor();
66+
CLIENT_INTERCEPTOR = GRPC_TELEMETRY.createClientInterceptor();
6967
}
7068

7169
public static Context.Storage getStorage() {
@@ -77,5 +75,9 @@ public static Context.Storage setStorage(Context.Storage storage) {
7775
return getStorage();
7876
}
7977

78+
public static void configureServerBuilder(ServerBuilder<?> serverBuilder) {
79+
GRPC_TELEMETRY.configureServerBuilder(serverBuilder);
80+
}
81+
8082
private GrpcSingletons() {}
8183
}

instrumentation/grpc-1.6/library/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ void configureClientInterceptor(OpenTelemetry openTelemetry, NettyChannelBuilder
3737
nettyChannelBuilder.intercept(grpcTelemetry.createClientInterceptor());
3838
}
3939

40-
// For server-side, attatch the interceptor to your service.
41-
ServerServiceDefinition configureServerInterceptor(OpenTelemetry openTelemetry, ServerServiceDefinition serviceDefinition) {
40+
// For server-side, configure the server builder.
41+
void configureServer(OpenTelemetry openTelemetry, ServerBuilder<?> serverBuilder) {
4242
GrpcTelemetry grpcTelemetry = GrpcTelemetry.create(openTelemetry);
43-
return ServerInterceptors.intercept(serviceDefinition, grpcTelemetry.createServerInterceptor());
43+
grpcTelemetry.configureServerBuilder(serverBuilder);
4444
}
4545
```

instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcRequest.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
public final class GrpcRequest {
1414

15-
private final MethodDescriptor<?, ?> method;
15+
@Nullable private volatile MethodDescriptor<?, ?> method;
16+
private final String fullMethodName;
17+
@Nullable private final String originalFullMethodName;
1618

1719
@Nullable private volatile Metadata metadata;
1820

@@ -29,11 +31,19 @@ public final class GrpcRequest {
2931
@Nullable SocketAddress peerSocketAddress,
3032
@Nullable String authority) {
3133
this.method = method;
34+
this.fullMethodName = method.getFullMethodName();
35+
this.originalFullMethodName = null;
3236
this.metadata = metadata;
3337
this.peerSocketAddress = peerSocketAddress;
3438
setLogicalAddress(authority);
3539
}
3640

41+
GrpcRequest(String fullMethodName, @Nullable String originalFullMethodName, Metadata metadata) {
42+
this.fullMethodName = fullMethodName;
43+
this.originalFullMethodName = originalFullMethodName;
44+
this.metadata = metadata;
45+
}
46+
3747
private void setLogicalAddress(@Nullable String authority) {
3848
if (authority == null) {
3949
return;
@@ -51,10 +61,20 @@ private void setLogicalAddress(@Nullable String authority) {
5161
}
5262
}
5363

64+
@Nullable
5465
public MethodDescriptor<?, ?> getMethod() {
5566
return method;
5667
}
5768

69+
String getFullMethodName() {
70+
return fullMethodName;
71+
}
72+
73+
@Nullable
74+
String getOriginalFullMethodName() {
75+
return originalFullMethodName;
76+
}
77+
5878
@Nullable
5979
public Metadata getMetadata() {
6080
return metadata;

instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcRpcAttributesGetter.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public String getSystem(GrpcRequest request) {
2626
@Override
2727
@Nullable
2828
public String getService(GrpcRequest request) {
29-
String fullMethodName = request.getMethod().getFullMethodName();
29+
String fullMethodName = request.getFullMethodName();
3030
int slashIndex = fullMethodName.lastIndexOf('/');
3131
if (slashIndex == -1) {
3232
return null;
@@ -38,7 +38,7 @@ public String getService(GrpcRequest request) {
3838
@Override
3939
@Nullable
4040
public String getMethod(GrpcRequest request) {
41-
String fullMethodName = request.getMethod().getFullMethodName();
41+
String fullMethodName = request.getFullMethodName();
4242
int slashIndex = fullMethodName.lastIndexOf('/');
4343
if (slashIndex == -1) {
4444
return null;
@@ -47,8 +47,9 @@ public String getMethod(GrpcRequest request) {
4747
}
4848

4949
@Override
50+
@Nullable
5051
public String getRpcMethod(GrpcRequest request) {
51-
return request.getMethod().getFullMethodName();
52+
return request.getFullMethodName();
5253
}
5354

5455
@Override
@@ -63,6 +64,12 @@ public Long getResponseSize(GrpcRequest request) {
6364
return request.getResponseSize();
6465
}
6566

67+
@Override
68+
@Nullable
69+
public String getRpcMethodOriginal(GrpcRequest request) {
70+
return request.getOriginalFullMethodName();
71+
}
72+
6673
List<String> metadataValue(GrpcRequest request, String key) {
6774
if (request.getMetadata() == null) {
6875
return emptyList();

instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcSpanNameExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
final class GrpcSpanNameExtractor implements SpanNameExtractor<GrpcRequest> {
1212
@Override
1313
public String extract(GrpcRequest request) {
14-
return request.getMethod().getFullMethodName();
14+
return request.getFullMethodName();
1515
}
1616
}

0 commit comments

Comments
 (0)