453 lines
15 KiB
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
|
|
}
|