Skip to content

Commit

Permalink
Add producer support for Prometheus exporter as well
Browse files Browse the repository at this point in the history
Signed-off-by: gouthamve <gouthamve@gmail.com>
  • Loading branch information
gouthamve committed Apr 14, 2024
1 parent 4481431 commit 1155097
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
16 changes: 14 additions & 2 deletions exporters/autoexport/metrics.go
Expand Up @@ -136,10 +136,22 @@ func init() {
})
RegisterMetricReader("prometheus", func(ctx context.Context) (metric.Reader, error) {
// create an isolated registry instead of using the global registry --
// the user might not want to mix OTel with non-OTel metrics
// the user might not want to mix OTel with non-OTel metrics.
// Those that want to comingle metrics from global registry can use
// OTEL_METRICS_PRODUCERS=prometheus
reg := prometheus.NewRegistry()

reader, err := promexporter.New(promexporter.WithRegisterer(reg))
exporterOpts := []promexporter.Option{promexporter.WithRegisterer(reg)}

producer, err := metricsProducers.create(ctx)
if err != nil {
return nil, err
}
if producer != nil {
exporterOpts = append(exporterOpts, promexporter.WithProducer(producer))
}

reader, err := promexporter.New(exporterOpts...)
if err != nil {
return nil, err
}
Expand Down
37 changes: 35 additions & 2 deletions exporters/autoexport/metrics_test.go
Expand Up @@ -11,6 +11,7 @@ import (
"net/http/httptest"
"reflect"
"runtime/debug"
"strings"
"testing"

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

func TestMetricProducerPrometheus(t *testing.T) {
func TestMetricProducerPrometheusWithOTLPExporter(t *testing.T) {
assertNoOtelHandleErrors(t)

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

// Register it with a meter provider to ensure it is used.
metric.NewMeterProvider(metric.WithReader(r))
mp := metric.NewMeterProvider(metric.WithReader(r))

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

<-requestWaitChan
ts.Close()
assert.NoError(t, mp.Shutdown(context.Background()))
goleak.VerifyNone(t)
}

func TestMetricProducerPrometheusWithPrometheusExporter(t *testing.T) {
assertNoOtelHandleErrors(t)

t.Setenv("OTEL_METRICS_EXPORTER", "prometheus")
t.Setenv("OTEL_EXPORTER_PROMETHEUS_PORT", "0")
t.Setenv("OTEL_METRICS_PRODUCERS", "prometheus")

r, err := NewMetricReader(context.Background())
assert.NoError(t, err)

// pull-based exporters like Prometheus need to be registered
mp := metric.NewMeterProvider(metric.WithReader(r))

rws, ok := r.(readerWithServer)
if !ok {
t.Errorf("expected readerWithServer but got %v", r)
}

resp, err := http.Get(fmt.Sprintf("http://%s/metrics", rws.addr))
assert.NoError(t, err)
body, err := io.ReadAll(resp.Body)
assert.NoError(t, err)

// By default there are two metrics exporter. target_info and promhttp_metric_handler_errors_total.
// But by including the prometheus producer we should have more.
assert.Greater(t, strings.Count(string(body), "# HELP"), 2)

assert.NoError(t, mp.Shutdown(context.Background()))
goleak.VerifyNone(t)
}

0 comments on commit 1155097

Please sign in to comment.