From bd921afde8e33d46c6f1586b0182cee1addc391e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 3 Aug 2020 18:25:19 -0700 Subject: [PATCH] Migrate Prometheus to the new MetricsExporter interface (#1477) Signed-off-by: Bogdan Drutu --- exporter/prometheusexporter/config_test.go | 2 +- exporter/prometheusexporter/factory.go | 32 ++++++++----------- exporter/prometheusexporter/factory_test.go | 26 ++++++--------- exporter/prometheusexporter/prometheus.go | 23 ++++++------- .../prometheusexporter/prometheus_test.go | 31 +++++++++++------- service/defaultcomponents/defaults.go | 2 +- 6 files changed, 57 insertions(+), 59 deletions(-) diff --git a/exporter/prometheusexporter/config_test.go b/exporter/prometheusexporter/config_test.go index 93cc4434467..90d955fd408 100644 --- a/exporter/prometheusexporter/config_test.go +++ b/exporter/prometheusexporter/config_test.go @@ -30,7 +30,7 @@ func TestLoadConfig(t *testing.T) { factories, err := componenttest.ExampleComponents() assert.NoError(t, err) - factory := &Factory{} + factory := NewFactory() factories.Exporters[typeStr] = factory cfg, err := configtest.LoadConfigFile(t, path.Join(".", "testdata", "config.yaml"), factories) diff --git a/exporter/prometheusexporter/factory.go b/exporter/prometheusexporter/factory.go index 75a6be9f9bd..f47ad4cf2a9 100644 --- a/exporter/prometheusexporter/factory.go +++ b/exporter/prometheusexporter/factory.go @@ -15,16 +15,16 @@ package prometheusexporter import ( + "context" "net" "net/http" "strings" "github.com/orijtech/prometheus-go-metrics-exporter" - "go.uber.org/zap" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/configerror" "go.opentelemetry.io/collector/config/configmodels" + "go.opentelemetry.io/collector/exporter/exporterhelper" ) const ( @@ -32,17 +32,15 @@ const ( typeStr = "prometheus" ) -// Factory is the factory for Prometheus exporter. -type Factory struct { +// NewFactory creates a factory for OTLP exporter. +func NewFactory() component.ExporterFactory { + return exporterhelper.NewFactory( + typeStr, + createDefaultConfig, + exporterhelper.WithMetrics(createMetricsExporter)) } -// Type gets the type of the Exporter config created by this factory. -func (f *Factory) Type() configmodels.Type { - return typeStr -} - -// CreateDefaultConfig creates the default configuration for exporter. -func (f *Factory) CreateDefaultConfig() configmodels.Exporter { +func createDefaultConfig() configmodels.Exporter { return &Config{ ExporterSettings: configmodels.ExporterSettings{ TypeVal: typeStr, @@ -52,13 +50,11 @@ func (f *Factory) CreateDefaultConfig() configmodels.Exporter { } } -// CreateTraceExporter creates a trace exporter based on this config. -func (f *Factory) CreateTraceExporter(logger *zap.Logger, config configmodels.Exporter) (component.TraceExporterOld, error) { - return nil, configerror.ErrDataTypeIsNotSupported -} - -// CreateMetricsExporter creates a metrics exporter based on this config. -func (f *Factory) CreateMetricsExporter(logger *zap.Logger, cfg configmodels.Exporter) (component.MetricsExporterOld, error) { +func createMetricsExporter( + _ context.Context, + _ component.ExporterCreateParams, + cfg configmodels.Exporter, +) (component.MetricsExporter, error) { pcfg := cfg.(*Config) addr := strings.TrimSpace(pcfg.Endpoint) diff --git a/exporter/prometheusexporter/factory_test.go b/exporter/prometheusexporter/factory_test.go index b480351c3f3..7981dd145b0 100644 --- a/exporter/prometheusexporter/factory_test.go +++ b/exporter/prometheusexporter/factory_test.go @@ -15,39 +15,31 @@ package prometheusexporter import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configcheck" - "go.opentelemetry.io/collector/config/configerror" ) func TestCreateDefaultConfig(t *testing.T) { - factory := Factory{} - require.NotNil(t, factory) - - cfg := factory.CreateDefaultConfig() + cfg := createDefaultConfig() assert.NotNil(t, cfg, "failed to create default config") assert.NoError(t, configcheck.ValidateConfig(cfg)) } -func TestCreateTraceExporter(t *testing.T) { - factory := Factory{} - cfg := factory.CreateDefaultConfig() - - _, err := factory.CreateTraceExporter(zap.NewNop(), cfg) - assert.Error(t, err, configerror.ErrDataTypeIsNotSupported) -} - func TestCreateMetricsExporter(t *testing.T) { - factory := Factory{} - cfg := factory.CreateDefaultConfig() + cfg := createDefaultConfig() oCfg := cfg.(*Config) oCfg.Endpoint = "" - consumer, err := factory.CreateMetricsExporter(zap.NewNop(), oCfg) + exp, err := createMetricsExporter( + context.Background(), + component.ExporterCreateParams{Logger: zap.NewNop()}, + cfg) require.Equal(t, errBlankPrometheusAddress, err) - require.Nil(t, consumer) + require.Nil(t, exp) } diff --git a/exporter/prometheusexporter/prometheus.go b/exporter/prometheusexporter/prometheus.go index b38bb1e99f7..02565f7cd93 100644 --- a/exporter/prometheusexporter/prometheus.go +++ b/exporter/prometheusexporter/prometheus.go @@ -25,8 +25,8 @@ import ( "github.com/orijtech/prometheus-go-metrics-exporter" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/consumer" - "go.opentelemetry.io/collector/consumer/consumerdata" + "go.opentelemetry.io/collector/consumer/pdata" + "go.opentelemetry.io/collector/consumer/pdatautil" ) var errBlankPrometheusAddress = errors.New("expecting a non-blank address to run the Prometheus metrics handler") @@ -37,19 +37,20 @@ type prometheusExporter struct { shutdownFunc func() error } -var _ consumer.MetricsConsumerOld = (*prometheusExporter)(nil) - func (pe *prometheusExporter) Start(_ context.Context, _ component.Host) error { return nil } -func (pe *prometheusExporter) ConsumeMetricsData(ctx context.Context, md consumerdata.MetricsData) error { - merged := make(map[string]*metricspb.Metric) - for _, metric := range md.Metrics { - merge(merged, metric) - } - for _, metric := range merged { - _ = pe.exporter.ExportMetric(ctx, md.Node, md.Resource, metric) +func (pe *prometheusExporter) ConsumeMetrics(ctx context.Context, md pdata.Metrics) error { + ocmds := pdatautil.MetricsToMetricsData(md) + for _, ocmd := range ocmds { + merged := make(map[string]*metricspb.Metric) + for _, metric := range ocmd.Metrics { + merge(merged, metric) + } + for _, metric := range merged { + _ = pe.exporter.ExportMetric(ctx, ocmd.Node, ocmd.Resource, metric) + } } return nil } diff --git a/exporter/prometheusexporter/prometheus_test.go b/exporter/prometheusexporter/prometheus_test.go index 4f9ab0423bb..2522f5fff26 100644 --- a/exporter/prometheusexporter/prometheus_test.go +++ b/exporter/prometheusexporter/prometheus_test.go @@ -28,7 +28,9 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer/consumerdata" + "go.opentelemetry.io/collector/consumer/pdatautil" ) func TestPrometheusExporter(t *testing.T) { @@ -52,21 +54,24 @@ func TestPrometheusExporter(t *testing.T) { }, } - factory := Factory{} + factory := NewFactory() + creationParams := component.ExporterCreateParams{Logger: zap.NewNop()} for _, tt := range tests { // Run it a few times to ensure that shutdowns exit cleanly. for j := 0; j < 3; j++ { - consumer, err := factory.CreateMetricsExporter(zap.NewNop(), tt.config) + exp, err := factory.CreateMetricsExporter(context.Background(), creationParams, tt.config) if tt.wantErr != "" { - require.Equal(t, tt.wantErr, err.Error()) + require.Error(t, err) + assert.Equal(t, tt.wantErr, err.Error()) continue + } else { + require.NoError(t, err) } - assert.NotNil(t, consumer) - + assert.NotNil(t, exp) require.Nil(t, err) - require.NoError(t, consumer.Shutdown(context.Background())) + require.NoError(t, exp.Shutdown(context.Background())) } } } @@ -81,16 +86,20 @@ func TestPrometheusExporter_endToEnd(t *testing.T) { Endpoint: ":7777", } - factory := Factory{} - consumer, err := factory.CreateMetricsExporter(zap.NewNop(), config) + factory := NewFactory() + creationParams := component.ExporterCreateParams{Logger: zap.NewNop()} + exp, err := factory.CreateMetricsExporter(context.Background(), creationParams, config) assert.NoError(t, err) - defer consumer.Shutdown(context.Background()) + t.Cleanup(func() { + require.NoError(t, exp.Shutdown(context.Background())) + }) - assert.NotNil(t, consumer) + assert.NotNil(t, exp) for delta := 0; delta <= 20; delta += 10 { - consumer.ConsumeMetricsData(context.Background(), consumerdata.MetricsData{Metrics: metricBuilder(int64(delta))}) + md := pdatautil.MetricsFromMetricsData([]consumerdata.MetricsData{{Metrics: metricBuilder(int64(delta))}}) + assert.NoError(t, exp.ConsumeMetrics(context.Background(), md)) res, err := http.Get("http://localhost:7777/metrics") require.NoError(t, err, "Failed to perform a scrape") diff --git a/service/defaultcomponents/defaults.go b/service/defaultcomponents/defaults.go index f85e49039d6..5e83bfd73a8 100644 --- a/service/defaultcomponents/defaults.go +++ b/service/defaultcomponents/defaults.go @@ -81,7 +81,7 @@ func Components() ( exporters, err := component.MakeExporterFactoryMap( &opencensusexporter.Factory{}, - &prometheusexporter.Factory{}, + prometheusexporter.NewFactory(), loggingexporter.NewFactory(), zipkinexporter.NewFactory(), jaegerexporter.NewFactory(),