@@ -21,7 +21,6 @@ import (
21
21
"time"
22
22
23
23
"github.com/coreos/go-semver/semver"
24
- "github.com/google/uuid"
25
24
"github.com/influxdata/toml"
26
25
"github.com/influxdata/toml/ast"
27
26
@@ -69,15 +68,29 @@ type Config struct {
69
68
Outputs []* models.RunningOutput
70
69
Aggregators []* models.RunningAggregator
71
70
// Processors have a slice wrapper type because they need to be sorted
72
- Processors models.RunningProcessors
73
- AggProcessors models.RunningProcessors
71
+ Processors models.RunningProcessors
72
+ AggProcessors models.RunningProcessors
73
+ fileProcessors OrderedPlugins
74
+ fileAggProcessors OrderedPlugins
75
+
74
76
// Parsers are created by their inputs during gather. Config doesn't keep track of them
75
77
// like the other plugins because they need to be garbage collected (See issue #11809)
76
78
77
79
Deprecations map [string ][]int64
78
80
version * semver.Version
79
81
}
80
82
83
+ // Ordered plugins used to keep the order in which they appear in a file
84
+ type OrderedPlugin struct {
85
+ Line int
86
+ plugin any
87
+ }
88
+ type OrderedPlugins []* OrderedPlugin
89
+
90
+ func (op OrderedPlugins ) Len () int { return len (op ) }
91
+ func (op OrderedPlugins ) Swap (i , j int ) { op [i ], op [j ] = op [j ], op [i ] }
92
+ func (op OrderedPlugins ) Less (i , j int ) bool { return op [i ].Line < op [j ].Line }
93
+
81
94
// NewConfig creates a new struct to hold the Telegraf config.
82
95
// For historical reasons, It holds the actual instances of the running plugins
83
96
// once the configuration is parsed.
@@ -95,14 +108,16 @@ func NewConfig() *Config {
95
108
LogfileRotationMaxArchives : 5 ,
96
109
},
97
110
98
- Tags : make (map [string ]string ),
99
- Inputs : make ([]* models.RunningInput , 0 ),
100
- Outputs : make ([]* models.RunningOutput , 0 ),
101
- Processors : make ([]* models.RunningProcessor , 0 ),
102
- AggProcessors : make ([]* models.RunningProcessor , 0 ),
103
- InputFilters : make ([]string , 0 ),
104
- OutputFilters : make ([]string , 0 ),
105
- Deprecations : make (map [string ][]int64 ),
111
+ Tags : make (map [string ]string ),
112
+ Inputs : make ([]* models.RunningInput , 0 ),
113
+ Outputs : make ([]* models.RunningOutput , 0 ),
114
+ Processors : make ([]* models.RunningProcessor , 0 ),
115
+ AggProcessors : make ([]* models.RunningProcessor , 0 ),
116
+ fileProcessors : make ([]* OrderedPlugin , 0 ),
117
+ fileAggProcessors : make ([]* OrderedPlugin , 0 ),
118
+ InputFilters : make ([]string , 0 ),
119
+ OutputFilters : make ([]string , 0 ),
120
+ Deprecations : make (map [string ][]int64 ),
106
121
}
107
122
108
123
// Handle unknown version
@@ -391,14 +406,16 @@ func (c *Config) LoadAll(configFiles ...string) error {
391
406
}
392
407
}
393
408
409
+ // Sort the processors according to their `order` setting while
410
+ // using a stable sort to keep the file loading / file position order.
411
+ sort .Stable (c .Processors )
412
+ sort .Stable (c .AggProcessors )
413
+
394
414
return nil
395
415
}
396
416
397
417
// LoadConfigData loads TOML-formatted config data
398
418
func (c * Config ) LoadConfigData (data []byte ) error {
399
- // Create unique identifier for plugins to identify when using multiple configurations
400
- id := uuid .New ()
401
-
402
419
tbl , err := parseConfig (data )
403
420
if err != nil {
404
421
return fmt .Errorf ("error parsing data: %s" , err )
@@ -450,6 +467,10 @@ func (c *Config) LoadConfigData(data []byte) error {
450
467
return fmt .Errorf ("line %d: configuration specified the fields %q, but they weren't used" , tbl .Line , keys (c .UnusedFields ))
451
468
}
452
469
470
+ // Initialize the file-sorting slices
471
+ c .fileProcessors = make (OrderedPlugins , 0 )
472
+ c .fileAggProcessors = make (OrderedPlugins , 0 )
473
+
453
474
// Parse all the rest of the plugins:
454
475
for name , val := range tbl .Fields {
455
476
subTable , ok := val .(* ast.Table )
@@ -510,7 +531,7 @@ func (c *Config) LoadConfigData(data []byte) error {
510
531
switch pluginSubTable := pluginVal .(type ) {
511
532
case []* ast.Table :
512
533
for _ , t := range pluginSubTable {
513
- if err = c .addProcessor (id . String (), pluginName , t ); err != nil {
534
+ if err = c .addProcessor (pluginName , t ); err != nil {
514
535
return fmt .Errorf ("error parsing %s, %w" , pluginName , err )
515
536
}
516
537
}
@@ -555,8 +576,16 @@ func (c *Config) LoadConfigData(data []byte) error {
555
576
}
556
577
}
557
578
558
- if len (c .Processors ) > 1 {
559
- sort .Sort (c .Processors )
579
+ // Sort the processor according to the order they appeared in this file
580
+ // In a later stage, we sort them using the `order` option.
581
+ sort .Sort (c .fileProcessors )
582
+ for _ , op := range c .fileProcessors {
583
+ c .Processors = append (c .Processors , op .plugin .(* models.RunningProcessor ))
584
+ }
585
+
586
+ sort .Sort (c .fileAggProcessors )
587
+ for _ , op := range c .fileAggProcessors {
588
+ c .AggProcessors = append (c .AggProcessors , op .plugin .(* models.RunningProcessor ))
560
589
}
561
590
562
591
return nil
@@ -758,7 +787,7 @@ func (c *Config) addParser(parentcategory, parentname string, table *ast.Table)
758
787
return running , err
759
788
}
760
789
761
- func (c * Config ) addProcessor (id string , name string , table * ast.Table ) error {
790
+ func (c * Config ) addProcessor (name string , table * ast.Table ) error {
762
791
creator , ok := processors .Processors [name ]
763
792
if ! ok {
764
793
// Handle removed, deprecated plugins
@@ -780,7 +809,7 @@ func (c *Config) addProcessor(id string, name string, table *ast.Table) error {
780
809
c .setLocalMissingTomlFieldTracker (missCount )
781
810
defer c .resetMissingTomlFieldTracker ()
782
811
783
- processorConfig , err := c .buildProcessor (id , name , table )
812
+ processorConfig , err := c .buildProcessor (name , table )
784
813
if err != nil {
785
814
return err
786
815
}
@@ -791,15 +820,15 @@ func (c *Config) addProcessor(id string, name string, table *ast.Table) error {
791
820
return err
792
821
}
793
822
rf := models .NewRunningProcessor (processorBefore , processorConfig )
794
- c .Processors = append (c .Processors , rf )
823
+ c .fileProcessors = append (c .fileProcessors , & OrderedPlugin { table . Line , rf } )
795
824
796
825
// Setup another (new) processor instance running after the aggregator
797
826
processorAfter , _ , err := c .setupProcessor (processorConfig .Name , creator , table )
798
827
if err != nil {
799
828
return err
800
829
}
801
830
rf = models .NewRunningProcessor (processorAfter , processorConfig )
802
- c .AggProcessors = append (c .AggProcessors , rf )
831
+ c .fileAggProcessors = append (c .fileAggProcessors , & OrderedPlugin { table . Line , rf } )
803
832
804
833
// Check the number of misses against the threshold
805
834
if hasParser {
@@ -1074,12 +1103,8 @@ func (c *Config) buildParser(name string, tbl *ast.Table) *models.ParserConfig {
1074
1103
// buildProcessor parses Processor specific items from the ast.Table,
1075
1104
// builds the filter and returns a
1076
1105
// models.ProcessorConfig to be inserted into models.RunningProcessor
1077
- func (c * Config ) buildProcessor (id string , name string , tbl * ast.Table ) (* models.ProcessorConfig , error ) {
1078
- conf := & models.ProcessorConfig {
1079
- ID : id ,
1080
- Name : name ,
1081
- Line : tbl .Line ,
1082
- }
1106
+ func (c * Config ) buildProcessor (name string , tbl * ast.Table ) (* models.ProcessorConfig , error ) {
1107
+ conf := & models.ProcessorConfig {Name : name }
1083
1108
1084
1109
c .getFieldInt64 (tbl , "order" , & conf .Order )
1085
1110
c .getFieldString (tbl , "alias" , & conf .Alias )
0 commit comments