28
28
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .BIGTABLE_PROJECT_ID_KEY ;
29
29
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .CLIENT_UID_KEY ;
30
30
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .CLUSTER_ID_KEY ;
31
+ import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .GRPC_METRICS ;
31
32
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .INSTANCE_ID_KEY ;
33
+ import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .INTERNAL_METRICS ;
32
34
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .METER_NAME ;
33
35
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .TABLE_ID_KEY ;
34
36
import static com .google .cloud .bigtable .data .v2 .stub .metrics .BuiltinMetricsConstants .ZONE_ID_KEY ;
74
76
import java .util .List ;
75
77
import java .util .Map ;
76
78
import java .util .Objects ;
79
+ import java .util .Optional ;
77
80
import java .util .Set ;
78
81
import java .util .UUID ;
79
82
import java .util .logging .Level ;
@@ -164,16 +167,12 @@ static List<TimeSeries> convertToApplicationResourceTimeSeries(
164
167
"convert application metrics is called when the supported resource is not detected" );
165
168
List <TimeSeries > allTimeSeries = new ArrayList <>();
166
169
for (MetricData metricData : collection ) {
167
- if (!metricData .getInstrumentationScopeInfo ().getName ().equals (METER_NAME )) {
168
- // Filter out metric data for instruments that are not part of the bigtable builtin metrics
169
- continue ;
170
- }
171
170
metricData .getData ().getPoints ().stream ()
172
171
.map (
173
172
pointData ->
174
- convertPointToApplicationResourceTimeSeries (
175
- metricData , pointData , applicationResource ) )
176
- .forEach (allTimeSeries ::add );
173
+ createInternalMetricsTimeSeries ( metricData , pointData , applicationResource ))
174
+ . filter ( Optional :: isPresent )
175
+ .forEach (ts -> ts . ifPresent ( allTimeSeries ::add ) );
177
176
}
178
177
return allTimeSeries ;
179
178
}
@@ -290,19 +289,28 @@ private static TimeSeries convertPointToBigtableTimeSeries(
290
289
return builder .build ();
291
290
}
292
291
293
- private static TimeSeries convertPointToApplicationResourceTimeSeries (
292
+ private static Optional < TimeSeries > createInternalMetricsTimeSeries (
294
293
MetricData metricData , PointData pointData , MonitoredResource applicationResource ) {
295
294
TimeSeries .Builder builder =
296
295
TimeSeries .newBuilder ()
297
296
.setMetricKind (convertMetricKind (metricData ))
298
297
.setValueType (convertValueType (metricData .getType ()))
299
298
.setResource (applicationResource );
300
299
301
- Metric .Builder metricBuilder = Metric .newBuilder ().setType (metricData .getName ());
302
-
303
- Attributes attributes = pointData .getAttributes ();
304
- for (AttributeKey <?> key : attributes .asMap ().keySet ()) {
305
- metricBuilder .putLabels (key .getKey (), String .valueOf (attributes .get (key )));
300
+ final Metric .Builder metricBuilder ;
301
+ // TODO: clean this up
302
+ // Internal metrics are based on views that include the metric prefix
303
+ // gRPC metrics dont have views and are dot encoded
304
+ // To unify these:
305
+ // - the useless views should be removed
306
+ // - internal metrics should use relative metric names w/o the prefix
307
+ if (INTERNAL_METRICS .contains (metricData .getName ())) {
308
+ metricBuilder = newApplicationMetricBuilder (metricData .getName (), pointData .getAttributes ());
309
+ } else if (GRPC_METRICS .containsKey (metricData .getName ())) {
310
+ metricBuilder = newGrpcMetricBuilder (metricData .getName (), pointData .getAttributes ());
311
+ } else {
312
+ logger .fine ("Skipping unexpected internal metric: " + metricData .getName ());
313
+ return Optional .empty ();
306
314
}
307
315
308
316
builder .setMetric (metricBuilder .build ());
@@ -314,7 +322,42 @@ private static TimeSeries convertPointToApplicationResourceTimeSeries(
314
322
.build ();
315
323
316
324
builder .addPoints (createPoint (metricData .getType (), pointData , timeInterval ));
317
- return builder .build ();
325
+ return Optional .of (builder .build ());
326
+ }
327
+
328
+ private static Metric .Builder newApplicationMetricBuilder (
329
+ String metricName , Attributes attributes ) {
330
+ // TODO: unify handling of metric prefixes
331
+ Metric .Builder metricBuilder = Metric .newBuilder ().setType (metricName );
332
+ for (Map .Entry <AttributeKey <?>, Object > e : attributes .asMap ().entrySet ()) {
333
+ metricBuilder .putLabels (e .getKey ().getKey (), String .valueOf (e .getValue ()));
334
+ }
335
+ return metricBuilder ;
336
+ }
337
+
338
+ private static Metric .Builder newGrpcMetricBuilder (String grpcMetricName , Attributes attributes ) {
339
+ Set <String > allowedAttrs = GRPC_METRICS .get (grpcMetricName );
340
+
341
+ Metric .Builder metricBuilder =
342
+ Metric .newBuilder ()
343
+ .setType ("bigtable.googleapis.com/internal/client/" + grpcMetricName .replace ('.' , '/' ));
344
+ for (Map .Entry <AttributeKey <?>, Object > e : attributes .asMap ().entrySet ()) {
345
+ String attrKey = e .getKey ().getKey ();
346
+ Object attrValue = e .getValue ();
347
+
348
+ // gRPC metrics are experimental and can change attribute names, to avoid incompatibility with
349
+ // the predefined
350
+ // metric schemas in stackdriver, filter out unknown keys
351
+ if (!allowedAttrs .contains (attrKey )) {
352
+ continue ;
353
+ }
354
+ // translate grpc key format to be compatible with cloud monitoring:
355
+ // grpc.xds_client.server_failure -> grpc_xds_client_server_failure
356
+ String normalizedKey = attrKey .replace ('.' , '_' );
357
+ metricBuilder .putLabels (normalizedKey , String .valueOf (attrValue ));
358
+ }
359
+
360
+ return metricBuilder ;
318
361
}
319
362
320
363
private static MetricKind convertMetricKind (MetricData metricData ) {
0 commit comments