You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2026-06-03 18:35:08 +02:00
prometheus: Refactor getAttrs (#5937)
Addresses https://github.com/open-telemetry/opentelemetry-go/pull/5932#discussion_r1822469033 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% ```
This commit is contained in:
@@ -33,15 +33,14 @@ const (
|
||||
scopeInfoMetricName = "otel_scope_info"
|
||||
scopeInfoDescription = "Instrumentation Scope metadata"
|
||||
|
||||
scopeNameLabel = "otel_scope_name"
|
||||
scopeVersionLabel = "otel_scope_version"
|
||||
|
||||
traceIDExemplarKey = "trace_id"
|
||||
spanIDExemplarKey = "span_id"
|
||||
)
|
||||
|
||||
var (
|
||||
scopeInfoKeys = [2]string{"otel_scope_name", "otel_scope_version"}
|
||||
|
||||
errScopeInvalid = errors.New("invalid scope")
|
||||
)
|
||||
var errScopeInvalid = errors.New("invalid scope")
|
||||
|
||||
// Exporter is a Prometheus Exporter that embeds the OTel metric.Reader
|
||||
// interface for easy instantiation with a MeterProvider.
|
||||
@@ -187,7 +186,11 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||
}
|
||||
|
||||
for _, scopeMetrics := range metrics.ScopeMetrics {
|
||||
var keys, values [2]string
|
||||
n := len(c.resourceKeyVals.keys) + 2 // resource attrs + scope name + scope version
|
||||
kv := keyVals{
|
||||
keys: make([]string, 0, n),
|
||||
vals: make([]string, 0, n),
|
||||
}
|
||||
|
||||
if !c.disableScopeInfo {
|
||||
scopeInfo, err := c.scopeInfo(scopeMetrics.Scope)
|
||||
@@ -202,10 +205,13 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||
|
||||
ch <- scopeInfo
|
||||
|
||||
keys = scopeInfoKeys
|
||||
values = [2]string{scopeMetrics.Scope.Name, scopeMetrics.Scope.Version}
|
||||
kv.keys = append(kv.keys, scopeNameLabel, scopeVersionLabel)
|
||||
kv.vals = append(kv.vals, scopeMetrics.Scope.Name, scopeMetrics.Scope.Version)
|
||||
}
|
||||
|
||||
kv.keys = append(kv.keys, c.resourceKeyVals.keys...)
|
||||
kv.vals = append(kv.vals, c.resourceKeyVals.vals...)
|
||||
|
||||
for _, m := range scopeMetrics.Metrics {
|
||||
typ := c.metricType(m)
|
||||
if typ == nil {
|
||||
@@ -224,25 +230,27 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||
|
||||
switch v := m.Data.(type) {
|
||||
case metricdata.Histogram[int64]:
|
||||
addHistogramMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
|
||||
addHistogramMetric(ch, v, m, name, kv)
|
||||
case metricdata.Histogram[float64]:
|
||||
addHistogramMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
|
||||
addHistogramMetric(ch, v, m, name, kv)
|
||||
case metricdata.Sum[int64]:
|
||||
addSumMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
|
||||
addSumMetric(ch, v, m, name, kv)
|
||||
case metricdata.Sum[float64]:
|
||||
addSumMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
|
||||
addSumMetric(ch, v, m, name, kv)
|
||||
case metricdata.Gauge[int64]:
|
||||
addGaugeMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
|
||||
addGaugeMetric(ch, v, m, name, kv)
|
||||
case metricdata.Gauge[float64]:
|
||||
addGaugeMetric(ch, v, m, keys, values, name, c.resourceKeyVals)
|
||||
addGaugeMetric(ch, v, m, name, kv)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogram metricdata.Histogram[N], m metricdata.Metrics, ks, vs [2]string, name string, resourceKV keyVals) {
|
||||
func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogram metricdata.Histogram[N], m metricdata.Metrics, name string, kv keyVals) {
|
||||
for _, dp := range histogram.DataPoints {
|
||||
keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV)
|
||||
keys, values := getAttrs(dp.Attributes)
|
||||
keys = append(keys, kv.keys...)
|
||||
values = append(values, kv.vals...)
|
||||
|
||||
desc := prometheus.NewDesc(name, m.Description, keys, nil)
|
||||
buckets := make(map[float64]uint64, len(dp.Bounds))
|
||||
@@ -262,14 +270,16 @@ func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogra
|
||||
}
|
||||
}
|
||||
|
||||
func addSumMetric[N int64 | float64](ch chan<- prometheus.Metric, sum metricdata.Sum[N], m metricdata.Metrics, ks, vs [2]string, name string, resourceKV keyVals) {
|
||||
func addSumMetric[N int64 | float64](ch chan<- prometheus.Metric, sum metricdata.Sum[N], m metricdata.Metrics, name string, kv keyVals) {
|
||||
valueType := prometheus.CounterValue
|
||||
if !sum.IsMonotonic {
|
||||
valueType = prometheus.GaugeValue
|
||||
}
|
||||
|
||||
for _, dp := range sum.DataPoints {
|
||||
keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV)
|
||||
keys, values := getAttrs(dp.Attributes)
|
||||
keys = append(keys, kv.keys...)
|
||||
values = append(values, kv.vals...)
|
||||
|
||||
desc := prometheus.NewDesc(name, m.Description, keys, nil)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
func addGaugeMetric[N int64 | float64](ch chan<- prometheus.Metric, gauge metricdata.Gauge[N], m metricdata.Metrics, ks, vs [2]string, name string, resourceKV keyVals) {
|
||||
func addGaugeMetric[N int64 | float64](ch chan<- prometheus.Metric, gauge metricdata.Gauge[N], m metricdata.Metrics, name string, kv keyVals) {
|
||||
for _, dp := range gauge.DataPoints {
|
||||
keys, values := getAttrs(dp.Attributes, ks, vs, resourceKV)
|
||||
keys, values := getAttrs(dp.Attributes)
|
||||
keys = append(keys, kv.keys...)
|
||||
values = append(values, kv.vals...)
|
||||
|
||||
desc := prometheus.NewDesc(name, m.Description, keys, nil)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// getAttrs parses the attribute.Set to two lists of matching Prometheus-style
|
||||
// getAttrs converts the attribute.Set to two lists of matching Prometheus-style
|
||||
// keys and values.
|
||||
func getAttrs(attrs attribute.Set, ks, vs [2]string, resourceKV keyVals) ([]string, []string) {
|
||||
func getAttrs(attrs attribute.Set) ([]string, []string) {
|
||||
keys := make([]string, 0, attrs.Len())
|
||||
values := make([]string, 0, attrs.Len())
|
||||
itr := attrs.Iter()
|
||||
@@ -334,29 +346,17 @@ func getAttrs(attrs attribute.Set, ks, vs [2]string, resourceKV keyVals) ([]stri
|
||||
values = append(values, strings.Join(vals, ";"))
|
||||
}
|
||||
}
|
||||
|
||||
if ks[0] != "" {
|
||||
keys = append(keys, ks[:]...)
|
||||
values = append(values, vs[:]...)
|
||||
}
|
||||
|
||||
for idx := range resourceKV.keys {
|
||||
keys = append(keys, resourceKV.keys[idx])
|
||||
values = append(values, resourceKV.vals[idx])
|
||||
}
|
||||
|
||||
return keys, values
|
||||
}
|
||||
|
||||
func createInfoMetric(name, description string, res *resource.Resource) (prometheus.Metric, error) {
|
||||
keys, values := getAttrs(*res.Set(), [2]string{}, [2]string{}, keyVals{})
|
||||
keys, values := getAttrs(*res.Set())
|
||||
desc := prometheus.NewDesc(name, description, keys, nil)
|
||||
return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), values...)
|
||||
}
|
||||
|
||||
func createScopeInfoMetric(scope instrumentation.Scope) (prometheus.Metric, error) {
|
||||
keys := scopeInfoKeys[:]
|
||||
desc := prometheus.NewDesc(scopeInfoMetricName, scopeInfoDescription, keys, nil)
|
||||
desc := prometheus.NewDesc(scopeInfoMetricName, scopeInfoDescription, []string{scopeNameLabel, scopeVersionLabel}, nil)
|
||||
return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), scope.Name, scope.Version)
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ func (c *collector) createResourceAttributes(res *resource.Resource) {
|
||||
defer c.mu.Unlock()
|
||||
|
||||
resourceAttrs, _ := res.Set().Filter(c.resourceAttributesFilter)
|
||||
resourceKeys, resourceValues := getAttrs(resourceAttrs, [2]string{}, [2]string{}, keyVals{})
|
||||
resourceKeys, resourceValues := getAttrs(resourceAttrs)
|
||||
c.resourceKeyVals = keyVals{keys: resourceKeys, vals: resourceValues}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user