diff --git a/receiver/opencensusreceiver/testdata/config.yaml b/receiver/opencensusreceiver/testdata/config.yaml index 7a1d4a6511c..4bd8f55b94e 100644 --- a/receiver/opencensusreceiver/testdata/config.yaml +++ b/receiver/opencensusreceiver/testdata/config.yaml @@ -11,7 +11,7 @@ exporters: pipelines: traces: - receivers: [opencensus] - processors: [exampleprocessor] - exporters: [exampleexporter] + receivers: [opencensus] + processors: [exampleprocessor] + exporters: [exampleexporter] diff --git a/receiver/zipkinreceiver/config.go b/receiver/prometheusreceiver/config.go similarity index 60% rename from receiver/zipkinreceiver/config.go rename to receiver/prometheusreceiver/config.go index f31305a0a2b..eca2a108e9b 100644 --- a/receiver/zipkinreceiver/config.go +++ b/receiver/prometheusreceiver/config.go @@ -12,11 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -package zipkinreceiver +package prometheusreceiver -import "github.com/open-telemetry/opentelemetry-service/internal/configmodels" +import ( + "time" -// ConfigV2 defines configuration for Zipkin receiver. + "github.com/prometheus/prometheus/config" + + "github.com/open-telemetry/opentelemetry-service/internal/configmodels" +) + +// ConfigV2 defines configuration for Prometheus receiver. type ConfigV2 struct { configmodels.ReceiverSettings `mapstructure:",squash"` + PrometheusConfig *config.Config `mapstructure:"-"` + BufferPeriod time.Duration `mapstructure:"buffer_period"` + BufferCount int `mapstructure:"buffer_count"` } diff --git a/receiver/zipkinreceiver/config_test.go b/receiver/prometheusreceiver/config_test.go similarity index 73% rename from receiver/zipkinreceiver/config_test.go rename to receiver/prometheusreceiver/config_test.go index 7136262a6d8..cf24cddb8c9 100644 --- a/receiver/zipkinreceiver/config_test.go +++ b/receiver/prometheusreceiver/config_test.go @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package zipkinreceiver +package prometheusreceiver import ( "path" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -38,17 +39,16 @@ func TestLoadConfig(t *testing.T) { assert.Equal(t, len(config.Receivers), 2) - r0 := config.Receivers["zipkin"] + r0 := config.Receivers["prometheus"] assert.Equal(t, r0, factory.CreateDefaultConfig()) - r1 := config.Receivers["zipkin/customname"].(*ConfigV2) - assert.Equal(t, r1, - &ConfigV2{ - ReceiverSettings: configmodels.ReceiverSettings{ - TypeVal: typeStr, - NameVal: "zipkin/customname", - Endpoint: "127.0.0.1:8765", - Enabled: true, - }, + r1 := config.Receivers["prometheus/customname"].(*ConfigV2) + assert.Equal(t, r1.ReceiverSettings, + configmodels.ReceiverSettings{ + TypeVal: typeStr, + NameVal: "prometheus/customname", + Endpoint: "1.2.3.4:456", }) + assert.Equal(t, r1.PrometheusConfig.ScrapeConfigs[0].JobName, "demo") + assert.Equal(t, time.Duration(r1.PrometheusConfig.ScrapeConfigs[0].ScrapeInterval), 5*time.Second) } diff --git a/receiver/prometheusreceiver/factory.go b/receiver/prometheusreceiver/factory.go new file mode 100644 index 00000000000..2196735cf53 --- /dev/null +++ b/receiver/prometheusreceiver/factory.go @@ -0,0 +1,131 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package prometheusreceiver + +import ( + "context" + "fmt" + + "github.com/spf13/viper" + "gopkg.in/yaml.v2" + + "github.com/open-telemetry/opentelemetry-service/consumer" + "github.com/open-telemetry/opentelemetry-service/internal/configmodels" + "github.com/open-telemetry/opentelemetry-service/internal/factories" + "github.com/open-telemetry/opentelemetry-service/receiver" +) + +// This file implements config V2 for Prometheus receiver. + +var _ = factories.RegisterReceiverFactory(&ReceiverFactory{}) + +const ( + // The value of "type" key in configuration. + typeStr = "prometheus" +) + +// ReceiverFactory is the factory for receiver. +type ReceiverFactory struct { +} + +// Type gets the type of the Receiver config created by this factory. +func (f *ReceiverFactory) Type() string { + return typeStr +} + +// CustomUnmarshaler returns custom unmarshaler for this config. +func (f *ReceiverFactory) CustomUnmarshaler() factories.CustomUnmarshaler { + return CustomUnmarshalerFunc +} + +// CustomUnmarshalerFunc performs custom unmarshaling of config. +func CustomUnmarshalerFunc(v *viper.Viper, viperKey string, intoCfg interface{}) error { + // We need custom unmarshaling because prometheus "config" subkey defines its own + // YAML unmarshaling routines so we need to do it explicitly. + + // Unmarshal our config values (using viper's mapstructure) + err := v.UnmarshalKey(viperKey, intoCfg) + if err != nil { + return fmt.Errorf("prometheus receiver failed to parse config: %s", err) + } + + // Unmarshal prometheus's config values. Since prometheus uses `yaml` tags, so use `yaml`. + vSub := v.Sub(viperKey) + if vSub == nil || !vSub.IsSet(prometheusConfigKey) { + return nil + } + promCfgMap := vSub.Sub(prometheusConfigKey).AllSettings() + out, err := yaml.Marshal(promCfgMap) + if err != nil { + return fmt.Errorf("prometheus receiver failed to marshal config to yaml: %s", err) + } + + config := intoCfg.(*ConfigV2) + + err = yaml.Unmarshal(out, &config.PrometheusConfig) + if err != nil { + return fmt.Errorf("prometheus receiver failed to unmarshal yaml to prometheus config: %s", err) + } + if len(config.PrometheusConfig.ScrapeConfigs) == 0 { + return errNilScrapeConfig + } + return nil +} + +// CreateDefaultConfig creates the default configuration for receiver. +func (f *ReceiverFactory) CreateDefaultConfig() configmodels.Receiver { + return &ConfigV2{ + ReceiverSettings: configmodels.ReceiverSettings{ + TypeVal: typeStr, + NameVal: typeStr, + Endpoint: "127.0.0.1:9090", + }, + } +} + +// CreateTraceReceiver creates a trace receiver based on provided config. +func (f *ReceiverFactory) CreateTraceReceiver( + ctx context.Context, + cfg configmodels.Receiver, + nextConsumer consumer.TraceConsumer, +) (receiver.TraceReceiver, error) { + // VMMetrics do not support traces + return nil, factories.ErrDataTypeIsNotSupported +} + +// CreateMetricsReceiver creates a metrics receiver based on provided config. +func (f *ReceiverFactory) CreateMetricsReceiver( + cfg configmodels.Receiver, + consumer consumer.MetricsConsumer, +) (receiver.MetricsReceiver, error) { + + rCfg := cfg.(*ConfigV2) + + // Create receiver Configuration from our input cfg + config := Configuration{ + BufferCount: rCfg.BufferCount, + BufferPeriod: rCfg.BufferPeriod, + ScrapeConfig: rCfg.PrometheusConfig, + } + + if config.ScrapeConfig == nil || len(config.ScrapeConfig.ScrapeConfigs) == 0 { + return nil, errNilScrapeConfig + } + pr := &Preceiver{ + cfg: &config, + consumer: consumer, + } + return pr, nil +} diff --git a/receiver/zipkinreceiver/factory_test.go b/receiver/prometheusreceiver/factory_test.go similarity index 78% rename from receiver/zipkinreceiver/factory_test.go rename to receiver/prometheusreceiver/factory_test.go index 37aabce9f85..3089d2fbffe 100644 --- a/receiver/zipkinreceiver/factory_test.go +++ b/receiver/prometheusreceiver/factory_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package zipkinreceiver +package prometheusreceiver import ( "context" @@ -20,7 +20,6 @@ import ( "github.com/stretchr/testify/assert" - "github.com/open-telemetry/opentelemetry-service/data" "github.com/open-telemetry/opentelemetry-service/internal/factories" ) @@ -30,20 +29,17 @@ func TestCreateDefaultConfig(t *testing.T) { assert.NotNil(t, cfg, "failed to create default config") } -type mockTraceConsumer struct { -} - -func (m *mockTraceConsumer) ConsumeTraceData(ctx context.Context, td data.TraceData) error { return nil } - func TestCreateReceiver(t *testing.T) { factory := factories.GetReceiverFactory(typeStr) cfg := factory.CreateDefaultConfig() - tReceiver, err := factory.CreateTraceReceiver(context.Background(), cfg, &mockTraceConsumer{}) - assert.Nil(t, err, "receiver creation failed") - assert.NotNil(t, tReceiver, "receiver creation failed") + tReceiver, err := factory.CreateTraceReceiver(context.Background(), cfg, nil) + assert.Equal(t, err, factories.ErrDataTypeIsNotSupported) + assert.Nil(t, tReceiver) + // The default config does not provide scrape_config so we expect that metrics receiver + // creation must also fail. mReceiver, err := factory.CreateMetricsReceiver(cfg, nil) - assert.Equal(t, err, factories.ErrDataTypeIsNotSupported) + assert.Equal(t, err, errNilScrapeConfig) assert.Nil(t, mReceiver) } diff --git a/receiver/prometheusreceiver/testdata/config.yaml b/receiver/prometheusreceiver/testdata/config.yaml new file mode 100644 index 00000000000..45753058d78 --- /dev/null +++ b/receiver/prometheusreceiver/testdata/config.yaml @@ -0,0 +1,22 @@ +receivers: + prometheus: + prometheus/customname: + endpoint: "1.2.3.4:456" + buffer_period: 234 + buffer_count: 45 + config: + scrape_configs: + - job_name: 'demo' + scrape_interval: 5s + +processors: + exampleprocessor: + +exporters: + exampleexporter: + +pipelines: + traces: + receivers: [prometheus] + processors: [exampleprocessor] + exporters: [exampleexporter] diff --git a/receiver/zipkinreceiver/factory.go b/receiver/zipkinreceiver/factory.go deleted file mode 100644 index 36b82c974f2..00000000000 --- a/receiver/zipkinreceiver/factory.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2019, OpenCensus Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package zipkinreceiver - -import ( - "context" - - "github.com/open-telemetry/opentelemetry-service/consumer" - "github.com/open-telemetry/opentelemetry-service/internal/configmodels" - "github.com/open-telemetry/opentelemetry-service/internal/factories" - "github.com/open-telemetry/opentelemetry-service/receiver" -) - -// This file implements factory for Zipkin receiver. - -var _ = factories.RegisterReceiverFactory(&ReceiverFactory{}) - -const ( - // The value of "type" key in configuration. - typeStr = "zipkin" - - defaultBindEndpoint = "127.0.0.1:9411" -) - -// ReceiverFactory is the factory for Zipkin receiver. -type ReceiverFactory struct { -} - -// Type gets the type of the Receiver config created by this factory. -func (f *ReceiverFactory) Type() string { - return typeStr -} - -// CustomUnmarshaler returns nil because we don't need custom unmarshaling for this config. -func (f *ReceiverFactory) CustomUnmarshaler() factories.CustomUnmarshaler { - return nil -} - -// CreateDefaultConfig creates the default configuration for Jaeger receiver. -func (f *ReceiverFactory) CreateDefaultConfig() configmodels.Receiver { - return &ConfigV2{ - ReceiverSettings: configmodels.ReceiverSettings{ - TypeVal: typeStr, - NameVal: typeStr, - Endpoint: defaultBindEndpoint, - }, - } -} - -// CreateTraceReceiver creates a trace receiver based on provided config. -func (f *ReceiverFactory) CreateTraceReceiver( - ctx context.Context, - cfg configmodels.Receiver, - nextConsumer consumer.TraceConsumer, -) (receiver.TraceReceiver, error) { - - rCfg := cfg.(*ConfigV2) - return New(rCfg.Endpoint, nextConsumer) -} - -// CreateMetricsReceiver creates a metrics receiver based on provided config. -func (f *ReceiverFactory) CreateMetricsReceiver( - cfg configmodels.Receiver, - consumer consumer.MetricsConsumer, -) (receiver.MetricsReceiver, error) { - return nil, factories.ErrDataTypeIsNotSupported -} diff --git a/receiver/zipkinreceiver/testdata/config.yaml b/receiver/zipkinreceiver/testdata/config.yaml deleted file mode 100644 index bf6e7af9c88..00000000000 --- a/receiver/zipkinreceiver/testdata/config.yaml +++ /dev/null @@ -1,18 +0,0 @@ -receivers: - zipkin: - zipkin/customname: - endpoint: "127.0.0.1:8765" - enabled: true - -processors: - exampleprocessor: - -exporters: - exampleexporter: - -pipelines: - traces: - receivers: [zipkin] - processors: [exampleprocessor] - exporters: [exampleexporter] -