Skip to content

Commit

Permalink
Improve service Config types name (#6787) (#6803)
Browse files Browse the repository at this point in the history
Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu authored Dec 15, 2022
1 parent c1e1ea2 commit e63aed8
Show file tree
Hide file tree
Showing 22 changed files with 791 additions and 517 deletions.
11 changes: 11 additions & 0 deletions .chloggen/draftbuilder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: components

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add [receiver|processor|exporter|extension].Builder to help with creating components form a set of configs and factories

# One or more tracking issues or pull requests related to the change
issues: [6803]
76 changes: 76 additions & 0 deletions exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"context"
"fmt"

"go.uber.org/zap"

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

Expand Down Expand Up @@ -170,3 +172,77 @@ func MakeFactoryMap(factories ...Factory) (map[component.Type]Factory, error) {
}
return fMap, nil
}

// Builder exporter is a helper struct that given a set of Configs and Factories helps with creating exporters.
type Builder struct {
cfgs map[component.ID]component.Config
factories map[component.Type]Factory
}

// NewBuilder creates a new exporter.Builder to help with creating components form a set of configs and factories.
func NewBuilder(cfgs map[component.ID]component.Config, factories map[component.Type]Factory) *Builder {
return &Builder{cfgs: cfgs, factories: factories}
}

// CreateTraces creates a Traces exporter based on the settings and config.
func (b *Builder) CreateTraces(ctx context.Context, set CreateSettings) (Traces, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("exporter %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("exporter factory not available for: %q", set.ID)
}

logStabilityLevel(set.Logger, f.TracesExporterStability())
return f.CreateTracesExporter(ctx, set, cfg)
}

// CreateMetrics creates a Metrics exporter based on the settings and config.
func (b *Builder) CreateMetrics(ctx context.Context, set CreateSettings) (Metrics, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("exporter %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("exporter factory not available for: %q", set.ID)
}

logStabilityLevel(set.Logger, f.MetricsExporterStability())
return f.CreateMetricsExporter(ctx, set, cfg)
}

// CreateLogs creates a Logs exporter based on the settings and config.
func (b *Builder) CreateLogs(ctx context.Context, set CreateSettings) (Logs, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("exporter %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("exporter factory not available for: %q", set.ID)
}

logStabilityLevel(set.Logger, f.LogsExporterStability())
return f.CreateLogsExporter(ctx, set, cfg)
}

func (b *Builder) Factory(componentType component.Type) component.Factory {
return b.factories[componentType]
}

// logStabilityLevel logs the stability level of a component. The log level is set to info for
// undefined, unmaintained, deprecated and development. The log level is set to debug
// for alpha, beta and stable.
func logStabilityLevel(logger *zap.Logger, sl component.StabilityLevel) {
if sl >= component.StabilityLevelAlpha {
logger.Debug(sl.LogMessage())
} else {
logger.Info(sl.LogMessage())
}
}
10 changes: 10 additions & 0 deletions exporter/exportertest/nop_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"go.opentelemetry.io/collector/exporter"
)

const typeStr = "nop"

// NewNopCreateSettings returns a new nop settings for Create*Exporter functions.
func NewNopCreateSettings() exporter.CreateSettings {
return exporter.CreateSettings{
Expand All @@ -30,3 +32,11 @@ func NewNopCreateSettings() exporter.CreateSettings {

// NewNopFactory returns an exporter.Factory that constructs nop exporters.
var NewNopFactory = componenttest.NewNopExporterFactory //nolint:staticcheck

// NewNopBuilder returns a exporter.Builder that constructs nop receivers.
func NewNopBuilder() *exporter.Builder {
nopFactory := NewNopFactory()
return exporter.NewBuilder(
map[component.ID]component.Config{component.NewID(typeStr): nopFactory.CreateDefaultConfig()},
map[component.Type]exporter.Factory{typeStr: nopFactory})
}
28 changes: 28 additions & 0 deletions exporter/exportertest/nop_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,31 @@ func TestNewNopFactory(t *testing.T) {
assert.NoError(t, logs.ConsumeLogs(context.Background(), plog.NewLogs()))
assert.NoError(t, logs.Shutdown(context.Background()))
}

func TestNewNopBuilder(t *testing.T) {
builder := NewNopBuilder()
require.NotNil(t, builder)

factory := NewNopFactory()
cfg := factory.CreateDefaultConfig()
set := NewNopCreateSettings()
set.ID = component.NewID(typeStr)

traces, err := factory.CreateTracesExporter(context.Background(), set, cfg)
require.NoError(t, err)
bTraces, err := builder.CreateTraces(context.Background(), set)
require.NoError(t, err)
assert.IsType(t, traces, bTraces)

metrics, err := factory.CreateMetricsExporter(context.Background(), set, cfg)
require.NoError(t, err)
bMetrics, err := builder.CreateMetrics(context.Background(), set)
require.NoError(t, err)
assert.IsType(t, metrics, bMetrics)

logs, err := factory.CreateLogsExporter(context.Background(), set, cfg)
require.NoError(t, err)
bLogs, err := builder.CreateLogs(context.Background(), set)
require.NoError(t, err)
assert.IsType(t, logs, bLogs)
}
36 changes: 36 additions & 0 deletions extension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,39 @@ func MakeFactoryMap(factories ...Factory) (map[component.Type]Factory, error) {
}
return fMap, nil
}

// Builder extension is a helper struct that given a set of Configs and Factories helps with creating extensions.
type Builder struct {
cfgs map[component.ID]component.Config
factories map[component.Type]Factory
}

// NewBuilder creates a new extension.Builder to help with creating components form a set of configs and factories.
func NewBuilder(cfgs map[component.ID]component.Config, factories map[component.Type]Factory) *Builder {
return &Builder{cfgs: cfgs, factories: factories}
}

// Create creates an extension based on the settings and configs available.
func (b *Builder) Create(ctx context.Context, set CreateSettings) (Extension, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("extension %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("extension factory not available for: %q", set.ID)
}

sl := f.ExtensionStability()
if sl >= component.StabilityLevelAlpha {
set.Logger.Debug(sl.LogMessage())
} else {
set.Logger.Info(sl.LogMessage())
}
return f.CreateExtension(ctx, set, cfg)
}

func (b *Builder) Factory(componentType component.Type) component.Factory {
return b.factories[componentType]
}
10 changes: 10 additions & 0 deletions extension/extensiontest/nop_extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"go.opentelemetry.io/collector/extension"
)

const typeStr = "nop"

// NewNopCreateSettings returns a new nop settings for extension.Factory Create* functions.
func NewNopCreateSettings() extension.CreateSettings {
return extension.CreateSettings{
Expand All @@ -30,3 +32,11 @@ func NewNopCreateSettings() extension.CreateSettings {

// NewNopFactory returns an extension.Factory that constructs nop extensions.
var NewNopFactory = componenttest.NewNopExtensionFactory //nolint:staticcheck

// NewNopBuilder returns a extension.Builder that constructs nop receivers.
func NewNopBuilder() *extension.Builder {
nopFactory := NewNopFactory()
return extension.NewBuilder(
map[component.ID]component.Config{component.NewID(typeStr): nopFactory.CreateDefaultConfig()},
map[component.Type]extension.Factory{typeStr: nopFactory})
}
16 changes: 16 additions & 0 deletions extension/extensiontest/nop_extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,19 @@ func TestNewNopFactory(t *testing.T) {
assert.NoError(t, traces.Start(context.Background(), componenttest.NewNopHost()))
assert.NoError(t, traces.Shutdown(context.Background()))
}

func TestNewNopBuilder(t *testing.T) {
builder := NewNopBuilder()
require.NotNil(t, builder)

factory := NewNopFactory()
cfg := factory.CreateDefaultConfig()
set := NewNopCreateSettings()
set.ID = component.NewID(typeStr)

ext, err := factory.CreateExtension(context.Background(), set, cfg)
require.NoError(t, err)
bExt, err := builder.Create(context.Background(), set)
require.NoError(t, err)
assert.IsType(t, ext, bExt)
}
22 changes: 11 additions & 11 deletions otelcol/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import (
"go.uber.org/zap"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/exporter"
"go.opentelemetry.io/collector/extension"
"go.opentelemetry.io/collector/otelcol/internal/grpclog"
"go.opentelemetry.io/collector/processor"
"go.opentelemetry.io/collector/receiver"
"go.opentelemetry.io/collector/service"
)

Expand Down Expand Up @@ -157,17 +161,13 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error {
}

col.service, err = service.New(ctx, service.Settings{
BuildInfo: col.set.BuildInfo,
ReceiverFactories: col.set.Factories.Receivers,
ReceiverConfigs: cfg.Receivers,
ProcessorFactories: col.set.Factories.Processors,
ProcessorConfigs: cfg.Processors,
ExporterFactories: col.set.Factories.Exporters,
ExporterConfigs: cfg.Exporters,
ExtensionFactories: col.set.Factories.Extensions,
ExtensionConfigs: cfg.Extensions,
AsyncErrorChannel: col.asyncErrorChannel,
LoggingOptions: col.set.LoggingOptions,
BuildInfo: col.set.BuildInfo,
Receivers: receiver.NewBuilder(cfg.Receivers, col.set.Factories.Receivers),
Processors: processor.NewBuilder(cfg.Processors, col.set.Factories.Processors),
Exporters: exporter.NewBuilder(cfg.Exporters, col.set.Factories.Exporters),
Extensions: extension.NewBuilder(cfg.Extensions, col.set.Factories.Extensions),
AsyncErrorChannel: col.asyncErrorChannel,
LoggingOptions: col.set.LoggingOptions,
}, cfg.Service)
if err != nil {
return err
Expand Down
80 changes: 80 additions & 0 deletions processor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
package processor // import "go.opentelemetry.io/collector/processor"

import (
"context"
"fmt"

"go.uber.org/zap"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/consumer"
)

// Traces is a processor that can consume traces.
Expand Down Expand Up @@ -63,3 +69,77 @@ var NewFactory = component.NewProcessorFactory //nolint:staticcheck
// MakeFactoryMap takes a list of factories and returns a map with Factory type as keys.
// It returns a non-nil error when there are factories with duplicate type.
var MakeFactoryMap = component.MakeProcessorFactoryMap //nolint:staticcheck

// Builder processor is a helper struct that given a set of Configs and Factories helps with creating processors.
type Builder struct {
cfgs map[component.ID]component.Config
factories map[component.Type]Factory
}

// NewBuilder creates a new processor.Builder to help with creating components form a set of configs and factories.
func NewBuilder(cfgs map[component.ID]component.Config, factories map[component.Type]Factory) *Builder {
return &Builder{cfgs: cfgs, factories: factories}
}

// CreateTraces creates a Traces processor based on the settings and config.
func (b *Builder) CreateTraces(ctx context.Context, set CreateSettings, next consumer.Traces) (Traces, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("processor %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("processor factory not available for: %q", set.ID)
}

logStabilityLevel(set.Logger, f.TracesProcessorStability())
return f.CreateTracesProcessor(ctx, set, cfg, next)
}

// CreateMetrics creates a Metrics processor based on the settings and config.
func (b *Builder) CreateMetrics(ctx context.Context, set CreateSettings, next consumer.Metrics) (Metrics, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("processor %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("processor factory not available for: %q", set.ID)
}

logStabilityLevel(set.Logger, f.MetricsProcessorStability())
return f.CreateMetricsProcessor(ctx, set, cfg, next)
}

// CreateLogs creates a Logs processor based on the settings and config.
func (b *Builder) CreateLogs(ctx context.Context, set CreateSettings, next consumer.Logs) (Logs, error) {
cfg, existsCfg := b.cfgs[set.ID]
if !existsCfg {
return nil, fmt.Errorf("processor %q is not configured", set.ID)
}

f, existsFactory := b.factories[set.ID.Type()]
if !existsFactory {
return nil, fmt.Errorf("processor factory not available for: %q", set.ID)
}

logStabilityLevel(set.Logger, f.LogsProcessorStability())
return f.CreateLogsProcessor(ctx, set, cfg, next)
}

func (b *Builder) Factory(componentType component.Type) component.Factory {
return b.factories[componentType]
}

// logStabilityLevel logs the stability level of a component. The log level is set to info for
// undefined, unmaintained, deprecated and development. The log level is set to debug
// for alpha, beta and stable.
func logStabilityLevel(logger *zap.Logger, sl component.StabilityLevel) {
if sl >= component.StabilityLevelAlpha {
logger.Debug(sl.LogMessage())
} else {
logger.Info(sl.LogMessage())
}
}
12 changes: 12 additions & 0 deletions processor/processortest/nop_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,23 @@
package processortest // import "go.opentelemetry.io/collector/processor/processortest"

import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenttest"
"go.opentelemetry.io/collector/processor"
)

const typeStr = "nop"

// NewNopCreateSettings returns a new nop settings for Create* functions.
var NewNopCreateSettings = componenttest.NewNopProcessorCreateSettings //nolint:staticcheck

// NewNopFactory returns a component.ProcessorFactory that constructs nop processors.
var NewNopFactory = componenttest.NewNopProcessorFactory //nolint:staticcheck

// NewNopBuilder returns a processor.Builder that constructs nop receivers.
func NewNopBuilder() *processor.Builder {
nopFactory := NewNopFactory()
return processor.NewBuilder(
map[component.ID]component.Config{component.NewID(typeStr): nopFactory.CreateDefaultConfig()},
map[component.Type]processor.Factory{typeStr: nopFactory})
}
Loading

0 comments on commit e63aed8

Please sign in to comment.