@@ -137,7 +137,6 @@ func Load(
137137 Receivers map [string ]interface {} `mapstructure:"receivers"`
138138 Processors map [string ]interface {} `mapstructure:"processors"`
139139 Exporters map [string ]interface {} `mapstructure:"exporters"`
140- Pipelines map [string ]interface {} `mapstructure:"pipelines"`
141140 }
142141
143142 if err := v .UnmarshalExact (& topLevelSections ); err != nil {
@@ -147,21 +146,15 @@ func Load(
147146 }
148147 }
149148
150- // Start with extensions and service.
149+ // Start with the service extensions .
151150
152151 extensions , err := loadExtensions (v , factories .Extensions )
153152 if err != nil {
154153 return nil , err
155154 }
156155 config .Extensions = extensions
157156
158- service , err := loadService (v )
159- if err != nil {
160- return nil , err
161- }
162- config .Service = service
163-
164- // Load data components (receivers, exporters, processores, and pipelines).
157+ // Load data components (receivers, exporters, and processors).
165158
166159 receivers , err := loadReceivers (v , factories .Receivers )
167160 if err != nil {
@@ -181,11 +174,12 @@ func Load(
181174 }
182175 config .Processors = processors
183176
184- pipelines , err := loadPipelines (v )
177+ // Load the service and its data pipelines.
178+ service , err := loadService (v )
185179 if err != nil {
186180 return nil , err
187181 }
188- config .Pipelines = pipelines
182+ config .Service = service
189183
190184 // Config is loaded. Now validate it.
191185
@@ -296,13 +290,27 @@ func loadExtensions(v *viper.Viper, factories map[string]extension.Factory) (con
296290
297291func loadService (v * viper.Viper ) (configmodels.Service , error ) {
298292 var service configmodels.Service
299- if err := v .UnmarshalKey (serviceKeyName , & service , errorOnUnused ); err != nil {
293+ serviceSub := getConfigSection (v , serviceKeyName )
294+
295+ // Process the pipelines first so in case of error on them it can be properly
296+ // reported.
297+ pipelines , err := loadPipelines (serviceSub )
298+ if err != nil {
299+ return service , err
300+ }
301+
302+ // Do an exact match to find any unused section on config.
303+ if err := serviceSub .UnmarshalExact (& service ); err != nil {
300304 return service , & configError {
301305 code : errUnmarshalErrorOnService ,
302306 msg : fmt .Sprintf ("error reading settings for %q: %v" , serviceKeyName , err ),
303307 }
304308 }
305309
310+ // Unmarshal cannot properly build Pipelines field, set it to the value
311+ // previously loaded.
312+ service .Pipelines = pipelines
313+
306314 return service , nil
307315}
308316
@@ -640,12 +648,12 @@ func validateServiceExtensions(
640648
641649func validatePipelines (cfg * configmodels.Config , logger * zap.Logger ) error {
642650 // Must have at least one pipeline.
643- if len (cfg .Pipelines ) < 1 {
651+ if len (cfg .Service . Pipelines ) < 1 {
644652 return & configError {code : errMissingPipelines , msg : "must have at least one pipeline" }
645653 }
646654
647655 // Validate pipelines.
648- for _ , pipeline := range cfg .Pipelines {
656+ for _ , pipeline := range cfg .Service . Pipelines {
649657 if err := validatePipeline (cfg , pipeline , logger ); err != nil {
650658 return err
651659 }
@@ -849,7 +857,7 @@ func validateProcessors(cfg *configmodels.Config) {
849857// getConfigSection returns a sub-config from the viper config that has the corresponding given key.
850858// It also expands all the string values.
851859func getConfigSection (v * viper.Viper , key string ) * viper.Viper {
852- // Unmarsh only the subconfig for this processor.
860+ // Unmarshal only the subconfig for this processor.
853861 sv := v .Sub (key )
854862 if sv == nil {
855863 // When the config for this key is empty Sub returns nil. In order to avoid nil checks
0 commit comments