func (c *ProgramCollector) runProgram(dpchan chan<- *opentsdb.DataPoint) (progError error) { cmd := exec.Command(c.Path) setupExternalCommand(cmd) pr, pw := io.Pipe() s := bufio.NewScanner(pr) cmd.Stdout = pw er, ew := io.Pipe() cmd.Stderr = ew if err := cmd.Start(); err != nil { return err } go func() { progError = cmd.Wait() pw.Close() ew.Close() }() go func() { es := bufio.NewScanner(er) for es.Scan() { line := strings.TrimSpace(es.Text()) slog.Error(line) } }() for s.Scan() { var errs []error t := strings.TrimSpace(s.Text()) if len(t) == 0 { continue } if dp, err := parseTcollectorValue(t); err == nil { dpchan <- dp continue } else { errs = append(errs, fmt.Errorf("tcollector: %v", err)) } var dp opentsdb.DataPoint if err := json.Unmarshal([]byte(t), &dp); err != nil { errs = append(errs, fmt.Errorf("opentsdb.DataPoint: %v", err)) } else if dp.Valid() { if dp.Tags == nil { dp.Tags = opentsdb.TagSet{} } setExternalTags(dp.Tags) c.ApplyTags(dp.Tags) dpchan <- &dp continue } else { errs = append(errs, fmt.Errorf("opentsdb.DataPoint: invalid data")) } var m metadata.Metasend if err := json.Unmarshal([]byte(t), &m); err != nil { errs = append(errs, fmt.Errorf("metadata.Metasend: %v", err)) } else { if m.Tags == nil { m.Tags = opentsdb.TagSet{} } setExternalTags(m.Tags) if m.Value == "" || m.Name == "" || (m.Metric == "" && len(m.Tags) == 0) { errs = append(errs, fmt.Errorf("metadata.Metasend: invalid data")) } else { metadata.AddMeta(m.Metric, m.Tags, m.Name, m.Value, false) continue } } slog.Errorf("%s: unparseable line: %s", c.Path, t) for _, e := range errs { slog.Error(e) } } if err := s.Err(); err != nil { return err } return }