Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit 2e90f49

Browse files
implement gRPC client retry stats measures and views (#2084)
* implement gRPC client retry stats measures and views based on https://github.com/grpc/proposal/blob/master/A45-retry-stats.md#metrics-to-expose * fix aggregation arguments for new RpcViewConstants * attempt to fix checkstyle * add more sensible bucket boundaries for retry per call histograms * remove extraneous buckets and make >= 5 the upper bound * apply fix pointed out by @asafdav2
1 parent 81225af commit 2e90f49

File tree

6 files changed

+157
-2
lines changed

6 files changed

+157
-2
lines changed

contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcMeasureConstants.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,37 @@ public final class RpcMeasureConstants {
227227
Measure.MeasureLong.create(
228228
"grpc.io/client/started_rpcs", "Number of started client RPCs.", COUNT);
229229

230+
/**
231+
* {@link Measure} for total number of retry or hedging attempts excluding transparent retries
232+
* made during the client call.
233+
*
234+
* @since 0.31.0
235+
*/
236+
public static final MeasureLong GRPC_CLIENT_RETRIES_PER_CALL =
237+
Measure.MeasureLong.create(
238+
"grpc.io/client/retries_per_call", "Number of retries per call.", COUNT);
239+
240+
/**
241+
* {@link Measure} for total number of transparent retries made during the client call.
242+
*
243+
* @since 0.28
244+
*/
245+
public static final MeasureLong GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL =
246+
Measure.MeasureLong.create(
247+
"grpc.io/client/transparent_retries_per_call",
248+
"Number of transparent retries per call.",
249+
COUNT);
250+
251+
/**
252+
* {@link Measure} for total time of delay while there is no active attempt during the client
253+
* call.
254+
*
255+
* @since 0.28
256+
*/
257+
public static final MeasureLong GRPC_CLIENT_RETRY_DELAY_PER_CALL =
258+
Measure.MeasureLong.create(
259+
"grpc.io/client/retry_delay_per_call", "Retry delay per call.", MILLISECOND);
260+
230261
/**
231262
* {@link Measure} for gRPC client error counts.
232263
*

contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcViewConstants.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_RECEIVED_BYTES_PER_RPC;
2222
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_RECEIVED_MESSAGES_PER_METHOD;
2323
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_RECEIVED_MESSAGES_PER_RPC;
24+
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_RETRIES_PER_CALL;
25+
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_RETRY_DELAY_PER_CALL;
2426
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_ROUNDTRIP_LATENCY;
2527
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_SENT_BYTES_PER_METHOD;
2628
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_SENT_BYTES_PER_RPC;
@@ -29,6 +31,7 @@
2931
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_SERVER_LATENCY;
3032
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_STARTED_RPCS;
3133
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_STATUS;
34+
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL;
3235
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_SERVER_METHOD;
3336
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_SERVER_RECEIVED_BYTES_PER_METHOD;
3437
import static io.opencensus.contrib.grpc.metrics.RpcMeasureConstants.GRPC_SERVER_RECEIVED_BYTES_PER_RPC;
@@ -131,6 +134,10 @@ public final class RpcViewConstants {
131134
0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0,
132135
4096.0, 8192.0, 16384.0, 32768.0, 65536.0));
133136

137+
@VisibleForTesting
138+
static final List<Double> RETRY_COUNT_PER_CALL_BUCKET_BOUNDARIES =
139+
Collections.unmodifiableList(Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0));
140+
134141
// Use Aggregation.Mean to record sum and count stats at the same time.
135142
@VisibleForTesting static final Aggregation MEAN = Aggregation.Mean.create();
136143
@VisibleForTesting static final Aggregation COUNT = Count.create();
@@ -151,6 +158,10 @@ public final class RpcViewConstants {
151158
static final Aggregation AGGREGATION_WITH_COUNT_HISTOGRAM =
152159
Distribution.create(BucketBoundaries.create(RPC_COUNT_BUCKET_BOUNDARIES));
153160

161+
@VisibleForTesting
162+
static final Aggregation AGGREGATION_WITH_COUNT_RETRY_HISTOGRAM =
163+
Distribution.create(BucketBoundaries.create(RETRY_COUNT_PER_CALL_BUCKET_BOUNDARIES));
164+
154165
@VisibleForTesting static final Duration MINUTE = Duration.create(60, 0);
155166
@VisibleForTesting static final Duration HOUR = Duration.create(60 * 60, 0);
156167

@@ -502,6 +513,71 @@ public final class RpcViewConstants {
502513
COUNT,
503514
Arrays.asList(GRPC_CLIENT_METHOD));
504515

516+
/**
517+
* {@link View} for client retries per call.
518+
*
519+
* @since 0.28
520+
*/
521+
public static final View GRPC_CLIENT_RETRIES_PER_CALL_VIEW =
522+
View.create(
523+
View.Name.create("grpc.io/client/retries_per_call"),
524+
"Number of client retries per call",
525+
GRPC_CLIENT_RETRIES_PER_CALL,
526+
AGGREGATION_WITH_COUNT_RETRY_HISTOGRAM,
527+
Arrays.asList(GRPC_CLIENT_METHOD));
528+
529+
/**
530+
* {@link View} for total transparent client retries across calls.
531+
*
532+
* @since 0.28
533+
*/
534+
public static final View GRPC_CLIENT_TRANSPARENT_RETRIES_VIEW =
535+
View.create(
536+
View.Name.create("grpc.io/client/transparent_retries"),
537+
"Total number of transparent client retries across calls",
538+
GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL,
539+
SUM,
540+
Arrays.asList(GRPC_CLIENT_METHOD));
541+
542+
/**
543+
* {@link View} for total time of delay while there is no active attempt during the client call.
544+
*
545+
* @since 0.28
546+
*/
547+
public static final View GRPC_CLIENT_RETRY_DELAY_PER_CALL_VIEW =
548+
View.create(
549+
View.Name.create("grpc.io/client/retry_delay_per_call"),
550+
"Total time of delay while there is no active attempt during the client call",
551+
GRPC_CLIENT_RETRY_DELAY_PER_CALL,
552+
AGGREGATION_WITH_MILLIS_HISTOGRAM,
553+
Arrays.asList(GRPC_CLIENT_METHOD));
554+
555+
/**
556+
* {@link View} for total retries across all calls, excluding transparent retries.
557+
*
558+
* @since 0.28
559+
*/
560+
public static final View GRPC_CLIENT_RETRIES_VIEW =
561+
View.create(
562+
View.Name.create("grpc.io/client/retries"),
563+
"Total number of client retries across all calls",
564+
GRPC_CLIENT_RETRIES_PER_CALL,
565+
SUM,
566+
Arrays.asList(GRPC_CLIENT_METHOD));
567+
568+
/**
569+
* {@link View} for transparent retries per call.
570+
*
571+
* @since 0.28
572+
*/
573+
public static final View GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL_VIEW =
574+
View.create(
575+
View.Name.create("grpc.io/client/transparent_retries_per_call"),
576+
"Number of transparent client retries per call",
577+
GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL,
578+
AGGREGATION_WITH_COUNT_RETRY_HISTOGRAM,
579+
Arrays.asList(GRPC_CLIENT_METHOD));
580+
505581
// Rpc server cumulative views.
506582

507583
/**

contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcViews.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ public final class RpcViews {
144144
RpcViewConstants.GRPC_CLIENT_ROUNDTRIP_LATENCY_VIEW,
145145
RpcViewConstants.GRPC_CLIENT_STARTED_RPC_VIEW);
146146

147+
@VisibleForTesting
148+
static final ImmutableSet<View> GRPC_CLIENT_RETRY_VIEWS_SET =
149+
ImmutableSet.of(
150+
RpcViewConstants.GRPC_CLIENT_RETRIES_PER_CALL_VIEW,
151+
RpcViewConstants.GRPC_CLIENT_RETRIES_VIEW,
152+
RpcViewConstants.GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL_VIEW,
153+
RpcViewConstants.GRPC_CLIENT_TRANSPARENT_RETRIES_VIEW,
154+
RpcViewConstants.GRPC_CLIENT_RETRY_DELAY_PER_CALL_VIEW);
155+
147156
@VisibleForTesting
148157
static final ImmutableSet<View> GRPC_SERVER_BASIC_VIEWS_SET =
149158
ImmutableSet.of(
@@ -188,6 +197,24 @@ static void registerClientGrpcViews(ViewManager viewManager) {
188197
}
189198
}
190199

200+
/**
201+
* Registers client retry gRPC views.
202+
*
203+
* <p>It is recommended to call this method before doing any RPC call to avoid missing stats.
204+
*
205+
* @since 0.31.0
206+
*/
207+
public static void registerClientRetryGrpcViews() {
208+
registerClientRetryGrpcViews(Stats.getViewManager());
209+
}
210+
211+
@VisibleForTesting
212+
static void registerClientRetryGrpcViews(ViewManager viewManager) {
213+
for (View view : GRPC_CLIENT_RETRY_VIEWS_SET) {
214+
viewManager.registerView(view);
215+
}
216+
}
217+
191218
/**
192219
* Registers all standard server gRPC views.
193220
*

contrib/grpc_metrics/src/test/java/io/opencensus/contrib/grpc/metrics/RpcMeasureConstantsTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public void testConstants() {
5757
assertThat(RpcMeasureConstants.GRPC_CLIENT_SERVER_LATENCY).isNotNull();
5858
assertThat(RpcMeasureConstants.GRPC_CLIENT_ROUNDTRIP_LATENCY).isNotNull();
5959
assertThat(RpcMeasureConstants.GRPC_CLIENT_STARTED_RPCS).isNotNull();
60+
assertThat(RpcMeasureConstants.GRPC_CLIENT_RETRIES_PER_CALL).isNotNull();
61+
assertThat(RpcMeasureConstants.GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL).isNotNull();
62+
assertThat(RpcMeasureConstants.GRPC_CLIENT_RETRY_DELAY_PER_CALL).isNotNull();
6063

6164
// Test server measurement descriptors.
6265
assertThat(RpcMeasureConstants.RPC_SERVER_ERROR_COUNT).isNotNull();

contrib/grpc_metrics/src/test/java/io/opencensus/contrib/grpc/metrics/RpcViewConstantsTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ public void testConstants() {
6666
0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0,
6767
8192.0, 16384.0, 32768.0, 65536.0)
6868
.inOrder();
69+
assertThat(RpcViewConstants.RETRY_COUNT_PER_CALL_BUCKET_BOUNDARIES)
70+
.containsExactly(1.0, 2.0, 3.0, 4.0, 5.0)
71+
.inOrder();
6972

7073
// Test Aggregations
7174
assertThat(RpcViewConstants.MEAN).isEqualTo(Mean.create());
@@ -82,7 +85,10 @@ public void testConstants() {
8285
.isEqualTo(
8386
Distribution.create(
8487
BucketBoundaries.create(RpcViewConstants.RPC_COUNT_BUCKET_BOUNDARIES)));
85-
88+
assertThat(RpcViewConstants.AGGREGATION_WITH_COUNT_RETRY_HISTOGRAM)
89+
.isEqualTo(
90+
Distribution.create(
91+
BucketBoundaries.create(RpcViewConstants.RETRY_COUNT_PER_CALL_BUCKET_BOUNDARIES)));
8692
// Test Duration and Window
8793
assertThat(RpcViewConstants.MINUTE).isEqualTo(Duration.create(60, 0));
8894
assertThat(RpcViewConstants.HOUR).isEqualTo(Duration.create(60 * 60, 0));
@@ -112,7 +118,11 @@ public void testConstants() {
112118
assertThat(RpcViewConstants.GRPC_CLIENT_SENT_MESSAGES_PER_METHOD_VIEW).isNotNull();
113119
assertThat(RpcViewConstants.GRPC_CLIENT_RECEIVED_MESSAGES_PER_METHOD_VIEW).isNotNull();
114120
assertThat(RpcViewConstants.GRPC_CLIENT_SERVER_LATENCY_VIEW).isNotNull();
115-
assertThat(RpcViewConstants.GRPC_CLIENT_STARTED_RPC_VIEW).isNotNull();
121+
assertThat(RpcViewConstants.GRPC_CLIENT_RETRIES_PER_CALL_VIEW).isNotNull();
122+
assertThat(RpcViewConstants.GRPC_CLIENT_RETRIES_VIEW).isNotNull();
123+
assertThat(RpcViewConstants.GRPC_CLIENT_TRANSPARENT_RETRIES_PER_CALL_VIEW).isNotNull();
124+
assertThat(RpcViewConstants.GRPC_CLIENT_TRANSPARENT_RETRIES_VIEW).isNotNull();
125+
assertThat(RpcViewConstants.GRPC_CLIENT_RETRY_DELAY_PER_CALL_VIEW).isNotNull();
116126

117127
// Test server distribution view descriptors.
118128
assertThat(RpcViewConstants.RPC_SERVER_ERROR_COUNT_VIEW).isNotNull();

contrib/grpc_metrics/src/test/java/io/opencensus/contrib/grpc/metrics/RpcViewsTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ public void registerClientGrpcViews() {
8383
.containsExactlyElementsIn(RpcViews.GRPC_CLIENT_VIEWS_SET);
8484
}
8585

86+
@Test
87+
public void registerClientRetryGrpcViews() {
88+
FakeViewManager fakeViewManager = new FakeViewManager();
89+
RpcViews.registerClientRetryGrpcViews(fakeViewManager);
90+
assertThat(fakeViewManager.getRegisteredViews())
91+
.containsExactlyElementsIn(RpcViews.GRPC_CLIENT_RETRY_VIEWS_SET);
92+
}
93+
8694
@Test
8795
public void registerServerGrpcViews() {
8896
FakeViewManager fakeViewManager = new FakeViewManager();

0 commit comments

Comments
 (0)