Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .chloggen/otelcol-factoriestelemetry-required.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: breaking

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: The `otelcol.Factories.Telemetry` field is now required

# One or more tracking issues or pull requests related to the change
issues: [14003]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
Previously if this field was not set, then it would default to an otelconftelemetry factory.
Callers of the otelcol package must now set the field explicitly.

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [api]
7 changes: 0 additions & 7 deletions otelcol/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"go.opentelemetry.io/collector/confmap/xconfmap"
"go.opentelemetry.io/collector/otelcol/internal/grpclog"
"go.opentelemetry.io/collector/service"
"go.opentelemetry.io/collector/service/telemetry/otelconftelemetry"
)

// State defines Collector's state.
Expand Down Expand Up @@ -179,9 +178,6 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error {
if err != nil {
return fmt.Errorf("failed to initialize factories: %w", err)
}
if factories.Telemetry == nil {
factories.Telemetry = otelconftelemetry.NewFactory()
}

cfg, err := col.configProvider.Get(ctx, factories)
if err != nil {
Expand Down Expand Up @@ -274,9 +270,6 @@ func (col *Collector) DryRun(ctx context.Context) error {
if err != nil {
return fmt.Errorf("failed to initialize factories: %w", err)
}
if factories.Telemetry == nil {
factories.Telemetry = otelconftelemetry.NewFactory()
}

cfg, err := col.configProvider.Get(ctx, factories)
if err != nil {
Expand Down
31 changes: 15 additions & 16 deletions otelcol/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,17 +397,6 @@ func TestCollectorRun(t *testing.T) {
factories: nopFactories,
configFile: "otelcol-nop.yaml",
},
"defaul_telemetry_factory": {
factories: func() (Factories, error) {
factories, err := nopFactories()
if err != nil {
return Factories{}, err
}
factories.Telemetry = nil
return factories, nil
},
configFile: "otelcol-otelconftelemetry.yaml",
},
}

for name, test := range tests {
Expand Down Expand Up @@ -477,6 +466,18 @@ func TestCollectorRun_Errors(t *testing.T) {
},
expectedErr: "failed to get config: cannot unmarshal the configuration: decoding failed due to the following error(s):\n\n'service.telemetry' has invalid keys: unknown",
},
"missing_telemetry_factory": {
settings: CollectorSettings{
BuildInfo: component.NewDefaultBuildInfo(),
Factories: func() (Factories, error) {
factories, _ := nopFactories()
factories.Telemetry = nil
return factories, nil
},
ConfigProviderSettings: newDefaultConfigProviderSettings(t, []string{filepath.Join("testdata", "otelcol-otelconftelemetry.yaml")}),
},
expectedErr: "failed to get config: cannot unmarshal the configuration: otelcol.Factories.Telemetry must not be nil. For example, you can use otelconftelemetry.NewFactory to build a telemetry factory",
},
}

for name, test := range tests {
Expand Down Expand Up @@ -548,19 +549,17 @@ func TestCollectorDryRun(t *testing.T) {
},
expectedErr: "failed to get config: cannot unmarshal the configuration: decoding failed due to the following error(s):\n\n'service.telemetry' has invalid keys: unknown",
},
"default_telemetry_factory": {
"missing_telemetry_factory": {
settings: CollectorSettings{
BuildInfo: component.NewDefaultBuildInfo(),
Factories: func() (Factories, error) {
factories, err := nopFactories()
if err != nil {
return Factories{}, err
}
factories, _ := nopFactories()
factories.Telemetry = nil
return factories, nil
},
ConfigProviderSettings: newDefaultConfigProviderSettings(t, []string{filepath.Join("testdata", "otelcol-otelconftelemetry.yaml")}),
},
expectedErr: "failed to get config: cannot unmarshal the configuration: otelcol.Factories.Telemetry must not be nil. For example, you can use otelconftelemetry.NewFactory to build a telemetry factory",
},
}

Expand Down
4 changes: 0 additions & 4 deletions otelcol/factories.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ type Factories struct {
Connectors map[component.Type]connector.Factory

// Telemetry is the factory to create the telemetry providers for the service.
//
// If Telemetry is nil, otelconftelemetry will be used by default.
// TODO remove the backwards compatibility and require a non-nil factory
// https://github.com/open-telemetry/opentelemetry-collector/issues/14003
Telemetry telemetry.Factory

// ReceiverModules maps receiver types to their respective go modules.
Expand Down
10 changes: 4 additions & 6 deletions otelcol/otelcoltest/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,15 @@ import (
"go.opentelemetry.io/collector/confmap/provider/yamlprovider"
"go.opentelemetry.io/collector/confmap/xconfmap"
"go.opentelemetry.io/collector/otelcol"
"go.opentelemetry.io/collector/service/telemetry/otelconftelemetry"
)

// LoadConfig loads a config.Config from file, and does NOT validate the configuration.
// LoadConfig loads a config.Config from file, and does NOT validate the configuration.
//
// If factories.Telemetry is nil, otelconftelemetry will be used by default.
// TODO remove the backwards compatibility and require a non-nil factory
// https://github.com/open-telemetry/opentelemetry-collector/issues/14003
// If factories.Telemetry is nil, a no-op telemetry factory will be used. This
// factory does not support any telemetry configuration.
func LoadConfig(fileName string, factories otelcol.Factories) (*otelcol.Config, error) {
if factories.Telemetry == nil {
factories.Telemetry = otelconftelemetry.NewFactory()
factories.Telemetry = nopTelemetryFactory()
}
Comment on lines 23 to 25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not really ask users to provide even the no-op?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm ok with setting this as a convenience in otelcoltest

provider, err := otelcol.NewConfigProvider(otelcol.ConfigProviderSettings{
ResolverSettings: confmap.ResolverSettings{
Expand Down
5 changes: 2 additions & 3 deletions otelcol/otelcoltest/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/pipeline"
"go.opentelemetry.io/collector/service/pipelines"
"go.opentelemetry.io/collector/service/telemetry/otelconftelemetry"
)

func TestLoadConfig(t *testing.T) {
Expand Down Expand Up @@ -64,15 +63,15 @@ func TestLoadConfig(t *testing.T) {
assert.Equal(t, struct{}{}, cfg.Service.Telemetry)
}

func TestLoadConfig_DefaultTelemetry(t *testing.T) {
func TestLoadConfig_DefaultNopTelemetry(t *testing.T) {
factories, err := NopFactories()
require.NoError(t, err)
factories.Telemetry = nil

cfg, err := LoadConfig(filepath.Join("testdata", "config.yaml"), factories)
require.NoError(t, err)

assert.Equal(t, otelconftelemetry.NewFactory().CreateDefaultConfig(), cfg.Service.Telemetry)
assert.Equal(t, struct{}{}, cfg.Service.Telemetry)
}

func TestLoadConfigAndValidate(t *testing.T) {
Expand Down
10 changes: 7 additions & 3 deletions otelcol/otelcoltest/nop_factories.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ func NopFactories() (otelcol.Factories, error) {
factories.Exporters, _ = otelcol.MakeFactoryMap(exportertest.NewNopFactory())
factories.Processors, _ = otelcol.MakeFactoryMap(processortest.NewNopFactory())
factories.Connectors, _ = otelcol.MakeFactoryMap(connectortest.NewNopFactory())
factories.Telemetry = telemetry.NewFactory(
func() component.Config { return struct{}{} },
)
factories.Telemetry = nopTelemetryFactory()

return factories, nil
}

func nopTelemetryFactory() telemetry.Factory {
return telemetry.NewFactory(
func() component.Config { return struct{}{} },
)
}
8 changes: 8 additions & 0 deletions otelcol/unmarshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package otelcol // import "go.opentelemetry.io/collector/otelcol"

import (
"errors"

"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/connector"
"go.opentelemetry.io/collector/exporter"
Expand All @@ -14,6 +16,8 @@ import (
"go.opentelemetry.io/collector/service"
)

var errNilTelemetryFactory = errors.New("otelcol.Factories.Telemetry must not be nil. For example, you can use otelconftelemetry.NewFactory to build a telemetry factory")

type configSettings struct {
Receivers *configunmarshaler.Configs[receiver.Factory] `mapstructure:"receivers"`
Processors *configunmarshaler.Configs[processor.Factory] `mapstructure:"processors"`
Expand All @@ -26,6 +30,10 @@ type configSettings struct {
// unmarshal the configSettings from a confmap.Conf.
// After the config is unmarshalled, `Validate()` must be called to validate.
func unmarshal(v *confmap.Conf, factories Factories) (*configSettings, error) {
if factories.Telemetry == nil {
return nil, errNilTelemetryFactory
}

// Unmarshal top level sections and validate.
cfg := &configSettings{
Receivers: configunmarshaler.NewConfigs(factories.Receivers),
Expand Down