diff --git a/agent/agent.go b/agent/agent.go index d9c3a6c03..5d3f7dcf0 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -120,7 +120,7 @@ func (a *Agent) Run(ctx context.Context) error { } log.Printf("D! [agent] Initializing plugins") - if err := a.initPlugins(); err != nil { + if err := a.InitPlugins(); err != nil { return err } @@ -207,8 +207,8 @@ func (a *Agent) Run(ctx context.Context) error { return err } -// initPlugins runs the Init function on plugins. -func (a *Agent) initPlugins() error { +// InitPlugins runs the Init function on plugins. +func (a *Agent) InitPlugins() error { for _, input := range a.Config.Inputs { // Share the snmp translator setting with plugins that need it. if tp, ok := input.Input.(snmp.TranslatorPlugin); ok { @@ -1003,8 +1003,7 @@ func (a *Agent) Test(ctx context.Context, wait time.Duration) error { // inputs to run. func (a *Agent) runTest(ctx context.Context, wait time.Duration, outputC chan<- telegraf.Metric) error { log.Printf("D! [agent] Initializing plugins") - err := a.initPlugins() - if err != nil { + if err := a.InitPlugins(); err != nil { return err } @@ -1017,6 +1016,7 @@ func (a *Agent) runTest(ctx context.Context, wait time.Duration, outputC chan<- if len(a.Config.Aggregators) != 0 { procC := next if len(a.Config.AggProcessors) != 0 && !a.Config.Agent.SkipProcessorsAfterAggregators { + var err error procC, apu, err = a.startProcessors(next, a.Config.AggProcessors) if err != nil { return err @@ -1028,6 +1028,7 @@ func (a *Agent) runTest(ctx context.Context, wait time.Duration, outputC chan<- var pu []*processorUnit if len(a.Config.Processors) != 0 { + var err error next, pu, err = a.startProcessors(next, a.Config.Processors) if err != nil { return err @@ -1098,8 +1099,7 @@ func (a *Agent) Once(ctx context.Context, wait time.Duration) error { // inputs to run. func (a *Agent) runOnce(ctx context.Context, wait time.Duration) error { log.Printf("D! [agent] Initializing plugins") - err := a.initPlugins() - if err != nil { + if err := a.InitPlugins(); err != nil { return err } diff --git a/cmd/telegraf/cmd_config.go b/cmd/telegraf/cmd_config.go index 14d4c2331..d38ef88b0 100644 --- a/cmd/telegraf/cmd_config.go +++ b/cmd/telegraf/cmd_config.go @@ -12,17 +12,18 @@ import ( "github.com/urfave/cli/v2" + "github.com/influxdata/telegraf/agent" "github.com/influxdata/telegraf/config" "github.com/influxdata/telegraf/logger" "github.com/influxdata/telegraf/migrations" ) -func getConfigCommands(pluginFilterFlags []cli.Flag, outputBuffer io.Writer) []*cli.Command { +func getConfigCommands(configHandlingFlags []cli.Flag, outputBuffer io.Writer) []*cli.Command { return []*cli.Command{ { Name: "config", Usage: "commands for generating and migrating configurations", - Flags: pluginFilterFlags, + Flags: configHandlingFlags, Action: func(cCtx *cli.Context) error { // The sub_Filters are populated when the filter flags are set after the subcommand config // e.g. telegraf config --section-filter inputs @@ -32,6 +33,61 @@ func getConfigCommands(pluginFilterFlags []cli.Flag, outputBuffer io.Writer) []* return nil }, Subcommands: []*cli.Command{ + { + Name: "check", + Usage: "check configuration file(s) for issues", + Description: ` + The 'check' command reads the configuration files specified via '--config' or + '--config-directory' and tries to initialize, but not start, the plugins. + Syntax and semantic errors detectable without starting the plugins will + be reported. + If no configuration file is explicitly specified the command reads the + default locations and uses those configuration files. + + To check the file 'mysettings.conf' use + + > telegraf config check --config mysettings.conf + `, + Flags: configHandlingFlags, + Action: func(cCtx *cli.Context) error { + // Setup logging + logConfig := &logger.Config{Debug: cCtx.Bool("debug")} + if err := logger.SetupLogging(logConfig); err != nil { + return err + } + + // Collect the given configuration files + configFiles := cCtx.StringSlice("config") + configDir := cCtx.StringSlice("config-directory") + for _, fConfigDirectory := range configDir { + files, err := config.WalkDirectory(fConfigDirectory) + if err != nil { + return err + } + configFiles = append(configFiles, files...) + } + + // If no "config" or "config-directory" flag(s) was + // provided we should load default configuration files + if len(configFiles) == 0 { + paths, err := config.GetDefaultConfigPath() + if err != nil { + return err + } + configFiles = paths + } + + // Load the config and try to initialize the plugins + c := config.NewConfig() + c.Agent.Quiet = cCtx.Bool("quiet") + if err := c.LoadAll(configFiles...); err != nil { + return err + } + + ag := agent.NewAgent(c) + return ag.InitPlugins() + }, + }, { Name: "create", Usage: "create a full sample configuration and show it", @@ -49,7 +105,7 @@ InfluxDB v2 output plugin use > telegraf config create --section-filter "inputs:outputs" --input-filter "modbus" --output-filter "influxdb_v2" `, - Flags: pluginFilterFlags, + Flags: configHandlingFlags, Action: func(cCtx *cli.Context) error { filters := processFilterFlags(cCtx) @@ -74,7 +130,7 @@ those files unattended! To migrate the file 'mysettings.conf' use -> telegraf --config mysettings.conf config migrate +> telegraf config migrate --config mysettings.conf `, Flags: []cli.Flag{ &cli.BoolFlag{ diff --git a/cmd/telegraf/main.go b/cmd/telegraf/main.go index af396e89f..6821a6020 100644 --- a/cmd/telegraf/main.go +++ b/cmd/telegraf/main.go @@ -99,7 +99,15 @@ func deleteEmpty(s []string) []string { // runApp defines all the subcommands and flags for Telegraf // this abstraction is used for testing, so outputBuffer and args can be changed func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfig, m App) error { - pluginFilterFlags := []cli.Flag{ + configHandlingFlags := []cli.Flag{ + &cli.StringSliceFlag{ + Name: "config", + Usage: "configuration file to load", + }, + &cli.StringSliceFlag{ + Name: "config-directory", + Usage: "directory containing additional *.conf files", + }, &cli.StringFlag{ Name: "section-filter", Usage: "filter the sections to print, separator is ':'. " + @@ -127,7 +135,7 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi }, } - extraFlags := append(pluginFilterFlags, cliFlags()...) + mainFlags := append(configHandlingFlags, cliFlags()...) // This function is used when Telegraf is run with only flags action := func(cCtx *cli.Context) error { @@ -247,7 +255,7 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi } commands := append( - getConfigCommands(pluginFilterFlags, outputBuffer), + getConfigCommands(configHandlingFlags, outputBuffer), getSecretStoreCommands(m)..., ) commands = append(commands, getPluginCommands(outputBuffer)...) @@ -259,15 +267,6 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi Writer: outputBuffer, Flags: append( []cli.Flag{ - // String slice flags - &cli.StringSliceFlag{ - Name: "config", - Usage: "configuration file to load", - }, - &cli.StringSliceFlag{ - Name: "config-directory", - Usage: "directory containing additional *.conf files", - }, // Int flags &cli.IntFlag{ Name: "test-wait", @@ -368,7 +367,7 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi Usage: "DEPRECATED: path to directory containing external plugins", }, // !!! - }, extraFlags...), + }, mainFlags...), Action: action, Commands: append([]*cli.Command{ {