From d30b49fcf0c061e78844dee6174a91b765cc94c5 Mon Sep 17 00:00:00 2001 From: katarzyna-z Date: Mon, 3 Oct 2016 12:17:59 +0200 Subject: [PATCH] Fix for issue #1167, added handling of errors which are returned by scanner --- control/plugin/execution.go | 67 +++++++++++++------ .../snap-plugin-collector-mock2/mock/mock.go | 18 ++++- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/control/plugin/execution.go b/control/plugin/execution.go index 18a32f2ed..aad73c6ca 100644 --- a/control/plugin/execution.go +++ b/control/plugin/execution.go @@ -115,20 +115,35 @@ func (e *ExecutablePlugin) Run(timeout time.Duration) (Response, error) { e.cmd.Start() e.captureStderr() go func() { - for stdOutScanner.Scan() { - // The first chunk from the scanner is the plugin's response to the - // handshake. Once we've received that, we can begin to forward - // logs on to snapd's log. - if !respReceived { - respBytes := stdOutScanner.Bytes() - err = json.Unmarshal(respBytes, &resp) - respReceived = true - close(doneChan) - } else { - execLogger.WithFields(log.Fields{ - "plugin": path.Base(e.cmd.Path()), - "io": "stdout", - }).Debug(stdOutScanner.Text()) + for { + for stdOutScanner.Scan() { + // The first chunk from the scanner is the plugin's response to the + // handshake. Once we've received that, we can begin to forward + // logs on to snapd's log. + if !respReceived { + respBytes := stdOutScanner.Bytes() + err = json.Unmarshal(respBytes, &resp) + respReceived = true + close(doneChan) + } else { + execLogger.WithFields(log.Fields{ + "plugin": path.Base(e.cmd.Path()), + "io": "stdout", + }).Debug(stdOutScanner.Text()) + } + } + + if err := stdOutScanner.Err(); err != nil { + reader := bufio.NewReader(e.stdout) + log, err := reader.ReadString('\n') + + execLogger. + WithField("plugin", path.Base(e.cmd.Path())). + WithField("io", "stdout"). + WithField("scanner_err", stdOutScanner.Err()). + WithField("read_string_err", err). + Warn(log) + continue } } }() @@ -167,12 +182,26 @@ func (e *ExecutablePlugin) Kill() error { func (e *ExecutablePlugin) captureStderr() { stdErrScanner := bufio.NewScanner(e.stderr) go func() { - for stdErrScanner.Scan() { - execLogger. - WithField("io", "stderr"). - WithField("plugin", path.Base(e.cmd.Path())). - Debug(stdErrScanner.Text()) + for { + for stdErrScanner.Scan() { + execLogger. + WithField("plugin", path.Base(e.cmd.Path())). + WithField("io", "stderr"). + Debug(stdErrScanner.Text()) + } + if err := stdErrScanner.Err(); err != nil { + reader := bufio.NewReader(e.stderr) + log, err := reader.ReadString('\n') + + execLogger. + WithField("plugin", path.Base(e.cmd.Path())). + WithField("io", "stderr"). + WithField("scanner_err", stdErrScanner.Err()). + WithField("read_string_err", err). + Warn(log) + continue + } } }() } diff --git a/plugin/collector/snap-plugin-collector-mock2/mock/mock.go b/plugin/collector/snap-plugin-collector-mock2/mock/mock.go index 9e8e6a478..a0bd15f05 100644 --- a/plugin/collector/snap-plugin-collector-mock2/mock/mock.go +++ b/plugin/collector/snap-plugin-collector-mock2/mock/mock.go @@ -20,9 +20,11 @@ limitations under the License. package mock import ( + "bufio" "fmt" "log" "math/rand" + "os" "time" "github.com/intelsdi-x/snap/control/plugin" @@ -56,14 +58,24 @@ func (f *Mock) CollectMetrics(mts []plugin.MetricType) ([]plugin.MetricType, err rand.Seed(time.Now().UTC().UnixNano()) metrics := []plugin.MetricType{} for i := range mts { - if c, ok := mts[i].Config().Table()["long_print"]; ok && c.(ctypes.ConfigValueBool).Value { + if c, ok := mts[i].Config().Table()["long_stdout_log"]; ok && c.(ctypes.ConfigValueBool).Value { letterBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" longLine := []byte{} - for i := 0; i < 8193; i++ { + for i := 0; i < bufio.MaxScanTokenSize; i++ { longLine = append(longLine, letterBytes[rand.Intn(len(letterBytes))]) } - fmt.Println(string(longLine)) + fmt.Fprintln(os.Stdout, string(longLine)) } + + if c, ok := mts[i].Config().Table()["long_stderr_log"]; ok && c.(ctypes.ConfigValueBool).Value { + letterBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + longLine := []byte{} + for i := 0; i < bufio.MaxScanTokenSize; i++ { + longLine = append(longLine, letterBytes[rand.Intn(len(letterBytes))]) + } + fmt.Fprintln(os.Stderr, string(longLine)) + } + if c, ok := mts[i].Config().Table()["panic"]; ok && c.(ctypes.ConfigValueBool).Value { panic("Oops!") }