From 1398f8e6784a5dbe71348cc6841f772749f5d8cf 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. (cherry picked from commit 8e515688ebfabce40d0fbc509c3ad512063bb148) --- 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) {