diff --git a/config/config.go b/config/config.go index 35ebd6f64a1..a1d7481e465 100644 --- a/config/config.go +++ b/config/config.go @@ -161,7 +161,7 @@ type Service struct { // ServiceTelemetry defines the configurable settings for service telemetry. type ServiceTelemetry struct { - Logs ServiceTelemetryLogs `mapstructure:"logs"` + Logs ServiceTelemetryLogs } func (srvT *ServiceTelemetry) validate() error { @@ -173,24 +173,18 @@ func (srvT *ServiceTelemetry) validate() error { // the collector uses mapstructure and not yaml tags. type ServiceTelemetryLogs struct { // Level is the minimum enabled logging level. - // Valid values are "DEBUG", "INFO", "WARN", "ERROR", "DPANIC", "PANIC", "FATAL". - Level string `mapstructure:"level"` + Level zapcore.Level // Development puts the logger in development mode, which changes the // behavior of DPanicLevel and takes stacktraces more liberally. - Development bool `mapstructure:"development"` + Development bool // Encoding sets the logger's encoding. // Valid values are "json" and "console". - Encoding string `mapstructure:"encoding"` + Encoding string } func (srvTL *ServiceTelemetryLogs) validate() error { - var lvl zapcore.Level - if err := lvl.UnmarshalText([]byte(srvTL.Level)); err != nil { - return fmt.Errorf(`service telemetry logs invalid level: %q, valid values are "DEBUG", "INFO", "WARN", "ERROR", "DPANIC", "PANIC", "FATAL"`, srvTL.Level) - } - if srvTL.Encoding != "json" && srvTL.Encoding != "console" { return fmt.Errorf(`service telemetry logs invalid encoding: %q, valid values are "json" and "console"`, srvTL.Encoding) } diff --git a/config/config_test.go b/config/config_test.go index 9ae0ad7a4ac..cf443246c3a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "go.uber.org/zap/zapcore" ) var errInvalidRecvConfig = errors.New("invalid receiver config") @@ -212,15 +213,6 @@ func TestConfigValidate(t *testing.T) { }, expected: fmt.Errorf(`extension "nop" has invalid configuration: %w`, errInvalidExtConfig), }, - { - name: "invalid-service-telemetry-level", - cfgFn: func() *Config { - cfg := generateConfig() - cfg.Service.Telemetry.Logs.Level = "unknown" - return cfg - }, - expected: errors.New(`service telemetry logs invalid level: "unknown", valid values are "DEBUG", "INFO", "WARN", "ERROR", "DPANIC", "PANIC", "FATAL"`), - }, { name: "invalid-service-telemetry-encoding", cfgFn: func() *Config { @@ -263,7 +255,7 @@ func generateConfig() *Config { }, }, Service: Service{ - Telemetry: ServiceTelemetry{Logs: ServiceTelemetryLogs{Level: "DEBUG", Development: true, Encoding: "console"}}, + Telemetry: ServiceTelemetry{Logs: ServiceTelemetryLogs{Level: zapcore.DebugLevel, Development: true, Encoding: "console"}}, Extensions: []ComponentID{NewID("nop")}, Pipelines: map[string]*Pipeline{ "traces": { diff --git a/config/configunmarshaler/defaultunmarshaler.go b/config/configunmarshaler/defaultunmarshaler.go index 51473595545..5df58acd8b3 100644 --- a/config/configunmarshaler/defaultunmarshaler.go +++ b/config/configunmarshaler/defaultunmarshaler.go @@ -19,6 +19,8 @@ import ( "os" "reflect" + "go.uber.org/zap/zapcore" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configparser" @@ -33,6 +35,7 @@ const ( _ configErrorCode = iota errInvalidTypeAndNameKey + errInvalidLogsLevel errUnknownType errDuplicateName errUnmarshalTopLevelStructureError @@ -77,11 +80,21 @@ type configSettings struct { } type serviceSettings struct { - Telemetry config.ServiceTelemetry `mapstructure:"telemetry"` + Telemetry serviceTelemetrySettings `mapstructure:"telemetry"` Extensions []string `mapstructure:"extensions"` Pipelines map[string]pipelineSettings `mapstructure:"pipelines"` } +type serviceTelemetrySettings struct { + Logs serviceTelemetryLogsSettings `mapstructure:"logs"` +} + +type serviceTelemetryLogsSettings struct { + Level string `mapstructure:"level"` + Development bool `mapstructure:"development"` + Encoding string `mapstructure:"encoding"` +} + type pipelineSettings struct { Receivers []string `mapstructure:"receivers"` Processors []string `mapstructure:"processors"` @@ -108,8 +121,8 @@ func (*defaultUnmarshaler) Unmarshal(v *configparser.ConfigMap, factories compon // Setup default telemetry values as in service/logger.go. // TODO: Add a component.ServiceFactory to allow this to be defined by the Service. Service: serviceSettings{ - Telemetry: config.ServiceTelemetry{ - Logs: config.ServiceTelemetryLogs{ + Telemetry: serviceTelemetrySettings{ + Logs: serviceTelemetryLogsSettings{ Level: "INFO", Development: false, Encoding: "console", @@ -234,7 +247,20 @@ func unmarshalExtensions(exts map[string]map[string]interface{}, factories map[c func unmarshalService(rawService serviceSettings) (config.Service, error) { var ret config.Service - ret.Telemetry = rawService.Telemetry + + var lvl zapcore.Level + if err := lvl.UnmarshalText([]byte(rawService.Telemetry.Logs.Level)); err != nil { + return ret, &configError{ + msg: fmt.Sprintf(`service telemetry logs invalid level: %q, valid values are "DEBUG", "INFO", "WARN", "ERROR", "DPANIC", "PANIC", "FATAL"`, rawService.Telemetry.Logs.Level), + code: errInvalidLogsLevel, + } + } + + ret.Telemetry.Logs = config.ServiceTelemetryLogs{ + Level: lvl, + Development: rawService.Telemetry.Logs.Development, + Encoding: rawService.Telemetry.Logs.Encoding, + } ret.Extensions = make([]config.ComponentID, 0, len(rawService.Extensions)) for _, extIDStr := range rawService.Extensions { diff --git a/config/configunmarshaler/defaultunmarshaler_test.go b/config/configunmarshaler/defaultunmarshaler_test.go index 5dc336a1f18..487d2de0c5c 100644 --- a/config/configunmarshaler/defaultunmarshaler_test.go +++ b/config/configunmarshaler/defaultunmarshaler_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config" @@ -97,7 +98,7 @@ func TestDecodeConfig(t *testing.T) { "Did not load processor config correctly") // Verify Service Telemetry - assert.Equal(t, config.ServiceTelemetry{Logs: config.ServiceTelemetryLogs{Level: "DEBUG", Development: true, Encoding: "console"}}, cfg.Service.Telemetry) + assert.Equal(t, config.ServiceTelemetry{Logs: config.ServiceTelemetryLogs{Level: zapcore.DebugLevel, Development: true, Encoding: "console"}}, cfg.Service.Telemetry) // Verify Service Extensions assert.Equal(t, 2, len(cfg.Service.Extensions)) @@ -417,6 +418,8 @@ func TestDecodeConfig_Invalid(t *testing.T) { {name: "invalid-processor-sub-config", expected: errUnmarshalTopLevelStructureError}, {name: "invalid-receiver-sub-config", expected: errUnmarshalTopLevelStructureError}, {name: "invalid-pipeline-sub-config", expected: errUnmarshalTopLevelStructureError}, + + {name: "invalid-logs-level", expected: errInvalidLogsLevel}, } factories, err := testcomponents.ExampleComponents() diff --git a/config/configunmarshaler/testdata/invalid-logs-level.yaml b/config/configunmarshaler/testdata/invalid-logs-level.yaml new file mode 100644 index 00000000000..5abba340943 --- /dev/null +++ b/config/configunmarshaler/testdata/invalid-logs-level.yaml @@ -0,0 +1,19 @@ +receivers: + examplereceiver: +processors: + exampleprocessor: +exporters: + exampleexporter: +extensions: + exampleextension: +service: + telemetry: + logs: + level: "UNKNOWN" + extensions: [exampleextension] + pipelines: + traces: + receivers: [examplereceiver] + processors: [exampleprocessor] + exporters: [exampleexporter] +