11
11
import static com .linkedin .venice .stats .dimensions .VeniceResponseStatusCategory .SUCCESS ;
12
12
import static com .linkedin .venice .utils .CollectionUtils .setOf ;
13
13
import static org .apache .hc .core5 .http .HttpStatus .SC_NOT_FOUND ;
14
+ import static org .apache .hc .core5 .http .HttpStatus .SC_NO_CONTENT ;
14
15
import static org .apache .hc .core5 .http .HttpStatus .SC_OK ;
15
16
16
17
import com .linkedin .venice .client .exceptions .VeniceClientHttpException ;
@@ -74,6 +75,10 @@ public class BasicClientStats extends AbstractVeniceHttpStats {
74
75
private final MetricEntityStateOneEnum <VeniceResponseStatusCategory > healthyLatencyMetricForDavinciClient ;
75
76
private final MetricEntityStateOneEnum <VeniceResponseStatusCategory > unhealthyLatencyMetricForDavinciClient ;
76
77
private final Sensor requestKeyCountSensor ;
78
+ private final MetricEntityStateThreeEnums <HttpResponseStatusEnum , HttpResponseStatusCodeCategory , VeniceResponseStatusCategory > healthyKeyCountMetric ;
79
+ private final MetricEntityStateThreeEnums <HttpResponseStatusEnum , HttpResponseStatusCodeCategory , VeniceResponseStatusCategory > unhealthyKeyCountMetric ;
80
+ private final MetricEntityStateOneEnum <VeniceResponseStatusCategory > healthyKeyCountMetricForDavinciClient ;
81
+ private final MetricEntityStateOneEnum <VeniceResponseStatusCategory > unhealthyKeyCountMetricForDavinciClient ;
77
82
private final Sensor successRequestKeyCountSensor ;
78
83
private final Sensor successRequestRatioSensor ;
79
84
private final Sensor successRequestKeyRatioSensor ;
@@ -172,10 +177,31 @@ protected BasicClientStats(
172
177
getFullMetricName (BasicClientTehutiMetricName .UNHEALTHY_REQUEST_LATENCY .getMetricName ()))),
173
178
getBaseDimensionsMap (),
174
179
VeniceResponseStatusCategory .class );
180
+
181
+ healthyKeyCountMetricForDavinciClient = MetricEntityStateOneEnum .create (
182
+ BasicClientMetricEntity .KEY_COUNT_DVC .getMetricEntity (),
183
+ getOtelRepository (),
184
+ this ::registerSensor ,
185
+ BasicClientTehutiMetricName .SUCCESS_REQUEST_KEY_COUNT ,
186
+ Arrays .asList (successRequestKeyCountRate , new Avg (), new Max ()),
187
+ baseDimensionsMap ,
188
+ VeniceResponseStatusCategory .class );
189
+
190
+ unhealthyKeyCountMetricForDavinciClient = MetricEntityStateOneEnum .create (
191
+ BasicClientMetricEntity .KEY_COUNT_DVC .getMetricEntity (),
192
+ otelRepository ,
193
+ this ::registerSensor ,
194
+ BasicClientTehutiMetricName .FAILED_REQUEST_KEY_COUNT ,
195
+ Arrays .asList (new Rate (), new Avg (), new Max ()),
196
+ baseDimensionsMap ,
197
+ VeniceResponseStatusCategory .class );
198
+
175
199
healthyRequestMetric = null ;
176
200
unhealthyRequestMetric = null ;
177
201
healthyLatencyMetric = null ;
178
202
unhealthyLatencyMetric = null ;
203
+ healthyKeyCountMetric = null ;
204
+ unhealthyKeyCountMetric = null ;
179
205
} else {
180
206
healthyRequestMetric = MetricEntityStateThreeEnums .create (
181
207
BasicClientMetricEntity .CALL_COUNT .getMetricEntity (),
@@ -226,10 +252,34 @@ protected BasicClientStats(
226
252
HttpResponseStatusEnum .class ,
227
253
HttpResponseStatusCodeCategory .class ,
228
254
VeniceResponseStatusCategory .class );
255
+ // key count
256
+ healthyKeyCountMetric = MetricEntityStateThreeEnums .create (
257
+ BasicClientMetricEntity .KEY_COUNT .getMetricEntity (),
258
+ getOtelRepository (),
259
+ this ::registerSensor ,
260
+ BasicClientTehutiMetricName .SUCCESS_REQUEST_KEY_COUNT ,
261
+ Arrays .asList (successRequestKeyCountRate , new Avg (), new Max ()),
262
+ baseDimensionsMap ,
263
+ HttpResponseStatusEnum .class ,
264
+ HttpResponseStatusCodeCategory .class ,
265
+ VeniceResponseStatusCategory .class );
266
+ unhealthyKeyCountMetric = MetricEntityStateThreeEnums .create (
267
+ BasicClientMetricEntity .KEY_COUNT .getMetricEntity (),
268
+ otelRepository ,
269
+ this ::registerSensor ,
270
+ BasicClientTehutiMetricName .FAILED_REQUEST_KEY_COUNT ,
271
+ Arrays .asList (new Rate (), new Avg (), new Max ()),
272
+ baseDimensionsMap ,
273
+ HttpResponseStatusEnum .class ,
274
+ HttpResponseStatusCodeCategory .class ,
275
+ VeniceResponseStatusCategory .class );
276
+
229
277
healthyRequestMetricForDavinciClient = null ;
230
278
unhealthyRequestMetricForDavinciClient = null ;
231
279
healthyLatencyMetricForDavinciClient = null ;
232
280
unhealthyLatencyMetricForDavinciClient = null ;
281
+ healthyKeyCountMetricForDavinciClient = null ;
282
+ unhealthyKeyCountMetricForDavinciClient = null ;
233
283
}
234
284
235
285
// successRequestRatioSensor will be a derived metric in OTel
@@ -301,6 +351,34 @@ public void recordRequestKeyCount(int keyCount) {
301
351
302
352
public void recordSuccessRequestKeyCount (int successKeyCount ) {
303
353
successRequestKeyCountSensor .record (successKeyCount );
354
+ if (ClientType .isDavinciClient (this .clientType )) {
355
+ healthyKeyCountMetricForDavinciClient .record (successKeyCount , SUCCESS );
356
+ } else {
357
+ int httpStatus = getHealthyRequestHttpStatus (successKeyCount );
358
+ HttpResponseStatusEnum statusEnum = transformIntToHttpResponseStatusEnum (httpStatus );
359
+ HttpResponseStatusCodeCategory httpCategory = getVeniceHttpResponseStatusCodeCategory (httpStatus );
360
+ healthyKeyCountMetric .record (successKeyCount , statusEnum , httpCategory , SUCCESS );
361
+ }
362
+ }
363
+
364
+ public void recordFailedRequestKeyCount (int failedKeyCount , Throwable throwable ) {
365
+ if (ClientType .isDavinciClient (this .clientType )) {
366
+ unhealthyKeyCountMetricForDavinciClient .record (failedKeyCount , FAIL );
367
+ } else {
368
+ /**
369
+ * When throwable is null and the failed key count is 0, it means that the request was successful. However,
370
+ * we still need to record the failed key count as 0, and thus we use a default http status of SC_NO_CONTENT
371
+ * to indicate success.
372
+ */
373
+ int httpStatus = throwable != null ? getUnhealthyRequestHttpStatus (throwable ) : SC_NO_CONTENT ;
374
+ HttpResponseStatusEnum statusEnum = transformIntToHttpResponseStatusEnum (httpStatus );
375
+ HttpResponseStatusCodeCategory httpCategory = getVeniceHttpResponseStatusCodeCategory (httpStatus );
376
+ unhealthyKeyCountMetric .record (failedKeyCount , statusEnum , httpCategory , FAIL );
377
+ }
378
+ }
379
+
380
+ public void recordFailedRequestKeyCount (int failedKeyCount ) {
381
+ recordFailedRequestKeyCount (failedKeyCount , null );
304
382
}
305
383
306
384
protected final Rate getRequestRate () {
@@ -361,7 +439,8 @@ private Map<VeniceMetricsDimensions, String> getBaseDimensionsMap() {
361
439
* Metric names for tehuti metrics used in this class.
362
440
*/
363
441
public enum BasicClientTehutiMetricName implements TehutiMetricNameEnum {
364
- HEALTHY_REQUEST , UNHEALTHY_REQUEST , HEALTHY_REQUEST_LATENCY , UNHEALTHY_REQUEST_LATENCY ;
442
+ HEALTHY_REQUEST , UNHEALTHY_REQUEST , HEALTHY_REQUEST_LATENCY , UNHEALTHY_REQUEST_LATENCY , SUCCESS_REQUEST_KEY_COUNT ,
443
+ FAILED_REQUEST_KEY_COUNT ;
365
444
366
445
private final String metricName ;
367
446
@@ -401,6 +480,18 @@ public enum BasicClientMetricEntity {
401
480
HTTP_RESPONSE_STATUS_CODE_CATEGORY ,
402
481
VENICE_RESPONSE_STATUS_CODE_CATEGORY )
403
482
),
483
+ /**
484
+ * Count of keys during response handling along with response codes
485
+ */
486
+ KEY_COUNT (
487
+ MetricType .HISTOGRAM , MetricUnit .NUMBER , "Count of keys during response handling along with response codes" ,
488
+ setOf (
489
+ VENICE_STORE_NAME ,
490
+ VENICE_REQUEST_METHOD ,
491
+ HTTP_RESPONSE_STATUS_CODE ,
492
+ HTTP_RESPONSE_STATUS_CODE_CATEGORY ,
493
+ VENICE_RESPONSE_STATUS_CODE_CATEGORY )
494
+ ),
404
495
/**
405
496
* Count of all DaVinci requests: as DaVinci is local reads, we do not track HTTP response codes
406
497
* But keeping the same name call_count across all clients for consistency
@@ -416,6 +507,14 @@ public enum BasicClientMetricEntity {
416
507
CALL_TIME .name ().toLowerCase (), MetricType .HISTOGRAM , MetricUnit .MILLISECOND ,
417
508
"Latency for all DaVinci Client responses" ,
418
509
setOf (VENICE_STORE_NAME , VENICE_REQUEST_METHOD , VENICE_RESPONSE_STATUS_CODE_CATEGORY )
510
+ ),
511
+ /**
512
+ * Count of keys during response handling along with response codes
513
+ */
514
+ KEY_COUNT_DVC (
515
+ KEY_COUNT .name ().toLowerCase (), MetricType .HISTOGRAM , MetricUnit .NUMBER ,
516
+ "Count of keys for all DaVinci Client responses" ,
517
+ setOf (VENICE_STORE_NAME , VENICE_REQUEST_METHOD , VENICE_RESPONSE_STATUS_CODE_CATEGORY )
419
518
);
420
519
421
520
private final MetricEntity metricEntity ;
0 commit comments