allow querying sensors via the open interface
closes #2244 closes #1547
This commit is contained in:
committed by
Cameron Sparr
parent
dfba3ff37a
commit
a610f8bd03
@@ -1,48 +1,62 @@
|
||||
package ipmi_sensor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
var (
|
||||
execCommand = exec.Command // execCommand is used to mock commands in tests.
|
||||
)
|
||||
|
||||
type Ipmi struct {
|
||||
path string
|
||||
Servers []string
|
||||
runner Runner
|
||||
}
|
||||
|
||||
var sampleConfig = `
|
||||
## specify servers via a url matching:
|
||||
## optionally specify the path to the ipmitool executable
|
||||
# path = "/usr/bin/ipmitool"
|
||||
#
|
||||
## optionally specify one or more servers via a url matching
|
||||
## [username[:password]@][protocol[(address)]]
|
||||
## e.g.
|
||||
## root:passwd@lan(127.0.0.1)
|
||||
##
|
||||
servers = ["USERID:PASSW0RD@lan(192.168.1.1)"]
|
||||
## if no servers are specified, local machine sensor stats will be queried
|
||||
##
|
||||
# servers = ["USERID:PASSW0RD@lan(192.168.1.1)"]
|
||||
`
|
||||
|
||||
func NewIpmi() *Ipmi {
|
||||
return &Ipmi{
|
||||
runner: CommandRunner{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Ipmi) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (m *Ipmi) Description() string {
|
||||
return "Read metrics from one or many bare metal servers"
|
||||
return "Read metrics from the bare metal servers via IPMI"
|
||||
}
|
||||
|
||||
func (m *Ipmi) Gather(acc telegraf.Accumulator) error {
|
||||
if m.runner == nil {
|
||||
m.runner = CommandRunner{}
|
||||
if len(m.path) == 0 {
|
||||
return fmt.Errorf("ipmitool not found: verify that ipmitool is installed and that ipmitool is in your PATH")
|
||||
}
|
||||
for _, serv := range m.Servers {
|
||||
err := m.gatherServer(serv, acc)
|
||||
|
||||
if len(m.Servers) > 0 {
|
||||
for _, server := range m.Servers {
|
||||
err := m.parse(acc, server)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := m.parse(acc, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -51,17 +65,26 @@ func (m *Ipmi) Gather(acc telegraf.Accumulator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Ipmi) gatherServer(serv string, acc telegraf.Accumulator) error {
|
||||
conn := NewConnection(serv)
|
||||
func (m *Ipmi) parse(acc telegraf.Accumulator, server string) error {
|
||||
opts := make([]string, 0)
|
||||
hostname := ""
|
||||
|
||||
res, err := m.runner.Run(conn, "sdr")
|
||||
if server != "" {
|
||||
conn := NewConnection(server)
|
||||
hostname = conn.Hostname
|
||||
opts = conn.options()
|
||||
}
|
||||
|
||||
opts = append(opts, "sdr")
|
||||
cmd := execCommand(m.path, opts...)
|
||||
out, err := internal.CombinedOutputTimeout(cmd, time.Second*5)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out))
|
||||
}
|
||||
|
||||
// each line will look something like
|
||||
// Planar VBAT | 3.05 Volts | ok
|
||||
lines := strings.Split(res, "\n")
|
||||
lines := strings.Split(string(out), "\n")
|
||||
for i := 0; i < len(lines); i++ {
|
||||
vals := strings.Split(lines[i], "|")
|
||||
if len(vals) != 3 {
|
||||
@@ -69,8 +92,12 @@ func (m *Ipmi) gatherServer(serv string, acc telegraf.Accumulator) error {
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"server": conn.Hostname,
|
||||
"name": transform(vals[0]),
|
||||
"name": transform(vals[0]),
|
||||
}
|
||||
|
||||
// tag the server is we have one
|
||||
if hostname != "" {
|
||||
tags["server"] = hostname
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
@@ -99,10 +126,6 @@ func (m *Ipmi) gatherServer(serv string, acc telegraf.Accumulator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Runner interface {
|
||||
Run(conn *Connection, args ...string) (string, error)
|
||||
}
|
||||
|
||||
func Atofloat(val string) float64 {
|
||||
f, err := strconv.ParseFloat(val, 64)
|
||||
if err != nil {
|
||||
@@ -123,7 +146,12 @@ func transform(s string) string {
|
||||
}
|
||||
|
||||
func init() {
|
||||
m := Ipmi{}
|
||||
path, _ := exec.LookPath("ipmitool")
|
||||
if len(path) > 0 {
|
||||
m.path = path
|
||||
}
|
||||
inputs.Add("ipmi_sensor", func() telegraf.Input {
|
||||
return &Ipmi{}
|
||||
return &m
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user