package ipmi_sensor import ( "strconv" "strings" "time" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" ) type Ipmi struct { Servers []string runner Runner } var sampleConfig = ` ## specify 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)"] ` 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" } func (m *Ipmi) Gather(acc telegraf.Accumulator) error { if m.runner == nil { m.runner = CommandRunner{} } for _, serv := range m.Servers { err := m.gatherServer(serv, acc) if err != nil { return err } } return nil } func (m *Ipmi) gatherServer(serv string, acc telegraf.Accumulator) error { conn := NewConnection(serv) res, err := m.runner.Run(conn, "sdr") if err != nil { return err } // each line will look something like // Planar VBAT | 3.05 Volts | ok lines := strings.Split(res, "\n") for i := 0; i < len(lines); i++ { vals := strings.Split(lines[i], "|") if len(vals) != 3 { continue } tags := map[string]string{ "server": conn.Hostname, "name": transform(vals[0]), } fields := make(map[string]interface{}) if strings.EqualFold("ok", trim(vals[2])) { fields["status"] = 1 } else { fields["status"] = 0 } val1 := trim(vals[1]) if strings.Index(val1, " ") > 0 { // split middle column into value and unit valunit := strings.SplitN(val1, " ", 2) fields["value"] = Atofloat(valunit[0]) if len(valunit) > 1 { tags["unit"] = transform(valunit[1]) } } else { fields["value"] = 0.0 } acc.AddFields("ipmi_sensor", fields, tags, time.Now()) } 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 { return 0.0 } else { return f } } func trim(s string) string { return strings.TrimSpace(s) } func transform(s string) string { s = trim(s) s = strings.ToLower(s) return strings.Replace(s, " ", "_", -1) } func init() { inputs.Add("ipmi_sensor", func() telegraf.Input { return &Ipmi{} }) }