Skip to content

Commit d2e67c0

Browse files
committed
Capture gRPC UNKNOWN requests
1 parent bc8deee commit d2e67c0

16 files changed

Lines changed: 270 additions & 20 deletions

File tree

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ default String getRpcMethod(REQUEST request) {
5151
return null;
5252
}
5353

54+
/**
55+
* Returns the original method name when the method reported via {@link #getRpcMethod(REQUEST)} is
56+
* {@code _OTHER}. This is used to populate the {@code rpc.method_original} attribute.
57+
*
58+
* @return the original method name, or null if the method was not replaced with {@code _OTHER}
59+
*/
60+
@Nullable
61+
default String getRpcMethodOriginal(REQUEST request) {
62+
return null;
63+
}
64+
5465
/**
5566
* Returns a description of a class of error the operation ended with.
5667
*

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
@@ -16,6 +16,8 @@ abstract class RpcCommonAttributesExtractor<REQUEST, RESPONSE>
1616

1717
// copied from RpcIncubatingAttributes
1818
static final AttributeKey<String> RPC_METHOD = AttributeKey.stringKey("rpc.method");
19+
static final AttributeKey<String> RPC_METHOD_ORIGINAL =
20+
AttributeKey.stringKey("rpc.method_original");
1921
static final AttributeKey<String> RPC_SERVICE = AttributeKey.stringKey("rpc.service");
2022
static final AttributeKey<String> RPC_SYSTEM = AttributeKey.stringKey("rpc.system");
2123

@@ -31,6 +33,7 @@ public final void onStart(AttributesBuilder attributes, Context parentContext, R
3133
attributes.put(RPC_SYSTEM, getter.getSystem(request));
3234
attributes.put(RPC_SERVICE, getter.getService(request));
3335
attributes.put(RPC_METHOD, getter.getMethod(request));
36+
attributes.put(RPC_METHOD_ORIGINAL, getter.getRpcMethodOriginal(request));
3437
}
3538

3639
@Override

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/GrpcAttributesExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class GrpcAttributesExtractor implements AttributesExtractor<GrpcRequest,
3333

3434
@Override
3535
public void onStart(AttributesBuilder attributes, Context parentContext, GrpcRequest request) {
36-
// Request attributes captured on request end.
36+
// Attributes captured on request end.
3737
}
3838

3939
@Override

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: 9 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,10 +38,10 @@ 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) {
44-
return null;
44+
return fullMethodName;
4545
}
4646
return fullMethodName.substring(slashIndex + 1);
4747
}
@@ -58,6 +58,12 @@ public Long getResponseSize(GrpcRequest request) {
5858
return request.getResponseSize();
5959
}
6060

61+
@Override
62+
@Nullable
63+
public String getRpcMethodOriginal(GrpcRequest request) {
64+
return request.getOriginalFullMethodName();
65+
}
66+
6167
List<String> metadataValue(GrpcRequest request, String key) {
6268
if (request.getMetadata() == null) {
6369
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
}

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

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

88
import io.grpc.ClientInterceptor;
9+
import io.grpc.ServerBuilder;
910
import io.grpc.ServerInterceptor;
1011
import io.grpc.Status;
1112
import io.opentelemetry.api.OpenTelemetry;
@@ -53,10 +54,25 @@ public ClientInterceptor createClientInterceptor() {
5354
clientInstrumenter, propagators, captureExperimentalSpanAttributes, emitMessageEvents);
5455
}
5556

57+
/**
58+
* Configures a {@link ServerBuilder} with both the server interceptor and the stream tracer
59+
* factory. The interceptor handles registered service methods, while the stream tracer factory
60+
* creates spans for requests to unregistered services that are not seen by server interceptors.
61+
*/
62+
public void configureServerBuilder(ServerBuilder<?> serverBuilder) {
63+
serverBuilder.intercept(createServerInterceptor());
64+
serverBuilder.addStreamTracerFactory(
65+
new TracingServerStreamTracerFactory(serverInstrumenter, propagators));
66+
}
67+
5668
/**
5769
* Returns a new {@link ServerInterceptor} for use with methods like {@link
5870
* io.grpc.ServerBuilder#intercept(ServerInterceptor)}.
71+
*
72+
* @deprecated Use {@link #configureServerBuilder(ServerBuilder)} instead, which also registers
73+
* the stream tracer factory needed to capture requests to unregistered services.
5974
*/
75+
@Deprecated
6076
public ServerInterceptor createServerInterceptor() {
6177
return new TracingServerInterceptor(
6278
serverInstrumenter, captureExperimentalSpanAttributes, emitMessageEvents);

0 commit comments

Comments
 (0)