@@ -137,7 +137,6 @@ func Load(
137
137
Receivers map [string ]interface {} `mapstructure:"receivers"`
138
138
Processors map [string ]interface {} `mapstructure:"processors"`
139
139
Exporters map [string ]interface {} `mapstructure:"exporters"`
140
- Pipelines map [string ]interface {} `mapstructure:"pipelines"`
141
140
}
142
141
143
142
if err := v .UnmarshalExact (& topLevelSections ); err != nil {
@@ -147,21 +146,15 @@ func Load(
147
146
}
148
147
}
149
148
150
- // Start with extensions and service.
149
+ // Start with the service extensions .
151
150
152
151
extensions , err := loadExtensions (v , factories .Extensions )
153
152
if err != nil {
154
153
return nil , err
155
154
}
156
155
config .Extensions = extensions
157
156
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).
165
158
166
159
receivers , err := loadReceivers (v , factories .Receivers )
167
160
if err != nil {
@@ -181,11 +174,12 @@ func Load(
181
174
}
182
175
config .Processors = processors
183
176
184
- pipelines , err := loadPipelines (v )
177
+ // Load the service and its data pipelines.
178
+ service , err := loadService (v )
185
179
if err != nil {
186
180
return nil , err
187
181
}
188
- config .Pipelines = pipelines
182
+ config .Service = service
189
183
190
184
// Config is loaded. Now validate it.
191
185
@@ -296,13 +290,27 @@ func loadExtensions(v *viper.Viper, factories map[string]extension.Factory) (con
296
290
297
291
func loadService (v * viper.Viper ) (configmodels.Service , error ) {
298
292
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 {
300
304
return service , & configError {
301
305
code : errUnmarshalErrorOnService ,
302
306
msg : fmt .Sprintf ("error reading settings for %q: %v" , serviceKeyName , err ),
303
307
}
304
308
}
305
309
310
+ // Unmarshal cannot properly build Pipelines field, set it to the value
311
+ // previously loaded.
312
+ service .Pipelines = pipelines
313
+
306
314
return service , nil
307
315
}
308
316
@@ -640,12 +648,12 @@ func validateServiceExtensions(
640
648
641
649
func validatePipelines (cfg * configmodels.Config , logger * zap.Logger ) error {
642
650
// Must have at least one pipeline.
643
- if len (cfg .Pipelines ) < 1 {
651
+ if len (cfg .Service . Pipelines ) < 1 {
644
652
return & configError {code : errMissingPipelines , msg : "must have at least one pipeline" }
645
653
}
646
654
647
655
// Validate pipelines.
648
- for _ , pipeline := range cfg .Pipelines {
656
+ for _ , pipeline := range cfg .Service . Pipelines {
649
657
if err := validatePipeline (cfg , pipeline , logger ); err != nil {
650
658
return err
651
659
}
@@ -849,7 +857,7 @@ func validateProcessors(cfg *configmodels.Config) {
849
857
// getConfigSection returns a sub-config from the viper config that has the corresponding given key.
850
858
// It also expands all the string values.
851
859
func getConfigSection (v * viper.Viper , key string ) * viper.Viper {
852
- // Unmarsh only the subconfig for this processor.
860
+ // Unmarshal only the subconfig for this processor.
853
861
sv := v .Sub (key )
854
862
if sv == nil {
855
863
// When the config for this key is empty Sub returns nil. In order to avoid nil checks
0 commit comments