diff --git a/cmd/telegraf/main.go b/cmd/telegraf/main.go index 32f8c6822..600c97936 100644 --- a/cmd/telegraf/main.go +++ b/cmd/telegraf/main.go @@ -224,22 +224,23 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi filters := processFilterFlags(cCtx) g := GlobalFlags{ - config: cCtx.StringSlice("config"), - configDir: cCtx.StringSlice("config-directory"), - testWait: cCtx.Int("test-wait"), - configURLRetryAttempts: cCtx.Int("config-url-retry-attempts"), - configURLWatchInterval: cCtx.Duration("config-url-watch-interval"), - watchConfig: cCtx.String("watch-config"), - watchInterval: cCtx.Duration("watch-interval"), - pidFile: cCtx.String("pidfile"), - plugindDir: cCtx.String("plugin-directory"), - password: cCtx.String("password"), - oldEnvBehavior: cCtx.Bool("old-env-behavior"), - test: cCtx.Bool("test"), - debug: cCtx.Bool("debug"), - once: cCtx.Bool("once"), - quiet: cCtx.Bool("quiet"), - unprotected: cCtx.Bool("unprotected"), + config: cCtx.StringSlice("config"), + configDir: cCtx.StringSlice("config-directory"), + testWait: cCtx.Int("test-wait"), + configURLRetryAttempts: cCtx.Int("config-url-retry-attempts"), + configURLWatchInterval: cCtx.Duration("config-url-watch-interval"), + watchConfig: cCtx.String("watch-config"), + watchInterval: cCtx.Duration("watch-interval"), + pidFile: cCtx.String("pidfile"), + plugindDir: cCtx.String("plugin-directory"), + password: cCtx.String("password"), + oldEnvBehavior: cCtx.Bool("old-env-behavior"), + printPluginConfigSource: cCtx.Bool("print-plugin-config-source"), + test: cCtx.Bool("test"), + debug: cCtx.Bool("debug"), + once: cCtx.Bool("once"), + quiet: cCtx.Bool("quiet"), + unprotected: cCtx.Bool("unprotected"), } w := WindowFlags{ @@ -308,6 +309,10 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi Name: "old-env-behavior", Usage: "switch back to pre v1.27 environment replacement behavior", }, + &cli.BoolFlag{ + Name: "print-plugin-config-source", + Usage: "print the source for a given plugin", + }, &cli.BoolFlag{ Name: "once", Usage: "run one gather and exit", diff --git a/cmd/telegraf/telegraf.go b/cmd/telegraf/telegraf.go index 787a19d78..fb5de806b 100644 --- a/cmd/telegraf/telegraf.go +++ b/cmd/telegraf/telegraf.go @@ -34,22 +34,23 @@ import ( var stop chan struct{} type GlobalFlags struct { - config []string - configDir []string - testWait int - configURLRetryAttempts int - configURLWatchInterval time.Duration - watchConfig string - watchInterval time.Duration - pidFile string - plugindDir string - password string - oldEnvBehavior bool - test bool - debug bool - once bool - quiet bool - unprotected bool + config []string + configDir []string + testWait int + configURLRetryAttempts int + configURLWatchInterval time.Duration + watchConfig string + watchInterval time.Duration + pidFile string + plugindDir string + password string + oldEnvBehavior bool + printPluginConfigSource bool + test bool + debug bool + once bool + quiet bool + unprotected bool } type WindowFlags struct { @@ -105,6 +106,8 @@ func (t *Telegraf) Init(pprofErr <-chan error, f Filters, g GlobalFlags, w Windo // Set environment replacement behavior config.OldEnvVarReplacement = g.oldEnvBehavior + + config.PrintPluginConfigSource = g.printPluginConfigSource } func (t *Telegraf) ListSecretStores() ([]string, error) { @@ -389,14 +392,14 @@ func (t *Telegraf) runAgent(ctx context.Context, reloadConfig bool) error { len(outputs.Outputs), len(secretstores.SecretStores), ) - log.Printf("I! Loaded inputs: %s", strings.Join(c.InputNames(), " ")) - log.Printf("I! Loaded aggregators: %s", strings.Join(c.AggregatorNames(), " ")) - log.Printf("I! Loaded processors: %s", strings.Join(c.ProcessorNames(), " ")) - log.Printf("I! Loaded secretstores: %s", strings.Join(c.SecretstoreNames(), " ")) + log.Printf("I! Loaded inputs: %s\n%s", strings.Join(c.InputNames(), " "), c.InputNamesWithSources()) + log.Printf("I! Loaded aggregators: %s\n%s", strings.Join(c.AggregatorNames(), " "), c.AggregatorNamesWithSources()) + log.Printf("I! Loaded processors: %s\n%s", strings.Join(c.ProcessorNames(), " "), c.ProcessorNamesWithSources()) + log.Printf("I! Loaded secretstores: %s\n%s", strings.Join(c.SecretstoreNames(), " "), c.SecretstoreNamesWithSources()) if !t.once && (t.test || t.testWait != 0) { log.Print("W! " + color.RedString("Outputs are not used in testing mode!")) } else { - log.Printf("I! Loaded outputs: %s", strings.Join(c.OutputNames(), " ")) + log.Printf("I! Loaded outputs: %s\n%s", strings.Join(c.OutputNames(), " "), c.OutputNamesWithSources()) } log.Printf("I! Tags enabled: %s", c.ListTags()) diff --git a/config/config.go b/config/config.go index b2619de5e..3789e94a2 100644 --- a/config/config.go +++ b/config/config.go @@ -53,6 +53,9 @@ var ( // environment variable replacement behavior OldEnvVarReplacement = false + // PrintPluginConfigSource is a switch to enable printing of plugin sources + PrintPluginConfigSource = false + // Password specified via command-line Password Secret @@ -60,6 +63,8 @@ var ( telegrafVersion *semver.Version = semver.New("0.0.0-unknown") ) +const EmptySourcePath string = "" + // Config specifies the URL/user/password for the database that telegraf // will be logging to, as well as all the plugins that the user has // specified @@ -74,7 +79,8 @@ type Config struct { OutputFilters []string SecretStoreFilters []string - SecretStores map[string]telegraf.SecretStore + SecretStores map[string]telegraf.SecretStore + secretStoreSource map[string][]string Agent *AgentConfig Inputs []*models.RunningInput @@ -132,6 +138,7 @@ func NewConfig() *Config { Processors: make([]*models.RunningProcessor, 0), AggProcessors: make([]*models.RunningProcessor, 0), SecretStores: make(map[string]telegraf.SecretStore), + secretStoreSource: make(map[string][]string), fileProcessors: make([]*OrderedPlugin, 0), fileAggProcessors: make([]*OrderedPlugin, 0), InputFilters: make([]string, 0), @@ -303,6 +310,18 @@ func (c *Config) InputNames() []string { return PluginNameCounts(name) } +// InputNamesWithSources returns a table representation of input names and their sources. +func (c *Config) InputNamesWithSources() string { + plugins := make(pluginNames, 0, len(c.Inputs)) + for _, input := range c.Inputs { + plugins = append(plugins, pluginPrinter{ + name: input.Config.Name, + source: input.Config.Source, + }) + } + return getPluginSourcesTable(plugins) +} + // AggregatorNames returns a list of strings of the configured aggregators. func (c *Config) AggregatorNames() []string { name := make([]string, 0, len(c.Aggregators)) @@ -312,6 +331,18 @@ func (c *Config) AggregatorNames() []string { return PluginNameCounts(name) } +// AggregatorNamesWithSources returns a table representation of aggregator names and their sources. +func (c *Config) AggregatorNamesWithSources() string { + plugins := make(pluginNames, 0, len(c.Aggregators)) + for _, aggregator := range c.Aggregators { + plugins = append(plugins, pluginPrinter{ + name: aggregator.Config.Name, + source: aggregator.Config.Source, + }) + } + return getPluginSourcesTable(plugins) +} + // ProcessorNames returns a list of strings of the configured processors. func (c *Config) ProcessorNames() []string { name := make([]string, 0, len(c.Processors)) @@ -321,6 +352,18 @@ func (c *Config) ProcessorNames() []string { return PluginNameCounts(name) } +// ProcessorNamesWithSources returns a table representation of processor names and their sources. +func (c *Config) ProcessorNamesWithSources() string { + plugins := make(pluginNames, 0, len(c.Processors)) + for _, processor := range c.Processors { + plugins = append(plugins, pluginPrinter{ + name: processor.Config.Name, + source: processor.Config.Source, + }) + } + return getPluginSourcesTable(plugins) +} + // OutputNames returns a list of strings of the configured outputs. func (c *Config) OutputNames() []string { name := make([]string, 0, len(c.Outputs)) @@ -330,6 +373,18 @@ func (c *Config) OutputNames() []string { return PluginNameCounts(name) } +// OutputNamesWithSources returns a table representation of output names and their sources. +func (c *Config) OutputNamesWithSources() string { + plugins := make(pluginNames, 0, len(c.Outputs)) + for _, output := range c.Outputs { + plugins = append(plugins, pluginPrinter{ + name: output.Config.Name, + source: output.Config.Source, + }) + } + return getPluginSourcesTable(plugins) +} + // SecretstoreNames returns a list of strings of the configured secret-stores. func (c *Config) SecretstoreNames() []string { names := make([]string, 0, len(c.SecretStores)) @@ -339,6 +394,21 @@ func (c *Config) SecretstoreNames() []string { return PluginNameCounts(names) } +// SecretstoreNamesWithSources returns a table representation of secret store names and their sources. +func (c *Config) SecretstoreNamesWithSources() string { + plugins := make(pluginNames, 0, len(c.SecretStores)) + for name, sources := range c.secretStoreSource { + for _, source := range sources { + plugins = append(plugins, pluginPrinter{ + name: name, + source: source, + }) + } + } + return getPluginSourcesTable(plugins) +} + +// PluginNameCounts returns a string of plugin names and their counts. // PluginNameCounts returns a list of sorted plugin names and their count func PluginNameCounts(plugins []string) []string { names := make(map[string]int) @@ -475,7 +545,7 @@ func (c *Config) LoadConfig(path string) error { return fmt.Errorf("loading config file %s failed: %w", path, err) } - if err = c.LoadConfigData(data); err != nil { + if err = c.LoadConfigData(data, path); err != nil { return fmt.Errorf("loading config file %s failed: %w", path, err) } @@ -511,8 +581,20 @@ func (c *Config) LoadAll(configFiles ...string) error { return c.LinkSecrets() } +type cfgDataOptions struct { + sourcePath string +} + +type cfgDataOption func(*cfgDataOptions) + +func WithSourcePath(path string) cfgDataOption { + return func(o *cfgDataOptions) { + o.sourcePath = path + } +} + // LoadConfigData loads TOML-formatted config data -func (c *Config) LoadConfigData(data []byte) error { +func (c *Config) LoadConfigData(data []byte, path string) error { tbl, err := parseConfig(data) if err != nil { return fmt.Errorf("error parsing data: %w", err) @@ -603,12 +685,12 @@ func (c *Config) LoadConfigData(data []byte) error { switch pluginSubTable := pluginVal.(type) { // legacy [outputs.influxdb] support case *ast.Table: - if err = c.addOutput(pluginName, pluginSubTable); err != nil { + if err = c.addOutput(pluginName, path, pluginSubTable); err != nil { return fmt.Errorf("error parsing %s, %w", pluginName, err) } case []*ast.Table: for _, t := range pluginSubTable { - if err = c.addOutput(pluginName, t); err != nil { + if err = c.addOutput(pluginName, path, t); err != nil { return fmt.Errorf("error parsing %s array, %w", pluginName, err) } } @@ -628,12 +710,12 @@ func (c *Config) LoadConfigData(data []byte) error { switch pluginSubTable := pluginVal.(type) { // legacy [inputs.cpu] support case *ast.Table: - if err = c.addInput(pluginName, pluginSubTable); err != nil { + if err = c.addInput(pluginName, path, pluginSubTable); err != nil { return fmt.Errorf("error parsing %s, %w", pluginName, err) } case []*ast.Table: for _, t := range pluginSubTable { - if err = c.addInput(pluginName, t); err != nil { + if err = c.addInput(pluginName, path, t); err != nil { return fmt.Errorf("error parsing %s, %w", pluginName, err) } } @@ -653,7 +735,7 @@ func (c *Config) LoadConfigData(data []byte) error { switch pluginSubTable := pluginVal.(type) { case []*ast.Table: for _, t := range pluginSubTable { - if err = c.addProcessor(pluginName, t); err != nil { + if err = c.addProcessor(pluginName, path, t); err != nil { return fmt.Errorf("error parsing %s, %w", pluginName, err) } } @@ -677,7 +759,7 @@ func (c *Config) LoadConfigData(data []byte) error { switch pluginSubTable := pluginVal.(type) { case []*ast.Table: for _, t := range pluginSubTable { - if err = c.addAggregator(pluginName, t); err != nil { + if err = c.addAggregator(pluginName, path, t); err != nil { return fmt.Errorf("error parsing %s, %w", pluginName, err) } } @@ -697,7 +779,7 @@ func (c *Config) LoadConfigData(data []byte) error { switch pluginSubTable := pluginVal.(type) { case []*ast.Table: for _, t := range pluginSubTable { - if err = c.addSecretStore(pluginName, t); err != nil { + if err = c.addSecretStore(pluginName, path, t); err != nil { return fmt.Errorf("error parsing %s, %w", pluginName, err) } } @@ -714,7 +796,7 @@ func (c *Config) LoadConfigData(data []byte) error { // Assume it's an input for legacy config file support if no other // identifiers are present default: - if err = c.addInput(name, subTable); err != nil { + if err = c.addInput(name, path, subTable); err != nil { return fmt.Errorf("error parsing %s, %w", name, err) } } @@ -856,7 +938,7 @@ func parseConfig(contents []byte) (*ast.Table, error) { return toml.Parse(outputBytes) } -func (c *Config) addAggregator(name string, table *ast.Table) error { +func (c *Config) addAggregator(name, source string, table *ast.Table) error { creator, ok := aggregators.Aggregators[name] if !ok { // Handle removed, deprecated plugins @@ -868,7 +950,7 @@ func (c *Config) addAggregator(name string, table *ast.Table) error { } aggregator := creator() - conf, err := c.buildAggregator(name, table) + conf, err := c.buildAggregator(name, source, table) if err != nil { return err } @@ -885,7 +967,7 @@ func (c *Config) addAggregator(name string, table *ast.Table) error { return nil } -func (c *Config) addSecretStore(name string, table *ast.Table) error { +func (c *Config) addSecretStore(name, source string, table *ast.Table) error { if len(c.SecretStoreFilters) > 0 && !sliceContains(name, c.SecretStoreFilters) { return nil } @@ -928,6 +1010,10 @@ func (c *Config) addSecretStore(name string, table *ast.Table) error { return fmt.Errorf("duplicate ID %q for secretstore %q", storeID, name) } c.SecretStores[storeID] = store + if _, found := c.secretStoreSource[name]; !found { + c.secretStoreSource[name] = make([]string, 0) + } + c.secretStoreSource[name] = append(c.secretStoreSource[name], source) return nil } @@ -1057,7 +1143,7 @@ func (c *Config) addSerializer(parentname string, table *ast.Table) (*models.Run return running, err } -func (c *Config) addProcessor(name string, table *ast.Table) error { +func (c *Config) addProcessor(name, source string, table *ast.Table) error { creator, ok := processors.Processors[name] if !ok { // Handle removed, deprecated plugins @@ -1080,7 +1166,7 @@ func (c *Config) addProcessor(name string, table *ast.Table) error { defer c.resetMissingTomlFieldTracker() // Set up the processor running before the aggregators - processorBeforeConfig, err := c.buildProcessor("processors", name, table) + processorBeforeConfig, err := c.buildProcessor("processors", name, source, table) if err != nil { return err } @@ -1092,7 +1178,7 @@ func (c *Config) addProcessor(name string, table *ast.Table) error { c.fileProcessors = append(c.fileProcessors, &OrderedPlugin{table.Line, rf}) // Setup another (new) processor instance running after the aggregator - processorAfterConfig, err := c.buildProcessor("aggprocessors", name, table) + processorAfterConfig, err := c.buildProcessor("aggprocessors", name, source, table) if err != nil { return err } @@ -1180,7 +1266,7 @@ func (c *Config) setupProcessor(name string, creator processors.StreamingCreator return streamingProcessor, optionTestCount, err } -func (c *Config) addOutput(name string, table *ast.Table) error { +func (c *Config) addOutput(name, source string, table *ast.Table) error { if len(c.OutputFilters) > 0 && !sliceContains(name, c.OutputFilters) { return nil } @@ -1228,7 +1314,7 @@ func (c *Config) addOutput(name string, table *ast.Table) error { }) } - outputConfig, err := c.buildOutput(name, table) + outputConfig, err := c.buildOutput(name, source, table) if err != nil { return err } @@ -1263,7 +1349,7 @@ func (c *Config) addOutput(name string, table *ast.Table) error { return nil } -func (c *Config) addInput(name string, table *ast.Table) error { +func (c *Config) addInput(name, source string, table *ast.Table) error { if len(c.InputFilters) > 0 && !sliceContains(name, c.InputFilters) { return nil } @@ -1312,7 +1398,7 @@ func (c *Config) addInput(name string, table *ast.Table) error { }) } - pluginConfig, err := c.buildInput(name, table) + pluginConfig, err := c.buildInput(name, source, table) if err != nil { return err } @@ -1351,9 +1437,10 @@ func (c *Config) addInput(name string, table *ast.Table) error { // buildAggregator parses Aggregator specific items from the ast.Table, // builds the filter and returns a // models.AggregatorConfig to be inserted into models.RunningAggregator -func (c *Config) buildAggregator(name string, tbl *ast.Table) (*models.AggregatorConfig, error) { +func (c *Config) buildAggregator(name, source string, tbl *ast.Table) (*models.AggregatorConfig, error) { conf := &models.AggregatorConfig{ Name: name, + Source: source, Delay: time.Millisecond * 100, Period: time.Second * 30, Grace: time.Second * 0, @@ -1403,8 +1490,11 @@ func (c *Config) buildAggregator(name string, tbl *ast.Table) (*models.Aggregato // buildProcessor parses Processor specific items from the ast.Table, // builds the filter and returns a // models.ProcessorConfig to be inserted into models.RunningProcessor -func (c *Config) buildProcessor(category, name string, tbl *ast.Table) (*models.ProcessorConfig, error) { - conf := &models.ProcessorConfig{Name: name} +func (c *Config) buildProcessor(category, name, source string, tbl *ast.Table) (*models.ProcessorConfig, error) { + conf := &models.ProcessorConfig{ + Name: name, + Source: source, + } conf.Order = c.getFieldInt64(tbl, "order") conf.Alias = c.getFieldString(tbl, "alias") @@ -1509,9 +1599,10 @@ func (c *Config) buildFilter(plugin string, tbl *ast.Table) (models.Filter, erro // buildInput parses input specific items from the ast.Table, // builds the filter and returns a // models.InputConfig to be inserted into models.RunningInput -func (c *Config) buildInput(name string, tbl *ast.Table) (*models.InputConfig, error) { +func (c *Config) buildInput(name, source string, tbl *ast.Table) (*models.InputConfig, error) { cp := &models.InputConfig{ Name: name, + Source: source, AlwaysIncludeLocalTags: c.Agent.AlwaysIncludeLocalTags, AlwaysIncludeGlobalTags: c.Agent.AlwaysIncludeGlobalTags, } @@ -1556,13 +1647,14 @@ func (c *Config) buildInput(name string, tbl *ast.Table) (*models.InputConfig, e // builds the filter and returns a // models.OutputConfig to be inserted into models.RunningInput // Note: error exists in the return for future calls that might require error -func (c *Config) buildOutput(name string, tbl *ast.Table) (*models.OutputConfig, error) { +func (c *Config) buildOutput(name, source string, tbl *ast.Table) (*models.OutputConfig, error) { filter, err := c.buildFilter("outputs."+name, tbl) if err != nil { return nil, err } oc := &models.OutputConfig{ Name: name, + Source: source, Filter: filter, BufferStrategy: c.Agent.BufferStrategy, BufferDirectory: c.Agent.BufferDirectory, diff --git a/config/config_test.go b/config/config_test.go index fee399afe..893c31220 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -70,7 +70,8 @@ func TestConfig_LoadSingleInputWithEnvVars(t *testing.T) { c := config.NewConfig() t.Setenv("MY_TEST_SERVER", "192.168.1.1") t.Setenv("TEST_INTERVAL", "10s") - require.NoError(t, c.LoadConfig("./testdata/single_plugin_env_vars.toml")) + confFile := filepath.Join("testdata", "single_plugin_env_vars.toml") + require.NoError(t, c.LoadConfig(confFile)) input := inputs.Inputs["memcached"]().(*MockupInputPlugin) input.Servers = []string{"192.168.1.1"} @@ -98,6 +99,7 @@ func TestConfig_LoadSingleInputWithEnvVars(t *testing.T) { require.NoError(t, filter.Compile()) inputConfig := &models.InputConfig{ Name: "memcached", + Source: confFile, Filter: filter, Interval: 10 * time.Second, } @@ -113,7 +115,8 @@ func TestConfig_LoadSingleInputWithEnvVars(t *testing.T) { func TestConfig_LoadSingleInput(t *testing.T) { c := config.NewConfig() - require.NoError(t, c.LoadConfig("./testdata/single_plugin.toml")) + confFile := filepath.Join("testdata", "single_plugin.toml") + require.NoError(t, c.LoadConfig(confFile)) input := inputs.Inputs["memcached"]().(*MockupInputPlugin) input.Servers = []string{"localhost"} @@ -139,6 +142,7 @@ func TestConfig_LoadSingleInput(t *testing.T) { require.NoError(t, filter.Compile()) inputConfig := &models.InputConfig{ Name: "memcached", + Source: confFile, Filter: filter, Interval: 5 * time.Second, } @@ -154,7 +158,8 @@ func TestConfig_LoadSingleInput(t *testing.T) { func TestConfig_LoadSingleInput_WithSeparators(t *testing.T) { c := config.NewConfig() - require.NoError(t, c.LoadConfig("./testdata/single_plugin_with_separators.toml")) + confFile := filepath.Join("testdata", "single_plugin_with_separators.toml") + require.NoError(t, c.LoadConfig(confFile)) input := inputs.Inputs["memcached"]().(*MockupInputPlugin) input.Servers = []string{"localhost"} @@ -182,6 +187,7 @@ func TestConfig_LoadSingleInput_WithSeparators(t *testing.T) { require.NoError(t, filter.Compile()) inputConfig := &models.InputConfig{ Name: "memcached", + Source: confFile, Filter: filter, Interval: 5 * time.Second, } @@ -208,7 +214,8 @@ func TestConfig_LoadDirectory(t *testing.T) { c := config.NewConfig() files, err := config.WalkDirectory("./testdata/subconfig") - files = append([]string{"./testdata/single_plugin.toml"}, files...) + confFile := filepath.Join("testdata", "single_plugin.toml") + files = append([]string{confFile}, files...) require.NoError(t, err) require.NoError(t, c.LoadAll(files...)) @@ -240,6 +247,7 @@ func TestConfig_LoadDirectory(t *testing.T) { require.NoError(t, filterMockup.Compile()) expectedConfigs[0] = &models.InputConfig{ Name: "memcached", + Source: confFile, Filter: filterMockup, Interval: 5 * time.Second, } @@ -256,6 +264,7 @@ func TestConfig_LoadDirectory(t *testing.T) { expectedPlugins[1].Command = "/usr/bin/myothercollector --foo=bar" expectedConfigs[1] = &models.InputConfig{ Name: "exec", + Source: filepath.Join("testdata", "subconfig", "exec.conf"), // This is the source of the input MeasurementSuffix: "_myothercollector", } expectedConfigs[1].Tags = make(map[string]string) @@ -284,6 +293,7 @@ func TestConfig_LoadDirectory(t *testing.T) { require.NoError(t, filterMemcached.Compile()) expectedConfigs[2] = &models.InputConfig{ Name: "memcached", + Source: filepath.Join("testdata", "subconfig", "memcached.conf"), // This is the source of the input Filter: filterMemcached, Interval: 5 * time.Second, } @@ -291,7 +301,10 @@ func TestConfig_LoadDirectory(t *testing.T) { expectedPlugins[3] = inputs.Inputs["procstat"]().(*MockupInputPlugin) expectedPlugins[3].PidFile = "/var/run/grafana-server.pid" - expectedConfigs[3] = &models.InputConfig{Name: "procstat"} + expectedConfigs[3] = &models.InputConfig{ + Name: "procstat", + Source: filepath.Join("testdata", "subconfig", "procstat.conf"), // This is the source of the input + } expectedConfigs[3].Tags = make(map[string]string) // Check the generated plugins diff --git a/config/plugin_printer.go b/config/plugin_printer.go new file mode 100644 index 000000000..2b2eeedd7 --- /dev/null +++ b/config/plugin_printer.go @@ -0,0 +1,82 @@ +package config + +import ( + "bytes" + "fmt" + "sort" + "strings" + + "github.com/jedib0t/go-pretty/v6/table" +) + +var headers = []string{"Name", "Source(s)"} + +type pluginPrinter struct { + name string + source string +} + +type pluginNames []pluginPrinter + +func getPluginSourcesTable(pluginNames []pluginPrinter) string { + if !PrintPluginConfigSource { + return "" + } + + data := make([][]any, 0, len(pluginNames)) + rows := make(map[string][]string) + for _, plugin := range pluginNames { + if _, ok := rows[plugin.name]; !ok { + rows[plugin.name] = make([]string, 0) + } + rows[plugin.name] = append(rows[plugin.name], plugin.source) + } + + for name, sources := range rows { + var nameCountStr string + if len(sources) > 1 { + nameCountStr = fmt.Sprintf("%s (%dx)", name, len(sources)) + } else { + nameCountStr = name + } + data = append(data, []any{nameCountStr, sources}) + } + sort.Slice(data, func(i, j int) bool { + return len(data[i][1].([]string)) > len(data[j][1].([]string)) + }) + return getTableString(headers, data) +} + +func getTableString(headers []string, data [][]any) string { + buff := new(bytes.Buffer) + + t := table.NewWriter() + t.SetOutputMirror(buff) + t.AppendHeader(convertToRow(headers)) + + // Append rows + for _, row := range data { + processedRow := make([]interface{}, len(row)) + for i, col := range row { + switch v := col.(type) { + case []string: // Convert slices to multi-line strings + processedRow[i] = strings.Join(v, "\n") + default: + processedRow[i] = v + } + } + t.AppendRow(processedRow) + } + + t.Style().Options.SeparateRows = true + return t.Render() +} + +// Helper function to convert headers to table.Row +func convertToRow(data []string) table.Row { + row := make(table.Row, len(data)) + for i, val := range data { + row[i] = val + } + return row +} diff --git a/config/secret_test.go b/config/secret_test.go index 90fdff579..ae344f946 100644 --- a/config/secret_test.go +++ b/config/secret_test.go @@ -151,7 +151,7 @@ func TestSecretConstant(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewConfig() - require.NoError(t, c.LoadConfigData(tt.cfg)) + require.NoError(t, c.LoadConfigData(tt.cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) // Create a mockup secretstore @@ -302,7 +302,7 @@ func TestSecretUnquote(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewConfig() - require.NoError(t, c.LoadConfigData(tt.cfg)) + require.NoError(t, c.LoadConfigData(tt.cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) // Create a mockup secretstore @@ -331,7 +331,7 @@ func TestSecretEnvironmentVariable(t *testing.T) { t.Setenv("SOME_ENV_SECRET", "an env secret") c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) @@ -364,7 +364,7 @@ func TestSecretCount(t *testing.T) { `) c := NewConfig() - require.NoError(t, c.LoadConfigData(cfg)) + require.NoError(t, c.LoadConfigData(cfg, EmptySourcePath)) require.Len(t, c.Inputs, 3) require.Equal(t, int64(2), secretCount.Load()) @@ -390,7 +390,7 @@ func TestSecretStoreStatic(t *testing.T) { `) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 4) @@ -431,7 +431,7 @@ func TestSecretStoreInvalidKeys(t *testing.T) { `) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 4) @@ -469,7 +469,7 @@ func TestSecretStoreDeclarationMissingID(t *testing.T) { cfg := []byte(`[[secretstores.mockup]]`) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.ErrorContains(t, err, `error parsing mockup, "mockup" secret-store without ID`) } @@ -485,7 +485,7 @@ func TestSecretStoreDeclarationInvalidID(t *testing.T) { t.Run(id, func(t *testing.T) { cfg := []byte(fmt.Sprintf(tmpl, id)) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.ErrorContains(t, err, `error parsing mockup, invalid secret-store ID`) }) } @@ -503,7 +503,7 @@ func TestSecretStoreDeclarationValidID(t *testing.T) { t.Run(id, func(t *testing.T) { cfg := []byte(fmt.Sprintf(tmpl, id)) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.NoError(t, err) }) } @@ -555,7 +555,7 @@ func (tsuite *SecretImplTestSuite) TestSecretStoreInvalidReference() { `) c := NewConfig() - require.NoError(t, c.LoadConfigData(cfg)) + require.NoError(t, c.LoadConfigData(cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) // Create a mockup secretstore @@ -585,7 +585,7 @@ func (tsuite *SecretImplTestSuite) TestSecretStoreStaticChanging() { `) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) @@ -627,7 +627,7 @@ func (tsuite *SecretImplTestSuite) TestSecretStoreDynamic() { `) c := NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) @@ -661,7 +661,7 @@ func (tsuite *SecretImplTestSuite) TestSecretSet() { secret = "a secret" `) c := NewConfig() - require.NoError(t, c.LoadConfigData(cfg)) + require.NoError(t, c.LoadConfigData(cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) require.NoError(t, c.LinkSecrets()) @@ -686,7 +686,7 @@ func (tsuite *SecretImplTestSuite) TestSecretSetResolve() { secret = "@{mock:secret}" `) c := NewConfig() - require.NoError(t, c.LoadConfigData(cfg)) + require.NoError(t, c.LoadConfigData(cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) // Create a mockup secretstore @@ -720,7 +720,7 @@ func (tsuite *SecretImplTestSuite) TestSecretSetResolveInvalid() { secret = "@{mock:secret}" `) c := NewConfig() - require.NoError(t, c.LoadConfigData(cfg)) + require.NoError(t, c.LoadConfigData(cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) // Create a mockup secretstore @@ -757,7 +757,7 @@ func (tsuite *SecretImplTestSuite) TestSecretInvalidWarn() { secret = "server=a user=@{mock:secret-with-invalid-chars} pass=@{mock:secret_pass}" `) c := NewConfig() - require.NoError(t, c.LoadConfigData(cfg)) + require.NoError(t, c.LoadConfigData(cfg, EmptySourcePath)) require.Len(t, c.Inputs, 1) require.Contains(t, buf.String(), `W! Secret "@{mock:secret-with-invalid-chars}" contains invalid character(s)`) diff --git a/config/types_test.go b/config/types_test.go index 0459e798c..2011abc39 100644 --- a/config/types_test.go +++ b/config/types_test.go @@ -23,7 +23,7 @@ func TestConfigDuration(t *testing.T) { [[processors.reverse_dns.lookup]] field = "source_ip" dest = "source_name" -`)) +`), config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Processors, 1) p := c.Processors[0].Processor.(*reverse_dns.ReverseDNS) @@ -121,7 +121,7 @@ func TestTOMLParsingStringDurations(t *testing.T) { // Load the data c := config.NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) plugin := c.Inputs[0].Input.(*MockupTypesPlugin) @@ -151,7 +151,7 @@ func TestTOMLParsingIntegerDurations(t *testing.T) { // Load the data c := config.NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) plugin := c.Inputs[0].Input.(*MockupTypesPlugin) @@ -179,7 +179,7 @@ func TestTOMLParsingFloatDurations(t *testing.T) { // Load the data c := config.NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) plugin := c.Inputs[0].Input.(*MockupTypesPlugin) @@ -217,7 +217,7 @@ func TestTOMLParsingStringSizes(t *testing.T) { // Load the data c := config.NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) plugin := c.Inputs[0].Input.(*MockupTypesPlugin) @@ -249,7 +249,7 @@ func TestTOMLParsingIntegerSizes(t *testing.T) { // Load the data c := config.NewConfig() - err := c.LoadConfigData(cfg) + err := c.LoadConfigData(cfg, config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) plugin := c.Inputs[0].Input.(*MockupTypesPlugin) diff --git a/docs/LICENSE_OF_DEPENDENCIES.md b/docs/LICENSE_OF_DEPENDENCIES.md index af9823d39..0f46199ac 100644 --- a/docs/LICENSE_OF_DEPENDENCIES.md +++ b/docs/LICENSE_OF_DEPENDENCIES.md @@ -236,6 +236,7 @@ following works: - github.com/jcmturner/goidentity [Apache License 2.0](https://github.com/jcmturner/goidentity/blob/master/LICENSE) - github.com/jcmturner/gokrb5 [Apache License 2.0](https://github.com/jcmturner/gokrb5/blob/master/LICENSE) - github.com/jcmturner/rpc [Apache License 2.0](https://github.com/jcmturner/rpc/blob/master/LICENSE) +- github.com/jedib0t/go-pretty [MIT License](https://github.com/jedib0t/go-pretty/blob/main/LICENSE) - github.com/jeremywohl/flatten [MIT License](https://github.com/jeremywohl/flatten/blob/master/LICENSE) - github.com/jhump/protoreflect [Apache License 2.0](https://github.com/jhump/protoreflect/blob/master/LICENSE) - github.com/jmespath/go-jmespath [Apache License 2.0](https://github.com/jmespath/go-jmespath/blob/master/LICENSE) @@ -262,6 +263,7 @@ following works: - github.com/mattn/go-colorable [MIT License](https://github.com/mattn/go-colorable/blob/master/LICENSE) - github.com/mattn/go-ieproxy [MIT License](https://github.com/mattn/go-ieproxy/blob/master/LICENSE) - github.com/mattn/go-isatty [MIT License](https://github.com/mattn/go-isatty/blob/master/LICENSE) +- github.com/mattn/go-runewidth [MIT License](https://github.com/mattn/go-runewidth/blob/master/LICENSE) - github.com/mdlayher/apcupsd [MIT License](https://github.com/mdlayher/apcupsd/blob/master/LICENSE.md) - github.com/mdlayher/genetlink [MIT License](https://github.com/mdlayher/genetlink/blob/master/LICENSE.md) - github.com/mdlayher/netlink [MIT License](https://github.com/mdlayher/netlink/blob/master/LICENSE.md) @@ -336,6 +338,7 @@ following works: - github.com/remyoudompheng/bigfft [BSD 3-Clause "New" or "Revised" License](https://github.com/remyoudompheng/bigfft/blob/master/LICENSE) - github.com/rfjakob/eme [MIT License](https://github.com/rfjakob/eme/blob/master/LICENSE) - github.com/riemann/riemann-go-client [MIT License](https://github.com/riemann/riemann-go-client/blob/master/LICENSE) +- github.com/rivo/uniseg [MIT License](https://github.com/rivo/uniseg/blob/master/LICENSE.txt) - github.com/robbiet480/go.nut [MIT License](https://github.com/robbiet480/go.nut/blob/master/LICENSE) - github.com/robinson/gos7 [BSD 3-Clause "New" or "Revised" License](https://github.com/robinson/gos7/blob/master/LICENSE) - github.com/russross/blackfriday [BSD 2-Clause "Simplified" License](https://github.com/russross/blackfriday/blob/master/LICENSE.txt) diff --git a/go.mod b/go.mod index 3725d6ade..fdac1b768 100644 --- a/go.mod +++ b/go.mod @@ -124,6 +124,7 @@ require ( github.com/jackc/pgio v1.0.0 github.com/jackc/pgtype v1.14.4 github.com/jackc/pgx/v4 v4.18.3 + github.com/jedib0t/go-pretty/v6 v6.6.5 github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4 github.com/jhump/protoreflect v1.16.0 github.com/jmespath/go-jmespath v0.4.0 @@ -408,6 +409,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-ieproxy v0.0.11 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mdlayher/genetlink v1.2.0 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect @@ -455,6 +457,7 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rfjakob/eme v1.1.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 624f1cee8..1e453f971 100644 --- a/go.sum +++ b/go.sum @@ -1686,6 +1686,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6 github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jedib0t/go-pretty/v6 v6.6.5 h1:9PgMJOVBedpgYLI56jQRJYqngxYAAzfEUua+3NgSqAo= +github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs= github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4 h1:eA9wi6ZzpIRobvXkn/S2Lyw1hr2pc71zxzOPl7Xjs4w= @@ -1845,6 +1847,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -2173,6 +2177,9 @@ github.com/rfjakob/eme v1.1.2 h1:SxziR8msSOElPayZNFfQw4Tjx/Sbaeeh3eRvrHVMUs4= github.com/rfjakob/eme v1.1.2/go.mod h1:cVvpasglm/G3ngEfcfT/Wt0GwhkuO32pf/poW6Nyk1k= github.com/riemann/riemann-go-client v0.5.1-0.20211206220514-f58f10cdce16 h1:bGXoxRwUpPTCaQ86DRE+3wqE9vh3aH8W0HH5L/ygOFM= github.com/riemann/riemann-go-client v0.5.1-0.20211206220514-f58f10cdce16/go.mod h1:4rS0vfmzOMwfFPhi6Zve4k/59TsBepqd6WESNULE0ho= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robbiet480/go.nut v0.0.0-20220219091450-bd8f121e1fa1 h1:YmFqprZILGlF/X3tvMA4Rwn3ySxyE3hGUajBHkkaZbM= github.com/robbiet480/go.nut v0.0.0-20220219091450-bd8f121e1fa1/go.mod h1:pL1huxuIlWub46MsMVJg4p7OXkzbPp/APxh9IH0eJjQ= github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA= diff --git a/migrations/general_metricfilter/migration_test.go b/migrations/general_metricfilter/migration_test.go index 402459a73..616e39897 100644 --- a/migrations/general_metricfilter/migration_test.go +++ b/migrations/general_metricfilter/migration_test.go @@ -67,7 +67,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/global_agent/migration_test.go b/migrations/global_agent/migration_test.go index 1533f6fe1..599c8c6c5 100644 --- a/migrations/global_agent/migration_test.go +++ b/migrations/global_agent/migration_test.go @@ -24,7 +24,7 @@ func TestNoMigration(t *testing.T) { expectedBuffer, err := os.ReadFile(fn) require.NoError(t, err) expected := config.NewConfig() - require.NoError(t, expected.LoadConfigData(expectedBuffer)) + require.NoError(t, expected.LoadConfigData(expectedBuffer, config.EmptySourcePath)) require.NotNil(t, expected.Agent) // Migrate @@ -34,7 +34,7 @@ func TestNoMigration(t *testing.T) { require.Zero(t, n) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) require.NotNil(t, actual.Agent) // Test the output @@ -90,7 +90,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.Positive(t, n, "expected migration application but none applied") actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) require.NotNil(t, actual.Agent) // Test the output diff --git a/migrations/inputs_cassandra/migration_test.go b/migrations/inputs_cassandra/migration_test.go index a454376a3..f93021bc8 100644 --- a/migrations/inputs_cassandra/migration_test.go +++ b/migrations/inputs_cassandra/migration_test.go @@ -45,7 +45,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_disk/migration_test.go b/migrations/inputs_disk/migration_test.go index e460d8594..1b92ddcb5 100644 --- a/migrations/inputs_disk/migration_test.go +++ b/migrations/inputs_disk/migration_test.go @@ -70,7 +70,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_gnmi/migration_test.go b/migrations/inputs_gnmi/migration_test.go index 5507a026d..3238e7a96 100644 --- a/migrations/inputs_gnmi/migration_test.go +++ b/migrations/inputs_gnmi/migration_test.go @@ -57,7 +57,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_httpjson/migration_test.go b/migrations/inputs_httpjson/migration_test.go index 9d77d2a03..3bf6fab5d 100644 --- a/migrations/inputs_httpjson/migration_test.go +++ b/migrations/inputs_httpjson/migration_test.go @@ -53,7 +53,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_io/migration_test.go b/migrations/inputs_io/migration_test.go index 384ed0a2b..26a6f66cb 100644 --- a/migrations/inputs_io/migration_test.go +++ b/migrations/inputs_io/migration_test.go @@ -45,7 +45,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_jolokia/migration_test.go b/migrations/inputs_jolokia/migration_test.go index 3a69adca3..1d0caeb24 100644 --- a/migrations/inputs_jolokia/migration_test.go +++ b/migrations/inputs_jolokia/migration_test.go @@ -46,7 +46,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_mqtt_consumer/migration_test.go b/migrations/inputs_mqtt_consumer/migration_test.go index a1494e3cf..dc2530d22 100644 --- a/migrations/inputs_mqtt_consumer/migration_test.go +++ b/migrations/inputs_mqtt_consumer/migration_test.go @@ -145,7 +145,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_nats_consumer/migration_test.go b/migrations/inputs_nats_consumer/migration_test.go index 66ab428fd..b025f9d03 100644 --- a/migrations/inputs_nats_consumer/migration_test.go +++ b/migrations/inputs_nats_consumer/migration_test.go @@ -119,7 +119,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_procstat/migration_test.go b/migrations/inputs_procstat/migration_test.go index 23bd45e94..04c73e18f 100644 --- a/migrations/inputs_procstat/migration_test.go +++ b/migrations/inputs_procstat/migration_test.go @@ -57,7 +57,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_sflow/migration_test.go b/migrations/inputs_sflow/migration_test.go index cf6cd286a..da7e8e257 100644 --- a/migrations/inputs_sflow/migration_test.go +++ b/migrations/inputs_sflow/migration_test.go @@ -46,7 +46,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_tcp_listener/migration_test.go b/migrations/inputs_tcp_listener/migration_test.go index ca0dcda6a..c9f115640 100644 --- a/migrations/inputs_tcp_listener/migration_test.go +++ b/migrations/inputs_tcp_listener/migration_test.go @@ -46,7 +46,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/inputs_udp_listener/migration_test.go b/migrations/inputs_udp_listener/migration_test.go index 368b8ff17..c6a11ab65 100644 --- a/migrations/inputs_udp_listener/migration_test.go +++ b/migrations/inputs_udp_listener/migration_test.go @@ -46,7 +46,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Inputs, len(expected.Inputs)) diff --git a/migrations/outputs_influxdb/migration_test.go b/migrations/outputs_influxdb/migration_test.go index 9731e8611..3272a8935 100644 --- a/migrations/outputs_influxdb/migration_test.go +++ b/migrations/outputs_influxdb/migration_test.go @@ -57,7 +57,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Outputs, len(expected.Outputs)) diff --git a/migrations/outputs_riemann_legacy/migration_test.go b/migrations/outputs_riemann_legacy/migration_test.go index cf570e483..27e69bff4 100644 --- a/migrations/outputs_riemann_legacy/migration_test.go +++ b/migrations/outputs_riemann_legacy/migration_test.go @@ -45,7 +45,7 @@ func TestCases(t *testing.T) { require.NotEmpty(t, output) require.GreaterOrEqual(t, n, uint64(1)) actual := config.NewConfig() - require.NoError(t, actual.LoadConfigData(output)) + require.NoError(t, actual.LoadConfigData(output, config.EmptySourcePath)) // Test the output require.Len(t, actual.Outputs, len(expected.Outputs)) diff --git a/models/running_aggregator.go b/models/running_aggregator.go index b73cbd6c0..50c76fb7f 100644 --- a/models/running_aggregator.go +++ b/models/running_aggregator.go @@ -70,6 +70,7 @@ func NewRunningAggregator(aggregator telegraf.Aggregator, config *AggregatorConf // AggregatorConfig is the common config for all aggregators. type AggregatorConfig struct { Name string + Source string Alias string ID string DropOriginal bool diff --git a/models/running_input.go b/models/running_input.go index 62ab73e70..a331e5895 100644 --- a/models/running_input.go +++ b/models/running_input.go @@ -83,6 +83,7 @@ func NewRunningInput(input telegraf.Input, config *InputConfig) *RunningInput { // InputConfig is the common config for all inputs. type InputConfig struct { Name string + Source string Alias string ID string Interval time.Duration diff --git a/models/running_output.go b/models/running_output.go index 2d3468e2d..8718efe33 100644 --- a/models/running_output.go +++ b/models/running_output.go @@ -24,6 +24,7 @@ const ( // OutputConfig containing name and filter type OutputConfig struct { Name string + Source string Alias string ID string StartupErrorBehavior string diff --git a/models/running_processor.go b/models/running_processor.go index 3f54cb960..30275e3a7 100644 --- a/models/running_processor.go +++ b/models/running_processor.go @@ -24,6 +24,7 @@ func (rp RunningProcessors) Less(i, j int) bool { return rp[i].Config.Order < rp // ProcessorConfig containing a name and filter type ProcessorConfig struct { Name string + Source string Alias string ID string Order int64 diff --git a/plugins/inputs/exec/exec_test.go b/plugins/inputs/exec/exec_test.go index eb605f8fd..b49dc8d07 100644 --- a/plugins/inputs/exec/exec_test.go +++ b/plugins/inputs/exec/exec_test.go @@ -417,7 +417,7 @@ func TestCases(t *testing.T) { commands = [ "echo \"a,b\n1,2\n3,4\"" ] data_format = "csv" csv_header_row_count = 1 -`))) +`), config.EmptySourcePath)) require.Len(t, cfg.Inputs, 1) plugin := cfg.Inputs[0] require.NoError(t, plugin.Init()) diff --git a/plugins/inputs/execd/execd_test.go b/plugins/inputs/execd/execd_test.go index d4dfcf00c..c4c902f7b 100644 --- a/plugins/inputs/execd/execd_test.go +++ b/plugins/inputs/execd/execd_test.go @@ -32,7 +32,7 @@ func TestSettingConfigWorks(t *testing.T) { signal = "SIGHUP" ` conf := config.NewConfig() - require.NoError(t, conf.LoadConfigData([]byte(cfg))) + require.NoError(t, conf.LoadConfigData([]byte(cfg), config.EmptySourcePath)) require.Len(t, conf.Inputs, 1) inp, ok := conf.Inputs[0].Input.(*Execd) diff --git a/plugins/inputs/opcua/opcua_test.go b/plugins/inputs/opcua/opcua_test.go index 2c0bc5591..e5a43fbeb 100644 --- a/plugins/inputs/opcua/opcua_test.go +++ b/plugins/inputs/opcua/opcua_test.go @@ -361,7 +361,7 @@ use_unregistered_reads = true ` c := config.NewConfig() - err := c.LoadConfigData([]byte(toml)) + err := c.LoadConfigData([]byte(toml), config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) diff --git a/plugins/inputs/opcua_listener/opcua_listener_test.go b/plugins/inputs/opcua_listener/opcua_listener_test.go index 5484252bb..50856011f 100644 --- a/plugins/inputs/opcua_listener/opcua_listener_test.go +++ b/plugins/inputs/opcua_listener/opcua_listener_test.go @@ -426,7 +426,7 @@ additional_valid_status_codes = ["0xC0"] ` c := config.NewConfig() - err := c.LoadConfigData([]byte(toml)) + err := c.LoadConfigData([]byte(toml), config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) @@ -515,7 +515,7 @@ deadband_value = 100.0 ` c := config.NewConfig() - err := c.LoadConfigData([]byte(toml)) + err := c.LoadConfigData([]byte(toml), config.EmptySourcePath) require.NoError(t, err) require.Len(t, c.Inputs, 1) diff --git a/plugins/outputs/sumologic/sumologic_test.go b/plugins/outputs/sumologic/sumologic_test.go index c9b98035b..fa690d2b0 100644 --- a/plugins/outputs/sumologic/sumologic_test.go +++ b/plugins/outputs/sumologic/sumologic_test.go @@ -489,9 +489,9 @@ func TestTOMLConfig(t *testing.T) { c := config.NewConfig() if tt.expectedError { - require.Error(t, c.LoadConfigData(tt.configBytes)) + require.Error(t, c.LoadConfigData(tt.configBytes, config.EmptySourcePath)) } else { - require.NoError(t, c.LoadConfigData(tt.configBytes)) + require.NoError(t, c.LoadConfigData(tt.configBytes, config.EmptySourcePath)) } }) } diff --git a/plugins/processors/snmp_lookup/lookup_test.go b/plugins/processors/snmp_lookup/lookup_test.go index 61c24a243..570810858 100644 --- a/plugins/processors/snmp_lookup/lookup_test.go +++ b/plugins/processors/snmp_lookup/lookup_test.go @@ -6,15 +6,15 @@ import ( "testing" "time" + "github.com/gosnmp/gosnmp" + "github.com/stretchr/testify/require" + "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/config" "github.com/influxdata/telegraf/internal/snmp" "github.com/influxdata/telegraf/metric" "github.com/influxdata/telegraf/plugins/processors" "github.com/influxdata/telegraf/testutil" - - "github.com/gosnmp/gosnmp" - "github.com/stretchr/testify/require" ) type testSNMPConnection struct { @@ -60,7 +60,7 @@ func TestRegistry(t *testing.T) { func TestSampleConfig(t *testing.T) { cfg := config.NewConfig() - require.NoError(t, cfg.LoadConfigData(testutil.DefaultSampleConfig((&Lookup{}).SampleConfig()))) + require.NoError(t, cfg.LoadConfigData(testutil.DefaultSampleConfig((&Lookup{}).SampleConfig()), config.EmptySourcePath)) } func TestInit(t *testing.T) { diff --git a/plugins/processors/starlark/starlark_test.go b/plugins/processors/starlark/starlark_test.go index e9ef5c770..02faf1160 100644 --- a/plugins/processors/starlark/starlark_test.go +++ b/plugins/processors/starlark/starlark_test.go @@ -2647,7 +2647,7 @@ def apply(metric): // Build a Starlark plugin from the provided configuration. func buildPlugin(configContent string) (*Starlark, error) { c := config.NewConfig() - err := c.LoadConfigData([]byte(configContent)) + err := c.LoadConfigData([]byte(configContent), config.EmptySourcePath) if err != nil { return nil, err }