diff --git a/plugins/inputs/ipmi/README.md b/plugins/inputs/ipmi/README.md index ca42f7d10207f..16968777b5f02 100644 --- a/plugins/inputs/ipmi/README.md +++ b/plugins/inputs/ipmi/README.md @@ -12,11 +12,11 @@ ipmitool -I lan -H 192.168.1.1 -U USERID -P PASSW0RD sdr - ipmi_sensor: - * Tags: `server`,`host` + * Tags: `name`, `server`, `units` * Fields: - status - value - + ## Configuration ```toml @@ -31,20 +31,12 @@ ipmitool -I lan -H 192.168.1.1 -U USERID -P PASSW0RD sdr ## Output -> ipmi_sensor,host=10.20.2.203,inst=Ambient\ Temp status=1i,value=20 1458488465012559455 -> ipmi_sensor,host=10.20.2.203,inst=Altitude status=1i,value=80 1458488465012688613 -> ipmi_sensor,host=10.20.2.203,inst=Avg\ Power status=1i,value=220 1458488465012776511 -> ipmi_sensor,host=10.20.2.203,inst=Planar\ 3.3V status=1i,value=3.28 1458488465012861875 -> ipmi_sensor,host=10.20.2.203,inst=Planar\ 5V status=1i,value=4.9 1458488465012944188 -> ipmi_sensor,host=10.20.2.203,inst=Planar\ 12V status=1i,value=12.04 1458488465013008485 -> ipmi_sensor,host=10.20.2.203,inst=Planar\ VBAT status=1i,value=3.04 1458488465013072508 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 1A\ Tach status=1i,value=2610 1458488465013137932 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 1B\ Tach status=1i,value=1775 1458488465013279896 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 2A\ Tach status=1i,value=1972 1458488465013358177 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 2B\ Tach status=1i,value=1275 1458488465013434023 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 3A\ Tach status=1i,value=2929 1458488465013514567 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 3B\ Tach status=1i,value=2125 1458488465013582616 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 1 status=1i,value=0 1458488465013643746 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 2 status=1i,value=0 1458488465013714887 -> ipmi_sensor,host=10.20.2.203,inst=Fan\ 3 status=1i,value=0 1458488465013861854 - +``` +> ipmi_sensor,server=10.20.2.203,units=degrees_c,name=ambient_temp status=1i,value=20 1458488465012559455 +> ipmi_sensor,server=10.20.2.203,units=feet,name=altitude status=1i,value=80 1458488465012688613 +> ipmi_sensor,server=10.20.2.203,units=watts,name=avg_power status=1i,value=220 1458488465012776511 +> ipmi_sensor,server=10.20.2.203,units=volts,name=planar_3.3v status=1i,value=3.28 1458488465012861875 +> ipmi_sensor,server=10.20.2.203,units=volts,name=planar_vbat status=1i,value=3.04 1458488465013072508 +> ipmi_sensor,server=10.20.2.203,units=rpm,name=fan_1a_tach status=1i,value=2610 1458488465013137932 +> ipmi_sensor,server=10.20.2.203,units=rpm,name=fan_1b_tach status=1i,value=1775 1458488465013279896 +``` diff --git a/plugins/inputs/ipmi/ipmi.go b/plugins/inputs/ipmi/ipmi.go index 8a34c8d3f2f6b..7b2f4b63ea92a 100644 --- a/plugins/inputs/ipmi/ipmi.go +++ b/plugins/inputs/ipmi/ipmi.go @@ -15,6 +15,8 @@ type Ipmi struct { runner Runner } +var replacer = strings.NewReplacer(" ", "_") + var sampleConfig = ` ## specify servers via a url matching: ## [username[:password]@][protocol[(address)]] @@ -60,30 +62,41 @@ func (m *Ipmi) gatherServer(serv string, acc telegraf.Accumulator) error { 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 { - tags := map[string]string{"server": conn.Hostname, "name": trim(vals[0])} - fields := make(map[string]interface{}) - if strings.EqualFold("ok", trim(vals[2])) { - fields["status"] = 1 - } else { - fields["status"] = 0 - } + if len(vals) != 3 { + continue + } - val1 := trim(vals[1]) + tags := map[string]string{ + "server": conn.Hostname, + "name": transform(vals[0]), + } - if strings.Index(val1, " ") > 0 { - val := strings.Split(val1, " ")[0] - fields["value"] = Atofloat(val) - } else { - fields["value"] = 0.0 - } + fields := make(map[string]interface{}) + if strings.EqualFold("ok", trim(vals[2])) { + fields["status"] = 1 + } else { + fields["status"] = 0 + } + + val1 := trim(vals[1]) - acc.AddFields("ipmi_sensor", fields, tags, time.Now()) + 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["units"] = transform(valunit[1]) + } + } else { + fields["value"] = 0.0 } + + acc.AddFields("ipmi_sensor", fields, tags, time.Now()) } return nil @@ -96,9 +109,9 @@ type Runner interface { func Atofloat(val string) float64 { f, err := strconv.ParseFloat(val, 64) if err != nil { - return float64(0) + return 0.0 } else { - return float64(f) + return f } } @@ -106,6 +119,12 @@ func trim(s string) string { return strings.TrimSpace(s) } +func transform(s string) string { + s = trim(s) + s = strings.ToLower(s) + return replacer.Replace(s) +} + func init() { inputs.Add("ipmi", func() telegraf.Input { return &Ipmi{} diff --git a/plugins/inputs/ipmi/ipmi_test.go b/plugins/inputs/ipmi/ipmi_test.go index 1e0a57bd17949..8ae9c6724bab1 100644 --- a/plugins/inputs/ipmi/ipmi_test.go +++ b/plugins/inputs/ipmi/ipmi_test.go @@ -179,6 +179,93 @@ func TestIpmi(t *testing.T) { require.NoError(t, err) assert.Equal(t, acc.NFields(), 266, "non-numeric measurements should be ignored") + + var tests = []struct { + fields map[string]interface{} + tags map[string]string + }{ + { + map[string]interface{}{ + "value": float64(20), + "status": int(1), + }, + map[string]string{ + "name": "ambient_temp", + "server": "192.168.1.1", + "units": "degrees_c", + }, + }, + { + map[string]interface{}{ + "value": float64(80), + "status": int(1), + }, + map[string]string{ + "name": "altitude", + "server": "192.168.1.1", + "units": "feet", + }, + }, + { + map[string]interface{}{ + "value": float64(210), + "status": int(1), + }, + map[string]string{ + "name": "avg_power", + "server": "192.168.1.1", + "units": "watts", + }, + }, + { + map[string]interface{}{ + "value": float64(4.9), + "status": int(1), + }, + map[string]string{ + "name": "planar_5v", + "server": "192.168.1.1", + "units": "volts", + }, + }, + { + map[string]interface{}{ + "value": float64(3.05), + "status": int(1), + }, + map[string]string{ + "name": "planar_vbat", + "server": "192.168.1.1", + "units": "volts", + }, + }, + { + map[string]interface{}{ + "value": float64(2610), + "status": int(1), + }, + map[string]string{ + "name": "fan_1a_tach", + "server": "192.168.1.1", + "units": "rpm", + }, + }, + { + map[string]interface{}{ + "value": float64(1775), + "status": int(1), + }, + map[string]string{ + "name": "fan_1b_tach", + "server": "192.168.1.1", + "units": "rpm", + }, + }, + } + + for _, test := range tests { + acc.AssertContainsTaggedFields(t, "ipmi_sensor", test.fields, test.tags) + } } func TestIpmiConnection(t *testing.T) {