opentelemetry-collector/config/example_factories.go

453 lines
15 KiB
Go

// Copyright 2019, OpenTelemetry 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 config
import (
"context"
"fmt"
"go.uber.org/zap"
"github.com/open-telemetry/opentelemetry-collector/component"
"github.com/open-telemetry/opentelemetry-collector/config/configerror"
"github.com/open-telemetry/opentelemetry-collector/config/configmodels"
"github.com/open-telemetry/opentelemetry-collector/consumer"
"github.com/open-telemetry/opentelemetry-collector/consumer/consumerdata"
"github.com/open-telemetry/opentelemetry-collector/exporter"
"github.com/open-telemetry/opentelemetry-collector/extension"
"github.com/open-telemetry/opentelemetry-collector/processor"
"github.com/open-telemetry/opentelemetry-collector/receiver"
)
// ExampleReceiver is for testing purposes. We are defining an example config and factory
// for "examplereceiver" receiver type.
type ExampleReceiver struct {
configmodels.ReceiverSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
ExtraSetting string `mapstructure:"extra"`
ExtraMapSetting map[string]string `mapstructure:"extra_map"`
ExtraListSetting []string `mapstructure:"extra_list"`
// FailTraceCreation causes CreateTraceReceiver to fail. Useful for testing.
FailTraceCreation bool `mapstructure:"-"`
// FailMetricsCreation causes CreateTraceReceiver to fail. Useful for testing.
FailMetricsCreation bool `mapstructure:"-"`
}
// ExampleReceiverFactory is factory for ExampleReceiver.
type ExampleReceiverFactory struct {
}
// Type gets the type of the Receiver config created by this factory.
func (f *ExampleReceiverFactory) Type() string {
return "examplereceiver"
}
// CustomUnmarshaler returns nil because we don't need custom unmarshaling for this factory.
func (f *ExampleReceiverFactory) CustomUnmarshaler() receiver.CustomUnmarshaler {
return nil
}
// CreateDefaultConfig creates the default configuration for the Receiver.
func (f *ExampleReceiverFactory) CreateDefaultConfig() configmodels.Receiver {
return &ExampleReceiver{
ReceiverSettings: configmodels.ReceiverSettings{
TypeVal: "examplereceiver",
Endpoint: "localhost:1000",
},
ExtraSetting: "some string",
ExtraMapSetting: nil,
ExtraListSetting: nil,
}
}
// CreateTraceReceiver creates a trace receiver based on this config.
func (f *ExampleReceiverFactory) CreateTraceReceiver(
ctx context.Context,
logger *zap.Logger,
cfg configmodels.Receiver,
nextConsumer consumer.TraceConsumer,
) (receiver.TraceReceiver, error) {
if cfg.(*ExampleReceiver).FailTraceCreation {
return nil, configerror.ErrDataTypeIsNotSupported
}
// There must be one receiver for both metrics and traces. We maintain a map of
// receivers per config.
// Check to see if there is already a receiver for this config.
receiver, ok := exampleReceivers[cfg]
if !ok {
receiver = &ExampleReceiverProducer{}
// Remember the receiver in the map
exampleReceivers[cfg] = receiver
}
receiver.TraceConsumer = nextConsumer
return receiver, nil
}
// CreateMetricsReceiver creates a metrics receiver based on this config.
func (f *ExampleReceiverFactory) CreateMetricsReceiver(
logger *zap.Logger,
cfg configmodels.Receiver,
nextConsumer consumer.MetricsConsumer,
) (receiver.MetricsReceiver, error) {
if cfg.(*ExampleReceiver).FailMetricsCreation {
return nil, configerror.ErrDataTypeIsNotSupported
}
// There must be one receiver for both metrics and traces. We maintain a map of
// receivers per config.
// Check to see if there is already a receiver for this config.
receiver, ok := exampleReceivers[cfg]
if !ok {
receiver = &ExampleReceiverProducer{}
// Remember the receiver in the map
exampleReceivers[cfg] = receiver
}
receiver.MetricsConsumer = nextConsumer
return receiver, nil
}
// ExampleReceiverProducer allows producing traces and metrics for testing purposes.
type ExampleReceiverProducer struct {
TraceConsumer consumer.TraceConsumer
Started bool
Stopped bool
MetricsConsumer consumer.MetricsConsumer
}
// TraceSource returns the name of the trace data source.
func (erp *ExampleReceiverProducer) TraceSource() string {
return ""
}
// Start tells the receiver to start its processing.
func (erp *ExampleReceiverProducer) Start(host component.Host) error {
erp.Started = true
return nil
}
// Shutdown tells the receiver that should stop reception,
func (erp *ExampleReceiverProducer) Shutdown() error {
erp.Stopped = true
return nil
}
// MetricsSource returns the name of the metrics data source.
func (erp *ExampleReceiverProducer) MetricsSource() string {
return ""
}
// This is the map of already created example receivers for particular configurations.
// We maintain this map because the Factory is asked trace and metric receivers separately
// when it gets CreateTraceReceiver() and CreateMetricsReceiver() but they must not
// create separate objects, they must use one Receiver object per configuration.
var exampleReceivers = map[configmodels.Receiver]*ExampleReceiverProducer{}
// MultiProtoReceiver is for testing purposes. We are defining an example multi protocol
// config and factory for "multireceiver" receiver type.
type MultiProtoReceiver struct {
TypeVal string `mapstructure:"-"`
NameVal string `mapstructure:"-"`
Protocols map[string]MultiProtoReceiverOneCfg `mapstructure:"protocols"`
}
var _ configmodels.Receiver = (*MultiProtoReceiver)(nil)
// Name gets the exporter name.
func (rs *MultiProtoReceiver) Name() string {
return rs.NameVal
}
// SetName sets the receiver name.
func (rs *MultiProtoReceiver) SetName(name string) {
rs.NameVal = name
}
// Type sets the receiver type.
func (rs *MultiProtoReceiver) Type() string {
return rs.TypeVal
}
// SetType sets the receiver type.
func (rs *MultiProtoReceiver) SetType(typeStr string) {
rs.TypeVal = typeStr
}
// IsEnabled returns true if the entity is enabled.
func (rs *MultiProtoReceiver) IsEnabled() bool {
for _, p := range rs.Protocols {
if !p.Disabled {
// If any protocol is enabled then the receiver as a whole should be enabled.
return true
}
}
// All protocols are disabled so the entire receiver can be disabled.
return false
}
// MultiProtoReceiverOneCfg is multi proto receiver config.
type MultiProtoReceiverOneCfg struct {
Disabled bool `mapstructure:"disabled"`
Endpoint string `mapstructure:"endpoint"`
ExtraSetting string `mapstructure:"extra"`
}
// MultiProtoReceiverFactory is factory for MultiProtoReceiver.
type MultiProtoReceiverFactory struct {
}
// Type gets the type of the Receiver config created by this factory.
func (f *MultiProtoReceiverFactory) Type() string {
return "multireceiver"
}
// CustomUnmarshaler returns nil because we don't need custom unmarshaling for this factory.
func (f *MultiProtoReceiverFactory) CustomUnmarshaler() receiver.CustomUnmarshaler {
return nil
}
// CreateDefaultConfig creates the default configuration for the Receiver.
func (f *MultiProtoReceiverFactory) CreateDefaultConfig() configmodels.Receiver {
return &MultiProtoReceiver{
TypeVal: "multireceiver",
Protocols: map[string]MultiProtoReceiverOneCfg{
"http": {
Endpoint: "example.com:8888",
ExtraSetting: "extra string 1",
},
"tcp": {
Endpoint: "omnition.com:9999",
ExtraSetting: "extra string 2",
},
},
}
}
// CreateTraceReceiver creates a trace receiver based on this config.
func (f *MultiProtoReceiverFactory) CreateTraceReceiver(
ctx context.Context,
logger *zap.Logger,
cfg configmodels.Receiver,
nextConsumer consumer.TraceConsumer,
) (receiver.TraceReceiver, error) {
// Not used for this test, just return nil
return nil, nil
}
// CreateMetricsReceiver creates a metrics receiver based on this config.
func (f *MultiProtoReceiverFactory) CreateMetricsReceiver(
logger *zap.Logger,
cfg configmodels.Receiver,
consumer consumer.MetricsConsumer,
) (receiver.MetricsReceiver, error) {
// Not used for this test, just return nil
return nil, nil
}
// ExampleExporter is for testing purposes. We are defining an example config and factory
// for "exampleexporter" exporter type.
type ExampleExporter struct {
configmodels.ExporterSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
ExtraInt int32 `mapstructure:"extra_int"`
ExtraSetting string `mapstructure:"extra"`
ExtraMapSetting map[string]string `mapstructure:"extra_map"`
ExtraListSetting []string `mapstructure:"extra_list"`
ExporterShutdown bool
}
// ExampleExporterFactory is factory for ExampleExporter.
type ExampleExporterFactory struct {
}
// Type gets the type of the Exporter config created by this factory.
func (f *ExampleExporterFactory) Type() string {
return "exampleexporter"
}
// CreateDefaultConfig creates the default configuration for the Exporter.
func (f *ExampleExporterFactory) CreateDefaultConfig() configmodels.Exporter {
return &ExampleExporter{
ExporterSettings: configmodels.ExporterSettings{},
ExtraSetting: "some export string",
ExtraMapSetting: nil,
ExtraListSetting: nil,
}
}
// CreateTraceExporter creates a trace exporter based on this config.
func (f *ExampleExporterFactory) CreateTraceExporter(logger *zap.Logger, cfg configmodels.Exporter) (exporter.TraceExporter, error) {
return &ExampleExporterConsumer{}, nil
}
// CreateMetricsExporter creates a metrics exporter based on this config.
func (f *ExampleExporterFactory) CreateMetricsExporter(logger *zap.Logger, cfg configmodels.Exporter) (exporter.MetricsExporter, error) {
return &ExampleExporterConsumer{}, nil
}
// ExampleExporterConsumer stores consumed traces and metrics for testing purposes.
type ExampleExporterConsumer struct {
Traces []consumerdata.TraceData
Metrics []consumerdata.MetricsData
ExporterStarted bool
ExporterShutdown bool
}
// Start tells the exporter to start. The exporter may prepare for exporting
// by connecting to the endpoint. Host parameter can be used for communicating
// with the host after Start() has already returned.
func (exp *ExampleExporterConsumer) Start(host component.Host) error {
exp.ExporterStarted = true
return nil
}
// ConsumeTraceData receives consumerdata.TraceData for processing by the TraceConsumer.
func (exp *ExampleExporterConsumer) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error {
exp.Traces = append(exp.Traces, td)
return nil
}
// ConsumeMetricsData receives consumerdata.MetricsData for processing by the MetricsConsumer.
func (exp *ExampleExporterConsumer) ConsumeMetricsData(ctx context.Context, md consumerdata.MetricsData) error {
exp.Metrics = append(exp.Metrics, md)
return nil
}
// Name returns the name of the exporter.
func (exp *ExampleExporterConsumer) Name() string {
return "exampleexporter"
}
// Shutdown is invoked during shutdown.
func (exp *ExampleExporterConsumer) Shutdown() error {
exp.ExporterShutdown = true
return nil
}
// ExampleProcessor is for testing purposes. We are defining an example config and factory
// for "exampleprocessor" processor type.
type ExampleProcessor struct {
configmodels.ProcessorSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
ExtraSetting string `mapstructure:"extra"`
ExtraMapSetting map[string]string `mapstructure:"extra_map"`
ExtraListSetting []string `mapstructure:"extra_list"`
}
// ExampleProcessorFactory is factory for ExampleProcessor.
type ExampleProcessorFactory struct {
}
// Type gets the type of the Processor config created by this factory.
func (f *ExampleProcessorFactory) Type() string {
return "exampleprocessor"
}
// CreateDefaultConfig creates the default configuration for the Processor.
func (f *ExampleProcessorFactory) CreateDefaultConfig() configmodels.Processor {
return &ExampleProcessor{
ProcessorSettings: configmodels.ProcessorSettings{},
ExtraSetting: "some export string",
ExtraMapSetting: nil,
ExtraListSetting: nil,
}
}
// CreateTraceProcessor creates a trace processor based on this config.
func (f *ExampleProcessorFactory) CreateTraceProcessor(
logger *zap.Logger,
nextConsumer consumer.TraceConsumer,
cfg configmodels.Processor,
) (processor.TraceProcessor, error) {
return nil, configerror.ErrDataTypeIsNotSupported
}
// CreateMetricsProcessor creates a metrics processor based on this config.
func (f *ExampleProcessorFactory) CreateMetricsProcessor(
logger *zap.Logger,
nextConsumer consumer.MetricsConsumer,
cfg configmodels.Processor,
) (processor.MetricsProcessor, error) {
return nil, configerror.ErrDataTypeIsNotSupported
}
// ExampleExtension is for testing purposes. We are defining an example config and factory
// for "exampleextension" extension type.
type ExampleExtension struct {
configmodels.ExtensionSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
ExtraSetting string `mapstructure:"extra"`
ExtraMapSetting map[string]string `mapstructure:"extra_map"`
ExtraListSetting []string `mapstructure:"extra_list"`
}
// ExampleExtensionFactory is factory for ExampleExtension.
type ExampleExtensionFactory struct {
}
// Type gets the type of the Extension config created by this factory.
func (f *ExampleExtensionFactory) Type() string {
return "exampleextension"
}
// CreateDefaultConfig creates the default configuration for the Extension.
func (f *ExampleExtensionFactory) CreateDefaultConfig() configmodels.Extension {
return &ExampleExtension{
ExtensionSettings: configmodels.ExtensionSettings{},
ExtraSetting: "extra string setting",
ExtraMapSetting: nil,
ExtraListSetting: nil,
}
}
// CreateExtension creates an Extension based on this config.
func (f *ExampleExtensionFactory) CreateExtension(
logger *zap.Logger,
cfg configmodels.Extension,
) (extension.ServiceExtension, error) {
return nil, fmt.Errorf("cannot create %q extension type", f.Type())
}
var _ (extension.Factory) = (*ExampleExtensionFactory)(nil)
// ExampleComponents registers example factories. This is only used by tests.
func ExampleComponents() (
factories Factories,
err error,
) {
if factories.Extensions, err = extension.Build(&ExampleExtensionFactory{}); err != nil {
return
}
factories.Receivers, err = receiver.Build(
&ExampleReceiverFactory{},
&MultiProtoReceiverFactory{},
)
if err != nil {
return
}
factories.Exporters, err = exporter.Build(&ExampleExporterFactory{})
if err != nil {
return
}
factories.Processors, err = processor.Build(&ExampleProcessorFactory{})
return
}