// collect collects sysstat data with the collector utility sadc. // It runs the following command: // Sadc -S <Activity1> -S <Activity2> ... <collectInterval> 2 tmpFile // The above command collects system metrics during <collectInterval> and // saves it in binary form to tmpFile. func (s *Sysstat) collect() error { options := []string{} for _, act := range s.Activities { options = append(options, "-S", act) } s.tmpFile = path.Join("/tmp", fmt.Sprintf("sysstat-%d", time.Now().Unix())) // collectInterval has to be smaller than the telegraf data collection interval collectInterval := s.interval - parseInterval // If true, interval is not defined yet and Gather is run for the first time. if collectInterval < 0 { collectInterval = 1 // In that case we only collect for 1 second. } options = append(options, strconv.Itoa(collectInterval), "2", s.tmpFile) cmd := execCommand(s.Sadc, options...) out, err := internal.CombinedOutputTimeout(cmd, time.Second*time.Duration(collectInterval+parseInterval)) if err != nil { if err := os.Remove(s.tmpFile); err != nil { log.Printf("failed to remove tmp file after %s command: %s", strings.Join(cmd.Args, " "), err) } return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out)) } return nil }
func hostPinger(timeout float64, args ...string) (string, error) { bin, err := exec.LookPath("ping") if err != nil { return "", err } c := exec.Command(bin, args...) out, err := internal.CombinedOutputTimeout(c, time.Second*time.Duration(timeout+1)) return string(out), err }
func (t CommandRunner) Run(conn *Connection, args ...string) (string, error) { cmd := t.cmd(conn, args...) output, err := internal.CombinedOutputTimeout(cmd, time.Second*5) if err != nil { return "", fmt.Errorf("run %s %s: %s (%s)", cmd.Path, strings.Join(cmd.Args, " "), string(output), err) } return string(output), err }
// parse forks the command: // sensors -u -A // and parses the output to add it to the telegraf.Accumulator. func (s *Sensors) parse(acc telegraf.Accumulator) error { tags := map[string]string{} fields := map[string]interface{}{} chip := "" cmd := execCommand(s.path, "-A", "-u") out, err := internal.CombinedOutputTimeout(cmd, time.Second*5) if err != nil { return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out)) } lines := strings.Split(strings.TrimSpace(string(out)), "\n") for _, line := range lines { if len(line) == 0 { acc.AddFields("sensors", fields, tags) chip = "" tags = map[string]string{} fields = map[string]interface{}{} continue } if len(chip) == 0 { chip = line tags["chip"] = chip continue } if !strings.HasPrefix(line, " ") { if len(tags) > 1 { acc.AddFields("sensors", fields, tags) } fields = map[string]interface{}{} tags = map[string]string{ "chip": chip, "feature": strings.TrimRight(snake(line), ":"), } } else { splitted := strings.Split(line, ":") fieldName := strings.TrimSpace(splitted[0]) if s.RemoveNumbers { fieldName = numberRegp.ReplaceAllString(fieldName, "") } fieldValue, err := strconv.ParseFloat(strings.TrimSpace(splitted[1]), 64) if err != nil { return err } fields[fieldName] = fieldValue } } acc.AddFields("sensors", fields, tags) return nil }
func (c *Chrony) Gather(acc telegraf.Accumulator) error { if len(c.path) == 0 { return errors.New("chronyc not found: verify that chrony is installed and that chronyc is in your PATH") } cmd := execCommand(c.path, "tracking") out, err := internal.CombinedOutputTimeout(cmd, time.Second*5) if err != nil { return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out)) } fields, tags, err := processChronycOutput(string(out)) if err != nil { return err } acc.AddFields("chrony", fields, tags) return nil }