Skip to content

Commit f734ec6

Browse files
authored
perf(bigtable): Refactor metric attributes for performance (#12445)
1 parent f133811 commit f734ec6

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

bigtable/bigtable.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,14 +2237,14 @@ func recordOperationCompletion(mt *builtinMetricsTracer) {
22372237

22382238
// Record operation_latencies
22392239
opLatAttrs, _ := mt.toOtelMetricAttrs(metricNameOperationLatencies)
2240-
mt.instrumentOperationLatencies.Record(mt.ctx, elapsedTimeMs, metric.WithAttributes(opLatAttrs...))
2240+
mt.instrumentOperationLatencies.Record(mt.ctx, elapsedTimeMs, metric.WithAttributeSet(opLatAttrs))
22412241

22422242
// Record retry_count
22432243
retryCntAttrs, _ := mt.toOtelMetricAttrs(metricNameRetryCount)
22442244
if mt.currOp.attemptCount > 1 {
22452245
// Only record when retry count is greater than 0 so the retry
22462246
// graph will be less confusing
2247-
mt.instrumentRetryCount.Add(mt.ctx, mt.currOp.attemptCount-1, metric.WithAttributes(retryCntAttrs...))
2247+
mt.instrumentRetryCount.Add(mt.ctx, mt.currOp.attemptCount-1, metric.WithAttributeSet(retryCntAttrs))
22482248
}
22492249
}
22502250

@@ -2315,11 +2315,11 @@ func recordAttemptCompletion(mt *builtinMetricsTracer) {
23152315

23162316
// Record attempt_latencies
23172317
attemptLatAttrs, _ := mt.toOtelMetricAttrs(metricNameAttemptLatencies)
2318-
mt.instrumentAttemptLatencies.Record(mt.ctx, elapsedTime, metric.WithAttributes(attemptLatAttrs...))
2318+
mt.instrumentAttemptLatencies.Record(mt.ctx, elapsedTime, metric.WithAttributeSet(attemptLatAttrs))
23192319

23202320
// Record server_latencies
23212321
serverLatAttrs, _ := mt.toOtelMetricAttrs(metricNameServerLatencies)
23222322
if mt.currOp.currAttempt.serverLatencyErr == nil {
2323-
mt.instrumentServerLatencies.Record(mt.ctx, mt.currOp.currAttempt.serverLatency, metric.WithAttributes(serverLatAttrs...))
2323+
mt.instrumentServerLatencies.Record(mt.ctx, mt.currOp.currAttempt.serverLatency, metric.WithAttributeSet(serverLatAttrs))
23242324
}
23252325
}

bigtable/metrics.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const (
6666
// Metric units
6767
metricUnitMS = "ms"
6868
metricUnitCount = "1"
69+
maxAttrsLen = 12 // Monitored resource labels + Metric labels
6970
)
7071

7172
// These are effectively constant, but for testing purposes they are mutable
@@ -402,9 +403,10 @@ func (tf *builtinMetricsTracerFactory) createBuiltinMetricsTracer(ctx context.Co
402403
// - converts metric attributes values captured throughout the operation / attempt
403404
// to OpenTelemetry attributes format,
404405
// - combines these with common client attributes and returns
405-
func (mt *builtinMetricsTracer) toOtelMetricAttrs(metricName string) ([]attribute.KeyValue, error) {
406+
func (mt *builtinMetricsTracer) toOtelMetricAttrs(metricName string) (attribute.Set, error) {
407+
attrKeyValues := make([]attribute.KeyValue, 0, maxAttrsLen)
406408
// Create attribute key value pairs for attributes common to all metricss
407-
attrKeyValues := []attribute.KeyValue{
409+
attrKeyValues = append(attrKeyValues,
408410
attribute.String(metricLabelKeyMethod, mt.method),
409411

410412
// Add resource labels to otel metric labels.
@@ -416,13 +418,13 @@ func (mt *builtinMetricsTracer) toOtelMetricAttrs(metricName string) ([]attribut
416418
// use last attempt's cluster and zone
417419
attribute.String(monitoredResLabelKeyCluster, mt.currOp.currAttempt.clusterID),
418420
attribute.String(monitoredResLabelKeyZone, mt.currOp.currAttempt.zoneID),
419-
}
421+
)
420422
attrKeyValues = append(attrKeyValues, mt.clientAttributes...)
421423

422424
// Get metric details
423425
mDetails, found := metricsDetails[metricName]
424426
if !found {
425-
return attrKeyValues, fmt.Errorf("unable to create attributes list for unknown metric: %v", metricName)
427+
return attribute.Set{}, fmt.Errorf("unable to create attributes list for unknown metric: %v", metricName)
426428
}
427429

428430
status := mt.currOp.status
@@ -438,9 +440,10 @@ func (mt *builtinMetricsTracer) toOtelMetricAttrs(metricName string) ([]attribut
438440
case metricLabelKeyStreamingOperation:
439441
attrKeyValues = append(attrKeyValues, attribute.Bool(metricLabelKeyStreamingOperation, mt.isStreaming))
440442
default:
441-
return attrKeyValues, fmt.Errorf("unknown additional attribute: %v", attrKey)
443+
return attribute.Set{}, fmt.Errorf("unknown additional attribute: %v", attrKey)
442444
}
443445
}
444446

445-
return attrKeyValues, nil
447+
attrSet := attribute.NewSet(attrKeyValues...)
448+
return attrSet, nil
446449
}

bigtable/metrics_test.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -452,24 +452,23 @@ func TestToOtelMetricAttrs(t *testing.T) {
452452
desc: "Unknown metric",
453453
mt: mt,
454454
metricName: "unknown_metric",
455-
wantAttrs: []attribute.KeyValue{
456-
attribute.String(monitoredResLabelKeyTable, "my-table"),
457-
attribute.String(metricLabelKeyMethod, "ReadRows"),
458-
attribute.String(monitoredResLabelKeyCluster, clusterID1),
459-
attribute.String(monitoredResLabelKeyZone, zoneID1),
460-
},
461-
wantError: fmt.Errorf("unable to create attributes list for unknown metric: unknown_metric"),
455+
wantAttrs: []attribute.KeyValue{}, // Expect empty slice on error
456+
wantError: fmt.Errorf("unable to create attributes list for unknown metric: unknown_metric"),
462457
},
463458
}
464459

465460
lessKeyValue := func(a, b attribute.KeyValue) bool { return a.Key < b.Key }
466461
for _, test := range tests {
467462
t.Run(test.desc, func(t *testing.T) {
468-
gotAttrs, gotErr := test.mt.toOtelMetricAttrs(test.metricName)
463+
gotAttrSet, gotErr := test.mt.toOtelMetricAttrs(test.metricName)
469464
if !equalErrs(gotErr, test.wantError) {
470465
t.Errorf("error got: %v, want: %v", gotErr, test.wantError)
471466
}
472-
if diff := testutil.Diff(gotAttrs, test.wantAttrs,
467+
gotAttrsSlice := gotAttrSet.ToSlice() // Convert Set to Slice
468+
if gotAttrsSlice == nil { // Ensure nil slice is treated as empty slice for comparison
469+
gotAttrsSlice = []attribute.KeyValue{}
470+
}
471+
if diff := testutil.Diff(gotAttrsSlice, test.wantAttrs,
473472
cmpopts.IgnoreUnexported(attribute.KeyValue{}, attribute.Value{}),
474473
cmpopts.SortSlices(lessKeyValue)); diff != "" {
475474
t.Errorf("got=-, want=+ \n%v", diff)

0 commit comments

Comments
 (0)