feat(inputs.exec): Add option to ignore return code (#15400)

This commit is contained in:
Joshua Powers 2024-06-03 10:53:14 -06:00 committed by GitHub
parent a92d443a5b
commit 0a7aa308c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 25 deletions

View File

@ -21,11 +21,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
# Read metrics from one or more commands that can output to stdout
[[inputs.exec]]
## Commands array
commands = [
"/tmp/test.sh",
"/usr/bin/mycollector --foo=bar",
"/tmp/collect_*.sh"
]
commands = []
## Environment variables
## Array of "key=value" pairs to pass as environment variables
@ -34,16 +30,24 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
# environment = []
## Timeout for each command to complete.
timeout = "5s"
# timeout = "5s"
## measurement name suffix (for separating different commands)
name_suffix = "_mycollector"
## Measurement name suffix
## Used for separating different commands
# name_suffix = ""
## Data format to consume.
## Each data format has its own unique set of configuration options, read
## more about them here:
## Ignore Error Code
## If set to true, a non-zero error code in not considered an error and the
## plugin will continue to parse the output.
# ignore_error = false
## Data format
## By default, exec expects JSON. This was done for historical reasons and is
## different than other inputs that use the influx line protocol. Each data
## format has its own unique set of configuration options, read more about
## them here:
## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
data_format = "influx"
# data_format = "json"
```
Glob patterns in the `command` option are matched on every run, so adding new

View File

@ -31,6 +31,7 @@ type Exec struct {
Commands []string `toml:"commands"`
Command string `toml:"command"`
Environment []string `toml:"environment"`
IgnoreError bool `toml:"ignore_error"`
Timeout config.Duration `toml:"timeout"`
Log telegraf.Logger `toml:"-"`
@ -105,7 +106,7 @@ func (e *Exec) ProcessCommand(command string, acc telegraf.Accumulator, wg *sync
defer wg.Done()
out, errBuf, runErr := e.runner.Run(command, e.Environment, time.Duration(e.Timeout))
if !e.parseDespiteError && runErr != nil {
if !e.IgnoreError && !e.parseDespiteError && runErr != nil {
err := fmt.Errorf("exec: %w for command %q: %s", runErr, command, string(errBuf))
acc.AddError(err)
return

View File

@ -143,6 +143,34 @@ func TestCommandError(t *testing.T) {
require.Equal(t, 0, acc.NFields(), "No new points should have been added")
}
func TestCommandIgnoreError(t *testing.T) {
parser := &json.Parser{MetricName: "exec"}
require.NoError(t, parser.Init())
e := &Exec{
Log: testutil.Logger{},
runner: newRunnerMock([]byte(validJSON), []byte("error"), errors.New("exit status code 1")),
Commands: []string{"badcommand"},
IgnoreError: true,
parser: parser,
}
var acc testutil.Accumulator
require.NoError(t, acc.GatherError(e.Gather))
require.Equal(t, 8, acc.NFields(), "non-numeric measurements should be ignored")
fields := map[string]interface{}{
"num_processes": float64(82),
"cpu_used": float64(8234),
"cpu_free": float64(32),
"percent": float64(0.81),
"users_0": float64(0),
"users_1": float64(1),
"users_2": float64(2),
"users_3": float64(3),
}
acc.AssertContainsFields(t, "exec", fields)
}
func TestExecCommandWithGlob(t *testing.T) {
parser := value.Parser{
MetricName: "metric",

View File

@ -1,11 +1,7 @@
# Read metrics from one or more commands that can output to stdout
[[inputs.exec]]
## Commands array
commands = [
"/tmp/test.sh",
"/usr/bin/mycollector --foo=bar",
"/tmp/collect_*.sh"
]
commands = []
## Environment variables
## Array of "key=value" pairs to pass as environment variables
@ -14,13 +10,21 @@
# environment = []
## Timeout for each command to complete.
timeout = "5s"
# timeout = "5s"
## measurement name suffix (for separating different commands)
name_suffix = "_mycollector"
## Measurement name suffix
## Used for separating different commands
# name_suffix = ""
## Data format to consume.
## Each data format has its own unique set of configuration options, read
## more about them here:
## Ignore Error Code
## If set to true, a non-zero error code in not considered an error and the
## plugin will continue to parse the output.
# ignore_error = false
## Data format
## By default, exec expects JSON. This was done for historical reasons and is
## different than other inputs that use the influx line protocol. Each data
## format has its own unique set of configuration options, read more about
## them here:
## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
data_format = "influx"
# data_format = "json"