Skip to content

Commit 6e4c922

Browse files
authored
prometheus: Refactor getAttrs (#5937)
Addresses #5932 (comment) I feel that `getAttr` was doing too much and having: ```go keys, values := getAttrs(dp.Attributes) keys = append(keys, kv.keys...) values = append(values, kv.vals...) // ... keys, values := getAttrs(*res.Set()) ``` is more readable than: ```go keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV) // ... keys, values := getAttrs(*res.Set(), [2]string{}, [2]string{}, keyVals{}) ``` Benchmarks results just in case to minimize the possibility of accidental introduction of a performance overhead: ``` $ benchstat old.txt new.txt goos: linux goarch: amd64 pkg: go.opentelemetry.io/otel/exporters/prometheus cpu: Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ Collect1-16 29.77µ ± 11% 30.33µ ± 10% ~ (p=0.529 n=10) Collect10-16 80.58µ ± 7% 77.93µ ± 15% ~ (p=0.315 n=10) Collect100-16 528.5µ ± 7% 511.2µ ± 2% -3.28% (p=0.015 n=10) Collect1000-16 3.179m ± 6% 3.344m ± 15% +5.19% (p=0.003 n=10) Collect10000-16 31.77m ± 2% 33.14m ± 7% +4.34% (p=0.004 n=10) geomean 662.9µ 668.9µ +0.90% │ old.txt │ new.txt │ │ B/op │ B/op vs base │ Collect1-16 36.52Ki ± 0% 36.59Ki ± 0% +0.17% (p=0.000 n=10) Collect10-16 64.58Ki ± 0% 64.64Ki ± 0% +0.09% (p=0.000 n=10) Collect100-16 349.3Ki ± 0% 349.4Ki ± 0% +0.03% (p=0.000 n=10) Collect1000-16 3.163Mi ± 0% 3.163Mi ± 0% ~ (p=0.247 n=10) Collect10000-16 31.05Mi ± 0% 31.06Mi ± 0% +0.02% (p=0.009 n=10) geomean 610.6Ki 611.0Ki +0.06% │ old.txt │ new.txt │ │ allocs/op │ allocs/op vs base │ Collect1-16 70.00 ± 0% 72.00 ± 0% +2.86% (p=0.000 n=10) Collect10-16 396.0 ± 0% 398.0 ± 0% +0.51% (p=0.000 n=10) Collect100-16 3.661k ± 0% 3.663k ± 0% +0.05% (p=0.000 n=10) Collect1000-16 36.15k ± 0% 36.15k ± 0% +0.01% (p=0.000 n=10) Collect10000-16 361.4k ± 0% 361.5k ± 0% +0.03% (p=0.009 n=10) geomean 4.212k 4.241k +0.68% ```
1 parent 7fd5942 commit 6e4c922

File tree

1 file changed

+37
-37
lines changed

1 file changed

+37
-37
lines changed

exporters/prometheus/exporter.go

+37-37
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,14 @@ const (
3333
scopeInfoMetricName = "otel_scope_info"
3434
scopeInfoDescription = "Instrumentation Scope metadata"
3535

36+
scopeNameLabel = "otel_scope_name"
37+
scopeVersionLabel = "otel_scope_version"
38+
3639
traceIDExemplarKey = "trace_id"
3740
spanIDExemplarKey = "span_id"
3841
)
3942

40-
var (
41-
scopeInfoKeys = [2]string{"otel_scope_name", "otel_scope_version"}
42-
43-
errScopeInvalid = errors.New("invalid scope")
44-
)
43+
var errScopeInvalid = errors.New("invalid scope")
4544

4645
// Exporter is a Prometheus Exporter that embeds the OTel metric.Reader
4746
// interface for easy instantiation with a MeterProvider.
@@ -187,7 +186,11 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
187186
}
188187

189188
for _, scopeMetrics := range metrics.ScopeMetrics {
190-
var keys, values [2]string
189+
n := len(c.resourceKeyVals.keys) + 2 // resource attrs + scope name + scope version
190+
kv := keyVals{
191+
keys: make([]string, 0, n),
192+
vals: make([]string, 0, n),
193+
}
191194

192195
if !c.disableScopeInfo {
193196
scopeInfo, err := c.scopeInfo(scopeMetrics.Scope)
@@ -202,10 +205,13 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
202205

203206
ch <- scopeInfo
204207

205-
keys = scopeInfoKeys
206-
values = [2]string{scopeMetrics.Scope.Name, scopeMetrics.Scope.Version}
208+
kv.keys = append(kv.keys, scopeNameLabel, scopeVersionLabel)
209+
kv.vals = append(kv.vals, scopeMetrics.Scope.Name, scopeMetrics.Scope.Version)
207210
}
208211

212+
kv.keys = append(kv.keys, c.resourceKeyVals.keys...)
213+
kv.vals = append(kv.vals, c.resourceKeyVals.vals...)
214+
209215
for _, m := range scopeMetrics.Metrics {
210216
typ := c.metricType(m)
211217
if typ == nil {
@@ -224,25 +230,27 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
224230

225231
switch v := m.Data.(type) {
226232
case metricdata.Histogram[int64]:
227-
addHistogramMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
233+
addHistogramMetric(ch, v, m, name, kv)
228234
case metricdata.Histogram[float64]:
229-
addHistogramMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
235+
addHistogramMetric(ch, v, m, name, kv)
230236
case metricdata.Sum[int64]:
231-
addSumMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
237+
addSumMetric(ch, v, m, name, kv)
232238
case metricdata.Sum[float64]:
233-
addSumMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
239+
addSumMetric(ch, v, m, name, kv)
234240
case metricdata.Gauge[int64]:
235-
addGaugeMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
241+
addGaugeMetric(ch, v, m, name, kv)
236242
case metricdata.Gauge[float64]:
237-
addGaugeMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
243+
addGaugeMetric(ch, v, m, name, kv)
238244
}
239245
}
240246
}
241247
}
242248

243-
func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogram metricdata.Histogram[N], m metricdata.Metrics, ks, vs [2]string, name string, resourceKV keyVals) {
249+
func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogram metricdata.Histogram[N], m metricdata.Metrics, name string, kv keyVals) {
244250
for _, dp := range histogram.DataPoints {
245-
keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV)
251+
keys, values := getAttrs(dp.Attributes)
252+
keys = append(keys, kv.keys...)
253+
values = append(values, kv.vals...)
246254

247255
desc := prometheus.NewDesc(name, m.Description, keys, nil)
248256
buckets := make(map[float64]uint64, len(dp.Bounds))
@@ -262,14 +270,16 @@ func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogra
262270
}
263271
}
264272

265-
func addSumMetric[N int64 | float64](ch chan<- prometheus.Metric, sum metricdata.Sum[N], m metricdata.Metrics, ks, vs [2]string, name string, resourceKV keyVals) {
273+
func addSumMetric[N int64 | float64](ch chan<- prometheus.Metric, sum metricdata.Sum[N], m metricdata.Metrics, name string, kv keyVals) {
266274
valueType := prometheus.CounterValue
267275
if !sum.IsMonotonic {
268276
valueType = prometheus.GaugeValue
269277
}
270278

271279
for _, dp := range sum.DataPoints {
272-
keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV)
280+
keys, values := getAttrs(dp.Attributes)
281+
keys = append(keys, kv.keys...)
282+
values = append(values, kv.vals...)
273283

274284
desc := prometheus.NewDesc(name, m.Description, keys, nil)
275285
m, err := prometheus.NewConstMetric(desc, valueType, float64(dp.Value), values...)
@@ -286,9 +296,11 @@ func addSumMetric[N int64 | float64](ch chan<- prometheus.Metric, sum metricdata
286296
}
287297
}
288298

289-
func addGaugeMetric[N int64 | float64](ch chan<- prometheus.Metric, gauge metricdata.Gauge[N], m metricdata.Metrics, ks, vs [2]string, name string, resourceKV keyVals) {
299+
func addGaugeMetric[N int64 | float64](ch chan<- prometheus.Metric, gauge metricdata.Gauge[N], m metricdata.Metrics, name string, kv keyVals) {
290300
for _, dp := range gauge.DataPoints {
291-
keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV)
301+
keys, values := getAttrs(dp.Attributes)
302+
keys = append(keys, kv.keys...)
303+
values = append(values, kv.vals...)
292304

293305
desc := prometheus.NewDesc(name, m.Description, keys, nil)
294306
m, err := prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(dp.Value), values...)
@@ -300,9 +312,9 @@ func addGaugeMetric[N int64 | float64](ch chan<- prometheus.Metric, gauge metric
300312
}
301313
}
302314

303-
// getAttrs parses the attribute.Set to two lists of matching Prometheus-style
315+
// getAttrs converts the attribute.Set to two lists of matching Prometheus-style
304316
// keys and values.
305-
func getAttrs(attrs attribute.Set, ks, vs [2]string, resourceKV keyVals) ([]string, []string) {
317+
func getAttrs(attrs attribute.Set) ([]string, []string) {
306318
keys := make([]string, 0, attrs.Len())
307319
values := make([]string, 0, attrs.Len())
308320
itr := attrs.Iter()
@@ -334,29 +346,17 @@ func getAttrs(attrs attribute.Set, ks, vs [2]string, resourceKV keyVals) ([]stri
334346
values = append(values, strings.Join(vals, ";"))
335347
}
336348
}
337-
338-
if ks[0] != "" {
339-
keys = append(keys, ks[:]...)
340-
values = append(values, vs[:]...)
341-
}
342-
343-
for idx := range resourceKV.keys {
344-
keys = append(keys, resourceKV.keys[idx])
345-
values = append(values, resourceKV.vals[idx])
346-
}
347-
348349
return keys, values
349350
}
350351

351352
func createInfoMetric(name, description string, res *resource.Resource) (prometheus.Metric, error) {
352-
keys, values := getAttrs(*res.Set(), [2]string{}, [2]string{}, keyVals{})
353+
keys, values := getAttrs(*res.Set())
353354
desc := prometheus.NewDesc(name, description, keys, nil)
354355
return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), values...)
355356
}
356357

357358
func createScopeInfoMetric(scope instrumentation.Scope) (prometheus.Metric, error) {
358-
keys := scopeInfoKeys[:]
359-
desc := prometheus.NewDesc(scopeInfoMetricName, scopeInfoDescription, keys, nil)
359+
desc := prometheus.NewDesc(scopeInfoMetricName, scopeInfoDescription, []string{scopeNameLabel, scopeVersionLabel}, nil)
360360
return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), scope.Name, scope.Version)
361361
}
362362

@@ -446,7 +446,7 @@ func (c *collector) createResourceAttributes(res *resource.Resource) {
446446
defer c.mu.Unlock()
447447

448448
resourceAttrs, _ := res.Set().Filter(c.resourceAttributesFilter)
449-
resourceKeys, resourceValues := getAttrs(resourceAttrs, [2]string{}, [2]string{}, keyVals{})
449+
resourceKeys, resourceValues := getAttrs(resourceAttrs)
450450
c.resourceKeyVals = keyVals{keys: resourceKeys, vals: resourceValues}
451451
}
452452

0 commit comments

Comments
 (0)