Skip to content

Commit faf3f01

Browse files
committed
Add producer support for Prometheus exporter as well
Signed-off-by: gouthamve <[email protected]>
1 parent 4b5bba4 commit faf3f01

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

exporters/autoexport/metrics.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,22 @@ func init() {
136136
})
137137
RegisterMetricReader("prometheus", func(ctx context.Context) (metric.Reader, error) {
138138
// create an isolated registry instead of using the global registry --
139-
// the user might not want to mix OTel with non-OTel metrics
139+
// the user might not want to mix OTel with non-OTel metrics.
140+
// Those that want to comingle metrics from global registry can use
141+
// OTEL_METRICS_PRODUCERS=prometheus
140142
reg := prometheus.NewRegistry()
141143

142-
reader, err := promexporter.New(promexporter.WithRegisterer(reg))
144+
exporterOpts := []promexporter.Option{promexporter.WithRegisterer(reg)}
145+
146+
producer, err := metricsProducers.create(ctx)
147+
if err != nil {
148+
return nil, err
149+
}
150+
if producer != nil {
151+
exporterOpts = append(exporterOpts, promexporter.WithProducer(producer))
152+
}
153+
154+
reader, err := promexporter.New(exporterOpts...)
143155
if err != nil {
144156
return nil, err
145157
}

exporters/autoexport/metrics_test.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net/http/httptest"
1212
"reflect"
1313
"runtime/debug"
14+
"strings"
1415
"testing"
1516

1617
"go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp"
@@ -122,7 +123,7 @@ func TestMetricExporterPrometheusInvalidPort(t *testing.T) {
122123
assert.ErrorContains(t, err, "binding")
123124
}
124125

125-
func TestMetricProducerPrometheus(t *testing.T) {
126+
func TestMetricProducerPrometheusWithOTLPExporter(t *testing.T) {
126127
assertNoOtelHandleErrors(t)
127128

128129
requestWaitChan := make(chan struct{})
@@ -150,12 +151,44 @@ func TestMetricProducerPrometheus(t *testing.T) {
150151
assert.IsType(t, &metric.PeriodicReader{}, r)
151152

152153
// Register it with a meter provider to ensure it is used.
153-
metric.NewMeterProvider(metric.WithReader(r))
154+
mp := metric.NewMeterProvider(metric.WithReader(r))
154155

155156
// Shutdown actually makes an export call.
156157
assert.NoError(t, r.Shutdown(context.Background()))
157158

158159
<-requestWaitChan
159160
ts.Close()
161+
assert.NoError(t, mp.Shutdown(context.Background()))
162+
goleak.VerifyNone(t)
163+
}
164+
165+
func TestMetricProducerPrometheusWithPrometheusExporter(t *testing.T) {
166+
assertNoOtelHandleErrors(t)
167+
168+
t.Setenv("OTEL_METRICS_EXPORTER", "prometheus")
169+
t.Setenv("OTEL_EXPORTER_PROMETHEUS_PORT", "0")
170+
t.Setenv("OTEL_METRICS_PRODUCERS", "prometheus")
171+
172+
r, err := NewMetricReader(context.Background())
173+
assert.NoError(t, err)
174+
175+
// pull-based exporters like Prometheus need to be registered
176+
mp := metric.NewMeterProvider(metric.WithReader(r))
177+
178+
rws, ok := r.(readerWithServer)
179+
if !ok {
180+
t.Errorf("expected readerWithServer but got %v", r)
181+
}
182+
183+
resp, err := http.Get(fmt.Sprintf("http://%s/metrics", rws.addr))
184+
assert.NoError(t, err)
185+
body, err := io.ReadAll(resp.Body)
186+
assert.NoError(t, err)
187+
188+
// By default there are two metrics exporter. target_info and promhttp_metric_handler_errors_total.
189+
// But by including the prometheus producer we should have more.
190+
assert.Greater(t, strings.Count(string(body), "# HELP"), 2)
191+
192+
assert.NoError(t, mp.Shutdown(context.Background()))
160193
goleak.VerifyNone(t)
161194
}

0 commit comments

Comments
 (0)