Skip to content

Commit f556bd3

Browse files
authored
prometheus: use a sync.Pool instead of allocating metricdata.ResourceMetrics in Collect (#6472)
Fix #3047 Use a `sync.Pool` instead of allocating `metricdata.ResourceMetrics` in `go.opentelemetry.io/otel/exporters/prometheus` ```shell goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/exporters/prometheus cpu: Apple M3 │ before.txt │ after.txt │ │ sec/op │ sec/op vs base │ Collect1-8 8.273µ ± 0% 8.013µ ± 5% ~ (p=0.065 n=6) Collect10-8 23.84µ ± 0% 22.40µ ± 3% -6.02% (p=0.002 n=6) Collect100-8 148.0µ ± 0% 139.4µ ± 0% -5.84% (p=0.002 n=6) Collect1000-8 1.326m ± 0% 1.244m ± 1% -6.14% (p=0.002 n=6) Collect10000-8 15.90m ± 1% 14.51m ± 1% -8.77% (p=0.002 n=6) geomean 227.9µ 214.3µ -6.00% │ before.txt │ after.txt │ │ B/op │ B/op vs base │ Collect1-8 35.65Ki ± 0% 34.49Ki ± 0% -3.24% (p=0.002 n=6) Collect10-8 55.78Ki ± 0% 45.57Ki ± 0% -18.31% (p=0.002 n=6) Collect100-8 260.8Ki ± 0% 174.1Ki ± 0% -33.23% (p=0.002 n=6) Collect1000-8 2.307Mi ± 0% 1.537Mi ± 1% -33.38% (p=0.002 n=6) Collect10000-8 22.47Mi ± 0% 14.75Mi ± 4% -34.36% (p=0.002 n=6) geomean 489.8Ki 365.3Ki -25.42% │ before.txt │ after.txt │ │ allocs/op │ allocs/op vs base │ Collect1-8 72.00 ± 0% 66.00 ± 0% -8.33% (p=0.002 n=6) Collect10-8 398.0 ± 0% 375.0 ± 0% -5.78% (p=0.002 n=6) Collect100-8 3.662k ± 0% 3.491k ± 0% -4.67% (p=0.002 n=6) Collect1000-8 36.15k ± 0% 34.62k ± 0% -4.24% (p=0.002 n=6) Collect10000-8 361.0k ± 0% 345.7k ± 0% -4.25% (p=0.002 n=6) geomean 4.239k 4.008k -5.47% ```
1 parent 1b8fe16 commit f556bd3

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2424

2525
- Stop percent encoding header environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6392)
2626
- Ensure the `noopSpan.tracerProvider` method is not inlined in `go.opentelemetry.io/otel/trace` so the `go.opentelemetry.io/auto` instrumentation can instrument non-recording spans. (#6456)
27+
- Use a `sync.Pool` instead of allocating `metricdata.ResourceMetrics` in `go.opentelemetry.io/otel/exporters/prometheus`. (#6472)
2728

2829
<!-- Released section -->
2930
<!-- Don't change this section unless doing release -->

exporters/prometheus/exporter.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,15 @@ const (
4040
spanIDExemplarKey = "span_id"
4141
)
4242

43-
var errScopeInvalid = errors.New("invalid scope")
43+
var (
44+
errScopeInvalid = errors.New("invalid scope")
45+
46+
metricsPool = sync.Pool{
47+
New: func() interface{} {
48+
return &metricdata.ResourceMetrics{}
49+
},
50+
}
51+
)
4452

4553
// Exporter is a Prometheus Exporter that embeds the OTel metric.Reader
4654
// interface for easy instantiation with a MeterProvider.
@@ -144,9 +152,9 @@ func (c *collector) Describe(ch chan<- *prometheus.Desc) {
144152
//
145153
// This method is safe to call concurrently.
146154
func (c *collector) Collect(ch chan<- prometheus.Metric) {
147-
// TODO (#3047): Use a sync.Pool instead of allocating metrics every Collect.
148-
metrics := metricdata.ResourceMetrics{}
149-
err := c.reader.Collect(context.TODO(), &metrics)
155+
metrics := metricsPool.Get().(*metricdata.ResourceMetrics)
156+
defer metricsPool.Put(metrics)
157+
err := c.reader.Collect(context.TODO(), metrics)
150158
if err != nil {
151159
if errors.Is(err, metric.ErrReaderShutdown) {
152160
return

0 commit comments

Comments
 (0)