Skip to content

Commit f4eca31

Browse files
committed
Merge remote-tracking branch 'upstream/main' into re-add-test-runtime-hints
2 parents 275a9e4 + 4345a77 commit f4eca31

File tree

13 files changed

+247
-90
lines changed

13 files changed

+247
-90
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public ArmeriaGrpcInstrumentationModule() {
2222
public List<TypeInstrumentation> typeInstrumentations() {
2323
return asList(
2424
new ArmeriaGrpcClientBuilderInstrumentation(),
25-
new ArmeriaGrpcServiceBuilderInstrumentation());
25+
new ArmeriaGrpcServiceBuilderInstrumentation(),
26+
new ArmeriaServerCallInstrumentation());
2627
}
2728
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.armeria.grpc.v1_14;
7+
8+
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
9+
import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
10+
11+
import com.linecorp.armeria.server.ServiceRequestContext;
12+
import io.grpc.ServerCall;
13+
import io.opentelemetry.instrumentation.api.util.VirtualField;
14+
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
15+
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
16+
import net.bytebuddy.asm.Advice;
17+
import net.bytebuddy.description.type.TypeDescription;
18+
import net.bytebuddy.matcher.ElementMatcher;
19+
20+
public class ArmeriaServerCallInstrumentation implements TypeInstrumentation {
21+
@Override
22+
public ElementMatcher<TypeDescription> typeMatcher() {
23+
return namedOneOf(
24+
"com.linecorp.armeria.server.grpc.ArmeriaServerCall",
25+
"com.linecorp.armeria.internal.server.grpc.AbstractServerCall");
26+
}
27+
28+
@Override
29+
public void transform(TypeTransformer transformer) {
30+
transformer.applyAdviceToMethod(
31+
isConstructor(), this.getClass().getName() + "$ConstructorAdvice");
32+
}
33+
34+
@SuppressWarnings("unused")
35+
public static class ConstructorAdvice {
36+
37+
@Advice.OnMethodExit(suppress = Throwable.class)
38+
public static void onExit(
39+
@Advice.This ServerCall<?, ?> serverCall,
40+
@Advice.FieldValue("ctx") ServiceRequestContext ctx) {
41+
String authority = ctx.request().headers().get(":authority");
42+
if (authority != null) {
43+
// ArmeriaServerCall does not implement getAuthority. We will store the value for authority
44+
// header as virtual field, this field is read in grpc instrumentation in
45+
// TracingServerInterceptor
46+
VirtualField.find(ServerCall.class, String.class).set(serverCall, authority);
47+
}
48+
}
49+
}
50+
}

instrumentation/armeria/armeria-grpc-1.14/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/grpc/v1_14/ArmeriaGrpcTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void grpcInstrumentation() {
9898
.hasAttributesSatisfyingExactly(
9999
equalTo(
100100
MessageIncubatingAttributes.MESSAGE_TYPE, "RECEIVED"),
101-
equalTo(MessageIncubatingAttributes.MESSAGE_ID, 2L))),
101+
equalTo(MessageIncubatingAttributes.MESSAGE_ID, 1L))),
102102
span ->
103103
span.hasName("example.Greeter/SayHello")
104104
.hasKind(SpanKind.SERVER)
@@ -123,6 +123,6 @@ void grpcInstrumentation() {
123123
.hasName("message")
124124
.hasAttributesSatisfyingExactly(
125125
equalTo(MessageIncubatingAttributes.MESSAGE_TYPE, "SENT"),
126-
equalTo(MessageIncubatingAttributes.MESSAGE_ID, 2L)))));
126+
equalTo(MessageIncubatingAttributes.MESSAGE_ID, 1L)))));
127127
}
128128
}

instrumentation/grpc-1.6/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
| System property | Type | Default | Description |
44
|-------------------------------------------------------------|---------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
5+
| `otel.instrumentation.grpc.emit-message-events` | Boolean | `true` | Determines whether to emit span event for each individual message received and sent. |
56
| `otel.instrumentation.grpc.experimental-span-attributes` | Boolean | `false` | Enable the capture of experimental span attributes. |
67
| `otel.instrumentation.grpc.capture-metadata.client.request` | String | | A comma-separated list of request metadata keys. gRPC client instrumentation will capture metadata values corresponding to configured keys as span attributes. |
78
| `otel.instrumentation.grpc.capture-metadata.server.request` | String | | A comma-separated list of request metadata keys. gRPC server instrumentation will capture metadata values corresponding to configured keys as span attributes. |

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

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public final class GrpcSingletons {
2727
private static final AtomicReference<Context.Storage> STORAGE_REFERENCE = new AtomicReference<>();
2828

2929
static {
30+
boolean emitMessageEvents =
31+
AgentInstrumentationConfig.get()
32+
.getBoolean("otel.instrumentation.grpc.emit-message-events", true);
33+
3034
boolean experimentalSpanAttributes =
3135
AgentInstrumentationConfig.get()
3236
.getBoolean("otel.instrumentation.grpc.experimental-span-attributes", false);
@@ -40,6 +44,7 @@ public final class GrpcSingletons {
4044

4145
GrpcTelemetry telemetry =
4246
GrpcTelemetry.builder(GlobalOpenTelemetry.get())
47+
.setEmitMessageEvents(emitMessageEvents)
4348
.setCaptureExperimentalSpanAttributes(experimentalSpanAttributes)
4449
.setCapturedClientRequestMetadata(clientRequestMetadata)
4550
.setCapturedServerRequestMetadata(serverRequestMetadata)

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,36 @@ public static GrpcTelemetryBuilder builder(OpenTelemetry openTelemetry) {
2929
private final Instrumenter<GrpcRequest, Status> clientInstrumenter;
3030
private final ContextPropagators propagators;
3131
private final boolean captureExperimentalSpanAttributes;
32+
private final boolean emitMessageEvents;
3233

3334
GrpcTelemetry(
3435
Instrumenter<GrpcRequest, Status> serverInstrumenter,
3536
Instrumenter<GrpcRequest, Status> clientInstrumenter,
3637
ContextPropagators propagators,
37-
boolean captureExperimentalSpanAttributes) {
38+
boolean captureExperimentalSpanAttributes,
39+
boolean emitMessageEvents) {
3840
this.serverInstrumenter = serverInstrumenter;
3941
this.clientInstrumenter = clientInstrumenter;
4042
this.propagators = propagators;
4143
this.captureExperimentalSpanAttributes = captureExperimentalSpanAttributes;
44+
this.emitMessageEvents = emitMessageEvents;
4245
}
4346

4447
/**
4548
* Returns a new {@link ClientInterceptor} for use with methods like {@link
4649
* io.grpc.ManagedChannelBuilder#intercept(ClientInterceptor...)}.
4750
*/
4851
public ClientInterceptor newClientInterceptor() {
49-
return new TracingClientInterceptor(clientInstrumenter, propagators);
52+
return new TracingClientInterceptor(
53+
clientInstrumenter, propagators, captureExperimentalSpanAttributes, emitMessageEvents);
5054
}
5155

5256
/**
5357
* Returns a new {@link ServerInterceptor} for use with methods like {@link
5458
* io.grpc.ServerBuilder#intercept(ServerInterceptor)}.
5559
*/
5660
public ServerInterceptor newServerInterceptor() {
57-
return new TracingServerInterceptor(serverInstrumenter, captureExperimentalSpanAttributes);
61+
return new TracingServerInterceptor(
62+
serverInstrumenter, captureExperimentalSpanAttributes, emitMessageEvents);
5863
}
5964
}

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public final class GrpcTelemetryBuilder {
4949
additionalServerExtractors = new ArrayList<>();
5050

5151
private boolean captureExperimentalSpanAttributes;
52+
private boolean emitMessageEvents = true;
5253
private List<String> capturedClientRequestMetadata = Collections.emptyList();
5354
private List<String> capturedServerRequestMetadata = Collections.emptyList();
5455

@@ -130,6 +131,16 @@ public GrpcTelemetryBuilder setPeerService(String peerService) {
130131
return this;
131132
}
132133

134+
/**
135+
* Determines whether to add span event for each individual message received and sent. The default
136+
* is true. Set this to false in case of streaming large volumes of messages.
137+
*/
138+
@CanIgnoreReturnValue
139+
public GrpcTelemetryBuilder setEmitMessageEvents(boolean emitMessageEvents) {
140+
this.emitMessageEvents = emitMessageEvents;
141+
return this;
142+
}
143+
133144
/**
134145
* Sets whether experimental attributes should be set to spans. These attributes may be changed or
135146
* removed in the future, so only enable this if you know you do not require attributes filled by
@@ -211,6 +222,7 @@ public GrpcTelemetry build() {
211222
// So we go ahead and inject manually in this instrumentation.
212223
clientInstrumenterBuilder.buildInstrumenter(SpanKindExtractor.alwaysClient()),
213224
openTelemetry.getPropagators(),
214-
captureExperimentalSpanAttributes);
225+
captureExperimentalSpanAttributes,
226+
emitMessageEvents);
215227
}
216228
}

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

+41-17
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
final class TracingClientInterceptor implements ClientInterceptor {
2828

29+
private static final AttributeKey<Long> GRPC_RECEIVED_MESSAGE_COUNT =
30+
AttributeKey.longKey("grpc.received.message_count");
31+
private static final AttributeKey<Long> GRPC_SENT_MESSAGE_COUNT =
32+
AttributeKey.longKey("grpc.sent.message_count");
2933
// copied from MessageIncubatingAttributes
3034
private static final AttributeKey<Long> MESSAGE_ID = AttributeKey.longKey("message.id");
3135
private static final AttributeKey<String> MESSAGE_TYPE = AttributeKey.stringKey("message.type");
@@ -34,16 +38,27 @@ final class TracingClientInterceptor implements ClientInterceptor {
3438
private static final String RECEIVED = "RECEIVED";
3539

3640
@SuppressWarnings("rawtypes")
37-
private static final AtomicLongFieldUpdater<TracingClientCall> MESSAGE_ID_UPDATER =
38-
AtomicLongFieldUpdater.newUpdater(TracingClientCall.class, "messageId");
41+
private static final AtomicLongFieldUpdater<TracingClientCall> SENT_MESSAGE_ID_UPDATER =
42+
AtomicLongFieldUpdater.newUpdater(TracingClientCall.class, "sentMessageId");
43+
44+
@SuppressWarnings("rawtypes")
45+
private static final AtomicLongFieldUpdater<TracingClientCall> RECEIVED_MESSAGE_ID_UPDATER =
46+
AtomicLongFieldUpdater.newUpdater(TracingClientCall.class, "receivedMessageId");
3947

4048
private final Instrumenter<GrpcRequest, Status> instrumenter;
4149
private final ContextPropagators propagators;
50+
private final boolean captureExperimentalSpanAttributes;
51+
private final boolean emitMessageEvents;
4252

4353
TracingClientInterceptor(
44-
Instrumenter<GrpcRequest, Status> instrumenter, ContextPropagators propagators) {
54+
Instrumenter<GrpcRequest, Status> instrumenter,
55+
ContextPropagators propagators,
56+
boolean captureExperimentalSpanAttributes,
57+
boolean emitMessageEvents) {
4558
this.instrumenter = instrumenter;
4659
this.propagators = propagators;
60+
this.captureExperimentalSpanAttributes = captureExperimentalSpanAttributes;
61+
this.emitMessageEvents = emitMessageEvents;
4762
}
4863

4964
@Override
@@ -75,9 +90,13 @@ final class TracingClientCall<REQUEST, RESPONSE>
7590
private final Context context;
7691
private final GrpcRequest request;
7792

78-
// Used by MESSAGE_ID_UPDATER
93+
// Used by SENT_MESSAGE_ID_UPDATER
94+
@SuppressWarnings("UnusedVariable")
95+
volatile long sentMessageId;
96+
97+
// Used by RECEIVED_MESSAGE_ID_UPDATER
7998
@SuppressWarnings("UnusedVariable")
80-
volatile long messageId;
99+
volatile long receivedMessageId;
81100

82101
TracingClientCall(
83102
ClientCall<REQUEST, RESPONSE> delegate,
@@ -113,10 +132,11 @@ public void sendMessage(REQUEST message) {
113132
instrumenter.end(context, request, Status.UNKNOWN, e);
114133
throw e;
115134
}
116-
Span span = Span.fromContext(context);
117-
Attributes attributes =
118-
Attributes.of(MESSAGE_TYPE, SENT, MESSAGE_ID, MESSAGE_ID_UPDATER.incrementAndGet(this));
119-
span.addEvent("message", attributes);
135+
long messageId = SENT_MESSAGE_ID_UPDATER.incrementAndGet(this);
136+
if (emitMessageEvents) {
137+
Attributes attributes = Attributes.of(MESSAGE_TYPE, SENT, MESSAGE_ID, messageId);
138+
Span.fromContext(context).addEvent("message", attributes);
139+
}
120140
}
121141

122142
final class TracingClientCallListener
@@ -139,14 +159,11 @@ final class TracingClientCallListener
139159

140160
@Override
141161
public void onMessage(RESPONSE message) {
142-
Span span = Span.fromContext(context);
143-
Attributes attributes =
144-
Attributes.of(
145-
MESSAGE_TYPE,
146-
RECEIVED,
147-
MESSAGE_ID,
148-
MESSAGE_ID_UPDATER.incrementAndGet(TracingClientCall.this));
149-
span.addEvent("message", attributes);
162+
long messageId = RECEIVED_MESSAGE_ID_UPDATER.incrementAndGet(TracingClientCall.this);
163+
if (emitMessageEvents) {
164+
Attributes attributes = Attributes.of(MESSAGE_TYPE, RECEIVED, MESSAGE_ID, messageId);
165+
Span.fromContext(context).addEvent("message", attributes);
166+
}
150167
try (Scope ignored = context.makeCurrent()) {
151168
delegate().onMessage(message);
152169
}
@@ -155,6 +172,13 @@ public void onMessage(RESPONSE message) {
155172
@Override
156173
public void onClose(Status status, Metadata trailers) {
157174
request.setPeerSocketAddress(getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR));
175+
if (captureExperimentalSpanAttributes) {
176+
Span span = Span.fromContext(context);
177+
span.setAttribute(
178+
GRPC_RECEIVED_MESSAGE_COUNT, RECEIVED_MESSAGE_ID_UPDATER.get(TracingClientCall.this));
179+
span.setAttribute(
180+
GRPC_SENT_MESSAGE_COUNT, SENT_MESSAGE_ID_UPDATER.get(TracingClientCall.this));
181+
}
158182
instrumenter.end(context, request, status, status.getCause());
159183
try (Scope ignored = parentContext.makeCurrent()) {
160184
delegate().onClose(status, trailers);

0 commit comments

Comments
 (0)