Skip to content

Commit

Permalink
Move everything from exporterhelper to component.
Browse files Browse the repository at this point in the history
Updates #4681

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu committed Feb 21, 2022
1 parent 89e0d42 commit 7f7344d
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 307 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
- Deprecated `extensionhelper.CreateDefaultConfig` in favour of `component.ExtensionDefaultConfigFunc`
- Deprecated `extensionhelper.CreateServiceExtension` in favour of `component.CreateExtensionFunc`
- Deprecated `extensionhelper.NewFactory` in favour of `component.NewExtensionFactory`
- Move helpers from exporterhelper to component (#4899)
- Deprecated `exporterhelper.CreateDefaultConfig` in favour of `component.ExporterDefaultConfigFunc`
- Deprecated `exporterhelper.WithTraces` in favour of `component.WithTracesExporter`
- Deprecated `exporterhelper.WithMetrics` in favour of `component.WithMetricsExporter`
- Deprecated `exporterhelper.WithLogs` in favour of `component.WithLogsExporter`
- Deprecated `exporterhelper.NewFactory` in favour of `component.NewExporterFactory`

### 💡 Enhancements 💡

Expand Down
52 changes: 14 additions & 38 deletions component/componenttest/nop_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/consumer/consumertest"
"go.opentelemetry.io/collector/internal/internalinterface"
)

// NewNopExporterCreateSettings returns a new nop settings for Create*Exporter functions.
Expand All @@ -35,54 +34,31 @@ type nopExporterConfig struct {
config.ExporterSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}

// nopExporterFactory is factory for nopExporter.
type nopExporterFactory struct {
internalinterface.BaseInternal
}

var nopExporterFactoryInstance = &nopExporterFactory{}
var nopExporterFactory = component.NewExporterFactory(
"nop",
func() config.Exporter {
return &nopExporterConfig{
ExporterSettings: config.NewExporterSettings(config.NewComponentID("nop")),
}
},
component.WithTracesExporter(createTracesExporter),
component.WithMetricsExporter(createMetricsExporter),
component.WithLogsExporter(createLogsExporter))

// NewNopExporterFactory returns a component.ExporterFactory that constructs nop exporters.
func NewNopExporterFactory() component.ExporterFactory {
return nopExporterFactoryInstance
}

// Type gets the type of the Exporter config created by this factory.
func (f *nopExporterFactory) Type() config.Type {
return "nop"
}

// CreateDefaultConfig creates the default configuration for the Exporter.
func (f *nopExporterFactory) CreateDefaultConfig() config.Exporter {
return &nopExporterConfig{
ExporterSettings: config.NewExporterSettings(config.NewComponentID("nop")),
}
return nopExporterFactory
}

// CreateTracesExporter implements component.ExporterFactory interface.
func (f *nopExporterFactory) CreateTracesExporter(
_ context.Context,
_ component.ExporterCreateSettings,
_ config.Exporter,
) (component.TracesExporter, error) {
func createTracesExporter(context.Context, component.ExporterCreateSettings, config.Exporter) (component.TracesExporter, error) {
return nopExporterInstance, nil
}

// CreateMetricsExporter implements component.ExporterFactory interface.
func (f *nopExporterFactory) CreateMetricsExporter(
_ context.Context,
_ component.ExporterCreateSettings,
_ config.Exporter,
) (component.MetricsExporter, error) {
func createMetricsExporter(context.Context, component.ExporterCreateSettings, config.Exporter) (component.MetricsExporter, error) {
return nopExporterInstance, nil
}

// CreateLogsExporter implements component.ExporterFactory interface.
func (f *nopExporterFactory) CreateLogsExporter(
_ context.Context,
_ component.ExporterCreateSettings,
_ config.Exporter,
) (component.LogsExporter, error) {
func createLogsExporter(context.Context, component.ExporterCreateSettings, config.Exporter) (component.LogsExporter, error) {
return nopExporterInstance, nil
}

Expand Down
102 changes: 96 additions & 6 deletions component/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ package component // import "go.opentelemetry.io/collector/component"
import (
"context"

"go.opentelemetry.io/collector/component/componenterror"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/internal/internalinterface"
)

// Exporter exports telemetry data from the collector to a destination.
Expand Down Expand Up @@ -72,18 +74,106 @@ type ExporterFactory interface {
// CreateTracesExporter creates a trace exporter based on this config.
// If the exporter type does not support tracing or if the config is not valid,
// an error will be returned instead.
CreateTracesExporter(ctx context.Context, set ExporterCreateSettings,
cfg config.Exporter) (TracesExporter, error)
CreateTracesExporter(ctx context.Context, set ExporterCreateSettings, cfg config.Exporter) (TracesExporter, error)

// CreateMetricsExporter creates a metrics exporter based on this config.
// If the exporter type does not support metrics or if the config is not valid,
// an error will be returned instead.
CreateMetricsExporter(ctx context.Context, set ExporterCreateSettings,
cfg config.Exporter) (MetricsExporter, error)
CreateMetricsExporter(ctx context.Context, set ExporterCreateSettings, cfg config.Exporter) (MetricsExporter, error)

// CreateLogsExporter creates an exporter based on the config.
// If the exporter type does not support logs or if the config is not valid,
// an error will be returned instead.
CreateLogsExporter(ctx context.Context, set ExporterCreateSettings,
cfg config.Exporter) (LogsExporter, error)
CreateLogsExporter(ctx context.Context, set ExporterCreateSettings, cfg config.Exporter) (LogsExporter, error)
}

// ExporterFactoryOption apply changes to ExporterOptions.
type ExporterFactoryOption func(o *exporterFactory)

// ExporterCreateDefaultConfigFunc is the equivalent of ExporterFactory.CreateDefaultConfig()
type ExporterCreateDefaultConfigFunc func() config.Exporter

// CreateDefaultConfig implements ExtensionFactory.CreateDefaultConfig()
func (f ExporterCreateDefaultConfigFunc) CreateDefaultConfig() config.Exporter {
return f()
}

// CreateTracesExporterFunc is the equivalent of ExporterFactory.CreateTracesExporter()
type CreateTracesExporterFunc func(context.Context, ExporterCreateSettings, config.Exporter) (TracesExporter, error)

// CreateTracesExporter creates a TracesExporter based on this config.
func (f CreateTracesExporterFunc) CreateTracesExporter(ctx context.Context, set ExporterCreateSettings, cfg config.Exporter) (TracesExporter, error) {
if f == nil {
return nil, componenterror.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg)
}

// CreateMetricsExporterFunc is the equivalent of ExporterFactory.CreateMetricsExporter()
type CreateMetricsExporterFunc func(context.Context, ExporterCreateSettings, config.Exporter) (MetricsExporter, error)

// CreateMetricsExporter creates a MetricsExporter based on this config.
func (f CreateMetricsExporterFunc) CreateMetricsExporter(ctx context.Context, set ExporterCreateSettings, cfg config.Exporter) (MetricsExporter, error) {
if f == nil {
return nil, componenterror.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg)
}

// CreateLogsExporterFunc is the equivalent of ExporterFactory.CreateLogsExporter()
type CreateLogsExporterFunc func(context.Context, ExporterCreateSettings, config.Exporter) (LogsExporter, error)

// CreateLogsExporter creates a LogsExporter based on this config.
func (f CreateLogsExporterFunc) CreateLogsExporter(ctx context.Context, set ExporterCreateSettings, cfg config.Exporter) (LogsExporter, error) {
if f == nil {
return nil, componenterror.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg)
}

type exporterFactory struct {
internalinterface.BaseInternal
cfgType config.Type
ExporterCreateDefaultConfigFunc
CreateTracesExporterFunc
CreateMetricsExporterFunc
CreateLogsExporterFunc
}

// WithTracesExporter overrides the default "error not supported" implementation for CreateTracesExporter.
func WithTracesExporter(createTracesExporter CreateTracesExporterFunc) ExporterFactoryOption {
return func(o *exporterFactory) {
o.CreateTracesExporterFunc = createTracesExporter
}
}

// WithMetricsExporter overrides the default "error not supported" implementation for CreateMetricsExporter.
func WithMetricsExporter(createMetricsExporter CreateMetricsExporterFunc) ExporterFactoryOption {
return func(o *exporterFactory) {
o.CreateMetricsExporterFunc = createMetricsExporter
}
}

// WithLogsExporter overrides the default "error not supported" implementation for CreateLogsExporter.
func WithLogsExporter(createLogsExporter CreateLogsExporterFunc) ExporterFactoryOption {
return func(o *exporterFactory) {
o.CreateLogsExporterFunc = createLogsExporter
}
}

// NewExporterFactory returns a ExporterFactory.
func NewExporterFactory(cfgType config.Type, createDefaultConfig ExporterCreateDefaultConfigFunc, options ...ExporterFactoryOption) ExporterFactory {
f := &exporterFactory{
cfgType: cfgType,
ExporterCreateDefaultConfigFunc: createDefaultConfig,
}
for _, opt := range options {
opt(f)
}
return f
}

// Type returns the type of the Exporter created by this ExporterFactory.
func (f *exporterFactory) Type() config.Type {
return f.cfgType
}
105 changes: 74 additions & 31 deletions component/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,98 @@
package component

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

"go.opentelemetry.io/collector/config"
)

type TestExporterFactory struct {
ExporterFactory
name string
}

// Type gets the type of the Exporter config created by this factory.
func (f *TestExporterFactory) Type() config.Type {
return config.Type(f.name)
}

func TestBuildExporters(t *testing.T) {
func TestMakeExporterFactoryMap(t *testing.T) {
type testCase struct {
in []ExporterFactory
out map[config.Type]ExporterFactory
name string
in []ExporterFactory
out map[config.Type]ExporterFactory
}

p1 := NewExporterFactory("p1", nil)
p2 := NewExporterFactory("p2", nil)
testCases := []testCase{
{
in: []ExporterFactory{
&TestExporterFactory{name: "exp1"},
&TestExporterFactory{name: "exp2"},
},
name: "different names",
in: []ExporterFactory{p1, p2},
out: map[config.Type]ExporterFactory{
"exp1": &TestExporterFactory{name: "exp1"},
"exp2": &TestExporterFactory{name: "exp2"},
p1.Type(): p1,
p2.Type(): p2,
},
},
{
in: []ExporterFactory{
&TestExporterFactory{name: "exp1"},
&TestExporterFactory{name: "exp1"},
},
name: "same name",
in: []ExporterFactory{p1, p2, NewExporterFactory("p1", nil)},
},
}

for _, c := range testCases {
out, err := MakeExporterFactoryMap(c.in...)
if c.out == nil {
assert.Error(t, err)
continue
}
assert.NoError(t, err)
assert.Equal(t, c.out, out)
for i := range testCases {
tt := testCases[i]
t.Run(tt.name, func(t *testing.T) {
out, err := MakeExporterFactoryMap(tt.in...)
if tt.out == nil {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, tt.out, out)
})
}
}

func TestNewExporterFactory(t *testing.T) {
const typeStr = "test"
defaultCfg := config.NewExporterSettings(config.NewComponentID(typeStr))
factory := NewExporterFactory(
typeStr,
func() config.Exporter { return &defaultCfg })
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig())
_, err := factory.CreateTracesExporter(context.Background(), ExporterCreateSettings{}, &defaultCfg)
assert.Error(t, err)
_, err = factory.CreateMetricsExporter(context.Background(), ExporterCreateSettings{}, &defaultCfg)
assert.Error(t, err)
_, err = factory.CreateLogsExporter(context.Background(), ExporterCreateSettings{}, &defaultCfg)
assert.Error(t, err)
}

func TestNewExporterFactory_WithOptions(t *testing.T) {
const typeStr = "test"
defaultCfg := config.NewExporterSettings(config.NewComponentID(typeStr))
factory := NewExporterFactory(
typeStr,
func() config.Exporter { return &defaultCfg },
WithTracesExporter(createTracesExporter),
WithMetricsExporter(createMetricsExporter),
WithLogsExporter(createLogsExporter))
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig())

_, err := factory.CreateTracesExporter(context.Background(), ExporterCreateSettings{}, &defaultCfg)
assert.NoError(t, err)

_, err = factory.CreateMetricsExporter(context.Background(), ExporterCreateSettings{}, &defaultCfg)
assert.NoError(t, err)

_, err = factory.CreateLogsExporter(context.Background(), ExporterCreateSettings{}, &defaultCfg)
assert.NoError(t, err)
}

func createTracesExporter(context.Context, ExporterCreateSettings, config.Exporter) (TracesExporter, error) {
return nil, nil
}

func createMetricsExporter(context.Context, ExporterCreateSettings, config.Exporter) (MetricsExporter, error) {
return nil, nil
}

func createLogsExporter(context.Context, ExporterCreateSettings, config.Exporter) (LogsExporter, error) {
return nil, nil
}
2 changes: 1 addition & 1 deletion exporter/exporterhelper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
)

var (
defaultExporterCfg = config.NewExporterSettings(config.NewComponentID(typeStr))
defaultExporterCfg = config.NewExporterSettings(config.NewComponentID("test"))
exporterTag, _ = tag.NewKey("exporter")
defaultExporterTags = []tag.Tag{
{Key: exporterTag, Value: "test"},
Expand Down
Loading

0 comments on commit 7f7344d

Please sign in to comment.