From 8e515688ebfabce40d0fbc509c3ad512063bb148 Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Wed, 14 Mar 2018 20:09:01 +0100 Subject: [PATCH] Add output of stderr in case of error to exec log message (#3862) If the command failed with a non-zero exit status there might be an error message on stderr. Append the first line to the error message to ease the search for its cause. --- plugins/inputs/exec/exec.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/plugins/inputs/exec/exec.go b/plugins/inputs/exec/exec.go index bcd1cc8e5..9cb86c3cd 100644 --- a/plugins/inputs/exec/exec.go +++ b/plugins/inputs/exec/exec.go @@ -41,6 +41,8 @@ const sampleConfig = ` data_format = "influx" ` +const MaxStderrBytes = 512 + type Exec struct { Commands []string Command string @@ -96,15 +98,41 @@ func (c CommandRunner) Run( cmd := exec.Command(split_cmd[0], split_cmd[1:]...) - var out bytes.Buffer + var ( + out bytes.Buffer + stderr bytes.Buffer + ) cmd.Stdout = &out + cmd.Stderr = &stderr if err := internal.RunTimeout(cmd, e.Timeout.Duration); err != nil { switch e.parser.(type) { case *nagios.NagiosParser: AddNagiosState(err, acc) default: - return nil, fmt.Errorf("exec: %s for command '%s'", err, command) + var errMessage = "" + if stderr.Len() > 0 { + stderr = removeCarriageReturns(stderr) + // Limit the number of bytes. + didTruncate := false + if stderr.Len() > MaxStderrBytes { + stderr.Truncate(MaxStderrBytes) + didTruncate = true + } + if i := bytes.IndexByte(stderr.Bytes(), '\n'); i > 0 { + // Only show truncation if the newline wasn't the last character. + if i < stderr.Len()-1 { + didTruncate = true + } + stderr.Truncate(i) + } + if didTruncate { + stderr.WriteString("...") + } + + errMessage = fmt.Sprintf(": %s", stderr.String()) + } + return nil, fmt.Errorf("exec: %s for command '%s'%s", err, command, errMessage) } } else { switch e.parser.(type) {