Skip to content

Commit 61aa2e2

Browse files
committed
Capture gRPC UNKNOWN requests
1 parent bc8deee commit 61aa2e2

14 files changed

Lines changed: 258 additions & 9 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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public static CallDepth onEnter(@Advice.This ServerBuilder<?> serverBuilder) {
5151
}
5252
if (!Boolean.TRUE.equals(SERVER_BUILDER_INSTRUMENTED.get(serverBuilder))) {
5353
serverBuilder.intercept(GrpcSingletons.SERVER_INTERCEPTOR);
54+
serverBuilder.addStreamTracerFactory(GrpcSingletons.SERVER_STREAM_TRACER_FACTORY);
5455
SERVER_BUILDER_INSTRUMENTED.set(serverBuilder, true);
5556
}
5657
return callDepth;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.grpc.ManagedChannelBuilder;
1313
import io.grpc.ServerBuilder;
1414
import io.grpc.ServerInterceptor;
15+
import io.grpc.ServerStreamTracer;
1516
import io.opentelemetry.api.GlobalOpenTelemetry;
1617
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
1718
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
@@ -35,6 +36,8 @@ public final class GrpcSingletons {
3536

3637
public static final ServerInterceptor SERVER_INTERCEPTOR;
3738

39+
public static final ServerStreamTracer.Factory SERVER_STREAM_TRACER_FACTORY;
40+
3841
private static final AtomicReference<Context.Storage> STORAGE_REFERENCE = new AtomicReference<>();
3942

4043
static {
@@ -66,6 +69,7 @@ public final class GrpcSingletons {
6669

6770
CLIENT_INTERCEPTOR = telemetry.createClientInterceptor();
6871
SERVER_INTERCEPTOR = telemetry.createServerInterceptor();
72+
SERVER_STREAM_TRACER_FACTORY = telemetry.createServerStreamTracerFactory();
6973
}
7074

7175
public static Context.Storage getStorage() {

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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import io.grpc.ClientInterceptor;
99
import io.grpc.ServerInterceptor;
10+
import io.grpc.ServerStreamTracer;
1011
import io.grpc.Status;
1112
import io.opentelemetry.api.OpenTelemetry;
1213
import io.opentelemetry.context.propagation.ContextPropagators;
@@ -61,4 +62,14 @@ public ServerInterceptor createServerInterceptor() {
6162
return new TracingServerInterceptor(
6263
serverInstrumenter, captureExperimentalSpanAttributes, emitMessageEvents);
6364
}
65+
66+
/**
67+
* Returns a new {@link ServerStreamTracer.Factory} for use with methods like {@link
68+
* io.grpc.ServerBuilder#addStreamTracerFactory(ServerStreamTracer.Factory)}. This enables
69+
* creating server spans for requests to unregistered services, which are not seen by server
70+
* interceptors. Should be used together with {@link #createServerInterceptor()}.
71+
*/
72+
public ServerStreamTracer.Factory createServerStreamTracerFactory() {
73+
return new TracingServerStreamTracerFactory(serverInstrumenter, propagators);
74+
}
6475
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ public <REQUEST, RESPONSE> ServerCall.Listener<REQUEST> interceptCall(
7070
// field.
7171
authority = GrpcAuthorityStorage.getAuthority(call);
7272
}
73+
74+
// If a ServerStreamTracer is active, mark it as handled so it won't create a span for this
75+
// request in streamClosed().
76+
TracingServerStreamTracer streamTracer = TracingServerStreamTracer.STREAM_TRACER_KEY.get();
77+
if (streamTracer != null) {
78+
streamTracer.markInterceptorHandled();
79+
}
80+
7381
GrpcRequest request =
7482
new GrpcRequest(
7583
call.getMethodDescriptor(),

0 commit comments

Comments
 (0)