From 65a12e965333664c7ae70c2759dfd29bebbf1d3e Mon Sep 17 00:00:00 2001 From: "A. Binzxxxxxx" Date: Fri, 22 Jan 2021 00:14:21 +0100 Subject: [PATCH] Add setting to enable caching in ipmitool (#8335) --- plugins/inputs/ipmi_sensor/README.md | 9 +++++++ plugins/inputs/ipmi_sensor/ipmi.go | 38 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/plugins/inputs/ipmi_sensor/README.md b/plugins/inputs/ipmi_sensor/README.md index f620b93cb659e..609409985cb35 100644 --- a/plugins/inputs/ipmi_sensor/README.md +++ b/plugins/inputs/ipmi_sensor/README.md @@ -61,6 +61,15 @@ Any of the following parameters will be added to the aformentioned query if they ## Optionally provide the hex key for the IMPI connection. # hex_key = "" + + ## If ipmitool should use a cache + ## for me ipmitool runs about 2 to 10 times faster with cache enabled on HP G10 servers (when using ubuntu20.04) + ## the cache file may not work well for you if some sensors come up late + # use_cache = false + + ## Path to the ipmitools cache file (defaults to OS temp dir) + ## The provided path must exist and must be writable + # cache_path = "" ``` ### Measurements diff --git a/plugins/inputs/ipmi_sensor/ipmi.go b/plugins/inputs/ipmi_sensor/ipmi.go index 5572a195b2c29..eb344f539e695 100644 --- a/plugins/inputs/ipmi_sensor/ipmi.go +++ b/plugins/inputs/ipmi_sensor/ipmi.go @@ -5,7 +5,9 @@ import ( "bytes" "fmt" "log" + "os" "os/exec" + "path/filepath" "regexp" "strconv" "strings" @@ -34,6 +36,8 @@ type Ipmi struct { Timeout internal.Duration MetricVersion int UseSudo bool + UseCache bool + CachePath string } var sampleConfig = ` @@ -69,6 +73,15 @@ var sampleConfig = ` ## Optionally provide the hex key for the IMPI connection. # hex_key = "" + + ## If ipmitool should use a cache + ## for me ipmitool runs about 2 to 10 times faster with cache enabled on HP G10 servers (when using ubuntu20.04) + ## the cache file may not work well for you if some sensors come up late + # use_cache = false + + ## Path to the ipmitools cache file (defaults to OS temp dir) + ## The provided path must exist and must be writable + # cache_path = "" ` // SampleConfig returns the documentation about the sample configuration @@ -119,6 +132,29 @@ func (m *Ipmi) parse(acc telegraf.Accumulator, server string) error { opts = conn.options() } opts = append(opts, "sdr") + if m.UseCache { + cacheFile := filepath.Join(m.CachePath, server+"_ipmi_cache") + _, err := os.Stat(cacheFile) + if os.IsNotExist(err) { + dumpOpts := opts + // init cache file + dumpOpts = append(dumpOpts, "dump") + dumpOpts = append(dumpOpts, cacheFile) + name := m.Path + if m.UseSudo { + // -n - avoid prompting the user for input of any kind + dumpOpts = append([]string{"-n", name}, dumpOpts...) + name = "sudo" + } + cmd := execCommand(name, dumpOpts...) + out, err := internal.CombinedOutputTimeout(cmd, m.Timeout.Duration) + if err != nil { + return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out)) + } + } + opts = append(opts, "-S") + opts = append(opts, cacheFile) + } if m.MetricVersion == 2 { opts = append(opts, "elist") } @@ -294,6 +330,8 @@ func init() { m.Path = path } m.Timeout = internal.Duration{Duration: time.Second * 20} + m.UseCache = false + m.CachePath = os.TempDir() inputs.Add("ipmi_sensor", func() telegraf.Input { m := m return &m