-
Notifications
You must be signed in to change notification settings - Fork 860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gRPC support request/response size #11833
base: main
Are you sure you want to change the base?
Changes from 25 commits
425c17f
29259dc
06aa680
7960777
e8948d8
7954240
ef9b84e
d063d33
30f7c9c
9dff355
7fe3980
5c455e8
5c7f329
1b3ff26
38fc1c3
330f9f3
0dd479b
4bf7656
9d0f339
a3251af
3f8c53c
5048258
59adfd6
409a8d4
5084309
6676d78
4f69c46
360f658
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.api.incubator.semconv.rpc; | ||
|
||
import io.opentelemetry.api.common.AttributeKey; | ||
import io.opentelemetry.api.common.Attributes; | ||
import javax.annotation.Nullable; | ||
|
||
final class RpcMessageBodySizeUtil { | ||
|
||
@Nullable | ||
static Long getRpcClientRequestBodySize(Attributes... attributesList) { | ||
return getAttribute(RpcCommonAttributesExtractor.RPC_CLIENT_REQUEST_BODY_SIZE, attributesList); | ||
} | ||
|
||
@Nullable | ||
static Long getRpcClientResponseBodySize(Attributes... attributesList) { | ||
return getAttribute(RpcCommonAttributesExtractor.RPC_CLIENT_RESPONSE_BODY_SIZE, attributesList); | ||
} | ||
|
||
@Nullable | ||
static Long getRpcServerRequestBodySize(Attributes... attributesList) { | ||
return getAttribute(RpcCommonAttributesExtractor.RPC_SERVER_REQUEST_BODY_SIZE, attributesList); | ||
} | ||
|
||
@Nullable | ||
static Long getRpcServerResponseBodySize(Attributes... attributesList) { | ||
return getAttribute(RpcCommonAttributesExtractor.RPC_SERVER_RESPONSE_BODY_SIZE, attributesList); | ||
} | ||
|
||
@Nullable | ||
private static <T> T getAttribute(AttributeKey<T> key, Attributes... attributesList) { | ||
for (Attributes attributes : attributesList) { | ||
T value = attributes.get(key); | ||
if (value != null) { | ||
return value; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private RpcMessageBodySizeUtil() {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,15 @@ | |
|
||
package io.opentelemetry.instrumentation.api.incubator.semconv.rpc; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
import io.opentelemetry.api.common.AttributeKey; | ||
import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder; | ||
import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder; | ||
import io.opentelemetry.api.metrics.DoubleHistogramBuilder; | ||
import io.opentelemetry.api.metrics.LongHistogramBuilder; | ||
import io.opentelemetry.semconv.NetworkAttributes; | ||
import io.opentelemetry.semconv.ServerAttributes; | ||
import java.util.Arrays; | ||
|
||
final class RpcMetricsAdvice { | ||
|
||
|
@@ -26,7 +29,7 @@ static void applyClientDurationAdvice(DoubleHistogramBuilder builder) { | |
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md | ||
((ExtendedDoubleHistogramBuilder) builder) | ||
.setAttributesAdvice( | ||
Arrays.asList( | ||
asList( | ||
RpcCommonAttributesExtractor.RPC_SYSTEM, | ||
RpcCommonAttributesExtractor.RPC_SERVICE, | ||
RpcCommonAttributesExtractor.RPC_METHOD, | ||
|
@@ -45,7 +48,45 @@ static void applyServerDurationAdvice(DoubleHistogramBuilder builder) { | |
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md | ||
((ExtendedDoubleHistogramBuilder) builder) | ||
.setAttributesAdvice( | ||
Arrays.asList( | ||
asList( | ||
RpcCommonAttributesExtractor.RPC_SYSTEM, | ||
RpcCommonAttributesExtractor.RPC_SERVICE, | ||
RpcCommonAttributesExtractor.RPC_METHOD, | ||
RPC_GRPC_STATUS_CODE, | ||
NetworkAttributes.NETWORK_TYPE, | ||
NetworkAttributes.NETWORK_TRANSPORT, | ||
ServerAttributes.SERVER_ADDRESS, | ||
ServerAttributes.SERVER_PORT)); | ||
} | ||
|
||
static void applyClientRequestSizeAdvice(LongHistogramBuilder builder) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as you are always going to use the same set of attributes you could make all these delegate to a common method or extract the attributes list to a variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
if (!(builder instanceof ExtendedLongHistogramBuilder)) { | ||
return; | ||
} | ||
// the list of recommended metrics attributes is from | ||
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md | ||
((ExtendedLongHistogramBuilder) builder) | ||
.setAttributesAdvice( | ||
asList( | ||
RpcCommonAttributesExtractor.RPC_SYSTEM, | ||
RpcCommonAttributesExtractor.RPC_SERVICE, | ||
RpcCommonAttributesExtractor.RPC_METHOD, | ||
RPC_GRPC_STATUS_CODE, | ||
NetworkAttributes.NETWORK_TYPE, | ||
NetworkAttributes.NETWORK_TRANSPORT, | ||
ServerAttributes.SERVER_ADDRESS, | ||
ServerAttributes.SERVER_PORT)); | ||
} | ||
|
||
static void applyServerRequestSizeAdvice(LongHistogramBuilder builder) { | ||
if (!(builder instanceof ExtendedLongHistogramBuilder)) { | ||
return; | ||
} | ||
// the list of recommended metrics attributes is from | ||
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md | ||
((ExtendedLongHistogramBuilder) builder) | ||
.setAttributesAdvice( | ||
asList( | ||
RpcCommonAttributesExtractor.RPC_SYSTEM, | ||
RpcCommonAttributesExtractor.RPC_SERVICE, | ||
RpcCommonAttributesExtractor.RPC_METHOD, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,8 @@ | |
import io.opentelemetry.api.common.Attributes; | ||
import io.opentelemetry.api.metrics.DoubleHistogram; | ||
import io.opentelemetry.api.metrics.DoubleHistogramBuilder; | ||
import io.opentelemetry.api.metrics.LongHistogram; | ||
import io.opentelemetry.api.metrics.LongHistogramBuilder; | ||
import io.opentelemetry.api.metrics.Meter; | ||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.context.ContextKey; | ||
|
@@ -35,6 +37,8 @@ public final class RpcServerMetrics implements OperationListener { | |
private static final Logger logger = Logger.getLogger(RpcServerMetrics.class.getName()); | ||
|
||
private final DoubleHistogram serverDurationHistogram; | ||
private final LongHistogram serverRequestSize; | ||
private final LongHistogram serverResponseSize; | ||
|
||
private RpcServerMetrics(Meter meter) { | ||
DoubleHistogramBuilder durationBuilder = | ||
|
@@ -44,6 +48,24 @@ private RpcServerMetrics(Meter meter) { | |
.setUnit("ms"); | ||
RpcMetricsAdvice.applyServerDurationAdvice(durationBuilder); | ||
serverDurationHistogram = durationBuilder.build(); | ||
|
||
LongHistogramBuilder requestSizeBuilder = | ||
meter | ||
.histogramBuilder("rpc.server.request.size") | ||
.setUnit("By") | ||
.setDescription("Measures the size of RPC request messages (uncompressed).") | ||
.ofLongs(); | ||
RpcMetricsAdvice.applyServerRequestSizeAdvice(requestSizeBuilder); | ||
serverRequestSize = requestSizeBuilder.build(); | ||
|
||
LongHistogramBuilder responseSizeBuilder = | ||
meter | ||
.histogramBuilder("rpc.server.response.size") | ||
.setUnit("By") | ||
.setDescription("Measures the size of RPC response messages (uncompressed).") | ||
.ofLongs(); | ||
RpcMetricsAdvice.applyServerRequestSizeAdvice(responseSizeBuilder); | ||
serverResponseSize = responseSizeBuilder.build(); | ||
} | ||
|
||
/** | ||
|
@@ -72,10 +94,21 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) { | |
context); | ||
return; | ||
} | ||
Attributes attributes = state.startAttributes().toBuilder().putAll(endAttributes).build(); | ||
serverDurationHistogram.record( | ||
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, | ||
state.startAttributes().toBuilder().putAll(endAttributes).build(), | ||
context); | ||
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, attributes, context); | ||
|
||
Long rpcServerRequestBodySize = | ||
RpcMessageBodySizeUtil.getRpcServerRequestBodySize(endAttributes, state.startAttributes()); | ||
if (rpcServerRequestBodySize != null && rpcServerRequestBodySize > 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
serverRequestSize.record(rpcServerRequestBodySize, attributes, context); | ||
} | ||
|
||
Long rpcServerResponseBodySize = | ||
RpcMessageBodySizeUtil.getRpcServerResponseBodySize(endAttributes, state.startAttributes()); | ||
if (rpcServerResponseBodySize != null && rpcServerResponseBodySize > 0) { | ||
serverResponseSize.record(rpcServerResponseBodySize, attributes, context); | ||
} | ||
} | ||
|
||
@AutoValue | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the type for these should be
Long
, and these should returnnull
by default. We need to consider whether this should be split into separate client/server getters similarly to what we do for http client/server. Would it make sense to introduce a response parameter too? Or perhaps just havegetRequestSize
andgetResponseSize
in the getter, we already have separate extractors for client/server these could be used to set the correct attribute.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank for your suggestion, Done.