Skip to content

Commit 39eeba4

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

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

exporters/autoexport/metrics.go

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

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

exporters/autoexport/metrics_test.go

Lines changed: 34 additions & 1 deletion
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,6 +151,7 @@ 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.
154+
// mp.Shutdown errors out because r.Shutdown closes the reader.
153155
metric.NewMeterProvider(metric.WithReader(r))
154156

155157
// Shutdown actually makes an export call.
@@ -159,3 +161,34 @@ func TestMetricProducerPrometheus(t *testing.T) {
159161
ts.Close()
160162
goleak.VerifyNone(t)
161163
}
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()))
193+
goleak.VerifyNone(t)
194+
}

0 commit comments

Comments
 (0)