Skip to content

Commit 6147c81

Browse files
authored
stats/opentelemetry: Optimize slice allocations (#7525)
1 parent cd05c9e commit 6147c81

File tree

3 files changed

+32
-20
lines changed

3 files changed

+32
-20
lines changed

stats/opentelemetry/client_metrics.go

+17-8
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,13 @@ func (h *clientStatsHandler) streamInterceptor(ctx context.Context, desc *grpc.S
128128
}
129129

130130
func (h *clientStatsHandler) perCallMetrics(ctx context.Context, err error, startTime time.Time, ci *callInfo) {
131-
s := status.Convert(err)
132-
callLatency := float64(time.Since(startTime)) / float64(time.Second)
133-
h.clientMetrics.callDuration.Record(ctx, callLatency, otelmetric.WithAttributes(otelattribute.String("grpc.method", ci.method), otelattribute.String("grpc.target", ci.target), otelattribute.String("grpc.status", canonicalString(s.Code()))))
131+
callLatency := float64(time.Since(startTime)) / float64(time.Second) // calculate ASAP
132+
attrs := otelmetric.WithAttributeSet(otelattribute.NewSet(
133+
otelattribute.String("grpc.method", ci.method),
134+
otelattribute.String("grpc.target", ci.target),
135+
otelattribute.String("grpc.status", canonicalString(status.Code(err))),
136+
))
137+
h.clientMetrics.callDuration.Record(ctx, callLatency, attrs)
134138
}
135139

136140
// TagConn exists to satisfy stats.Handler.
@@ -188,7 +192,11 @@ func (h *clientStatsHandler) processRPCEvent(ctx context.Context, s stats.RPCSta
188192
return
189193
}
190194

191-
h.clientMetrics.attemptStarted.Add(ctx, 1, otelmetric.WithAttributes(otelattribute.String("grpc.method", ci.method), otelattribute.String("grpc.target", ci.target)))
195+
attrs := otelmetric.WithAttributeSet(otelattribute.NewSet(
196+
otelattribute.String("grpc.method", ci.method),
197+
otelattribute.String("grpc.target", ci.target),
198+
))
199+
h.clientMetrics.attemptStarted.Add(ctx, 1, attrs)
192200
case *stats.OutPayload:
193201
atomic.AddInt64(&ai.sentCompressedBytes, int64(st.CompressedLength))
194202
case *stats.InPayload:
@@ -244,10 +252,11 @@ func (h *clientStatsHandler) processRPCEnd(ctx context.Context, ai *attemptInfo,
244252
}
245253
}
246254

247-
clientAttributeOption := otelmetric.WithAttributes(attributes...)
248-
h.clientMetrics.attemptDuration.Record(ctx, latency, clientAttributeOption)
249-
h.clientMetrics.attemptSentTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.sentCompressedBytes), clientAttributeOption)
250-
h.clientMetrics.attemptRcvdTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.recvCompressedBytes), clientAttributeOption)
255+
// Allocate vararg slice once.
256+
opts := []otelmetric.RecordOption{otelmetric.WithAttributeSet(otelattribute.NewSet(attributes...))}
257+
h.clientMetrics.attemptDuration.Record(ctx, latency, opts...)
258+
h.clientMetrics.attemptSentTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.sentCompressedBytes), opts...)
259+
h.clientMetrics.attemptRcvdTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.recvCompressedBytes), opts...)
251260
}
252261

253262
const (

stats/opentelemetry/opentelemetry.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ func optionFromLabels(labelKeys []string, optionalLabelKeys []string, optionalLa
283283
}
284284
}
285285
}
286-
return otelmetric.WithAttributes(attributes...)
286+
return otelmetric.WithAttributeSet(otelattribute.NewSet(attributes...))
287287
}
288288

289289
// registryMetrics implements MetricsRecorder for the client and server stats
@@ -330,41 +330,40 @@ func (rm *registryMetrics) registerMetrics(metrics *estats.Metrics, meter otelme
330330

331331
func (rm *registryMetrics) RecordInt64Count(handle *estats.Int64CountHandle, incr int64, labels ...string) {
332332
desc := handle.Descriptor()
333-
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
334-
335333
if ic, ok := rm.intCounts[desc]; ok {
334+
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
336335
ic.Add(context.TODO(), incr, ao)
337336
}
338337
}
339338

340339
func (rm *registryMetrics) RecordFloat64Count(handle *estats.Float64CountHandle, incr float64, labels ...string) {
341340
desc := handle.Descriptor()
342-
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
343341
if fc, ok := rm.floatCounts[desc]; ok {
342+
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
344343
fc.Add(context.TODO(), incr, ao)
345344
}
346345
}
347346

348347
func (rm *registryMetrics) RecordInt64Histo(handle *estats.Int64HistoHandle, incr int64, labels ...string) {
349348
desc := handle.Descriptor()
350-
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
351349
if ih, ok := rm.intHistos[desc]; ok {
350+
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
352351
ih.Record(context.TODO(), incr, ao)
353352
}
354353
}
355354

356355
func (rm *registryMetrics) RecordFloat64Histo(handle *estats.Float64HistoHandle, incr float64, labels ...string) {
357356
desc := handle.Descriptor()
358-
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
359357
if fh, ok := rm.floatHistos[desc]; ok {
358+
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
360359
fh.Record(context.TODO(), incr, ao)
361360
}
362361
}
363362

364363
func (rm *registryMetrics) RecordInt64Gauge(handle *estats.Int64GaugeHandle, incr int64, labels ...string) {
365364
desc := handle.Descriptor()
366-
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
367365
if ig, ok := rm.intGauges[desc]; ok {
366+
ao := optionFromLabels(desc.Labels, desc.OptionalLabels, rm.optionalLabels, labels...)
368367
ig.Record(context.TODO(), incr, ao)
369368
}
370369
}

stats/opentelemetry/server_metrics.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,10 @@ func (h *serverStatsHandler) processRPCData(ctx context.Context, s stats.RPCStat
227227
}
228228
ai.pluginOptionLabels = labels
229229
}
230-
h.serverMetrics.callStarted.Add(ctx, 1, otelmetric.WithAttributes(otelattribute.String("grpc.method", ai.method)))
230+
attrs := otelmetric.WithAttributeSet(otelattribute.NewSet(
231+
otelattribute.String("grpc.method", ai.method),
232+
))
233+
h.serverMetrics.callStarted.Add(ctx, 1, attrs)
231234
case *stats.OutPayload:
232235
atomic.AddInt64(&ai.sentCompressedBytes, int64(st.CompressedLength))
233236
case *stats.InPayload:
@@ -253,10 +256,11 @@ func (h *serverStatsHandler) processRPCEnd(ctx context.Context, ai *attemptInfo,
253256
attributes = append(attributes, otelattribute.String(k, v))
254257
}
255258

256-
serverAttributeOption := otelmetric.WithAttributes(attributes...)
257-
h.serverMetrics.callDuration.Record(ctx, latency, serverAttributeOption)
258-
h.serverMetrics.callSentTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.sentCompressedBytes), serverAttributeOption)
259-
h.serverMetrics.callRcvdTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.recvCompressedBytes), serverAttributeOption)
259+
// Allocate vararg slice once.
260+
opts := []otelmetric.RecordOption{otelmetric.WithAttributeSet(otelattribute.NewSet(attributes...))}
261+
h.serverMetrics.callDuration.Record(ctx, latency, opts...)
262+
h.serverMetrics.callSentTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.sentCompressedBytes), opts...)
263+
h.serverMetrics.callRcvdTotalCompressedMessageSize.Record(ctx, atomic.LoadInt64(&ai.recvCompressedBytes), opts...)
260264
}
261265

262266
const (

0 commit comments

Comments
 (0)