Skip to content

Commit

Permalink
fix: sysstat use unique temp file vs hard-coded (#10165)
Browse files Browse the repository at this point in the history
  • Loading branch information
powersj authored Dec 1, 2021
1 parent 7675ce6 commit 7053fec
Showing 1 changed file with 16 additions and 18 deletions.
34 changes: 16 additions & 18 deletions plugins/inputs/sysstat/sysstat.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"io"
"os"
"os/exec"
"path"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -66,7 +65,6 @@ type Sysstat struct {

// DeviceTags adds the possibility to add additional tags for devices.
DeviceTags map[string][]map[string]string `toml:"device_tags"`
tmpFile string
interval int

Log telegraf.Logger
Expand Down Expand Up @@ -149,24 +147,27 @@ func (s *Sysstat) Gather(acc telegraf.Accumulator) error {
s.interval = int(time.Since(firstTimestamp).Seconds() + 0.5)
}
}

tmpfile, err := os.CreateTemp("", "sysstat-*")
if err != nil {
return fmt.Errorf("failed to create tmp file: %s", err)
}
defer os.Remove(tmpfile.Name())

ts := time.Now().Add(time.Duration(s.interval) * time.Second)
if err := s.collect(); err != nil {
if err := s.collect(tmpfile.Name()); err != nil {
return err
}
var wg sync.WaitGroup
for option := range s.Options {
wg.Add(1)
go func(acc telegraf.Accumulator, option string) {
defer wg.Done()
acc.AddError(s.parse(acc, option, ts))
acc.AddError(s.parse(acc, option, tmpfile.Name(), ts))
}(acc, option)
}
wg.Wait()

if _, err := os.Stat(s.tmpFile); err == nil {
acc.AddError(os.Remove(s.tmpFile))
}

return nil
}

Expand All @@ -175,12 +176,12 @@ func (s *Sysstat) Gather(acc telegraf.Accumulator) error {
// 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 {
func (s *Sysstat) collect(tempfile string) 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

Expand All @@ -189,13 +190,10 @@ func (s *Sysstat) collect() error {
collectInterval = 1 // In that case we only collect for 1 second.
}

options = append(options, strconv.Itoa(collectInterval), "2", s.tmpFile)
options = append(options, strconv.Itoa(collectInterval), "2", tempfile)
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 {
s.Log.Errorf("Failed to remove tmp file after %q command: %s", strings.Join(cmd.Args, " "), err.Error())
}
return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out))
}
return nil
Expand Down Expand Up @@ -229,8 +227,8 @@ func withCLocale(cmd *exec.Cmd) *exec.Cmd {
// parse runs Sadf on the previously saved tmpFile:
// Sadf -p -- -p <option> tmpFile
// and parses the output to add it to the telegraf.Accumulator acc.
func (s *Sysstat) parse(acc telegraf.Accumulator, option string, ts time.Time) error {
cmd := execCommand(s.Sadf, s.sadfOptions(option)...)
func (s *Sysstat) parse(acc telegraf.Accumulator, option string, tmpfile string, ts time.Time) error {
cmd := execCommand(s.Sadf, s.sadfOptions(option, tmpfile)...)
cmd = withCLocale(cmd)
stdout, err := cmd.StdoutPipe()
if err != nil {
Expand Down Expand Up @@ -314,7 +312,7 @@ func (s *Sysstat) parse(acc telegraf.Accumulator, option string, ts time.Time) e
}

// sadfOptions creates the correct options for the sadf utility.
func (s *Sysstat) sadfOptions(activityOption string) []string {
func (s *Sysstat) sadfOptions(activityOption string, tmpfile string) []string {
options := []string{
"-p",
"--",
Expand All @@ -323,7 +321,7 @@ func (s *Sysstat) sadfOptions(activityOption string) []string {

opts := strings.Split(activityOption, " ")
options = append(options, opts...)
options = append(options, s.tmpFile)
options = append(options, tmpfile)

return options
}
Expand Down

0 comments on commit 7053fec

Please sign in to comment.