Skip to content

Commit

Permalink
remove cgo dependeny with forking sensors command
Browse files Browse the repository at this point in the history
  • Loading branch information
zbindenren authored and aurrelhebert committed Aug 9, 2016
1 parent 2429b90 commit 97de9ff
Show file tree
Hide file tree
Showing 7 changed files with 464 additions and 61 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ consistent with the behavior of `collection_jitter`.
- [#1296](https://github.com/influxdata/telegraf/issues/1296): Refactor of flush_jitter argument.
- [#1213](https://github.com/influxdata/telegraf/issues/1213): Add inactive & active memory to mem plugin.
- [#1543](https://github.com/influxdata/telegraf/pull/1543): Official Windows service.
- [#1414](https://github.com/influxdata/telegraf/pull/1414): Forking sensors command to remove C package dependency.

### Bugfixes

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Currently implemented sources:
* [redis](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/redis)
* [rethinkdb](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/rethinkdb)
* [riak](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/riak)
* [sensors ](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/sensors) (only available if built from source)
* [sensors](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/sensors)
* [snmp](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/snmp)
* [sql server](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/sqlserver) (microsoft)
* [twemproxy](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/twemproxy)
Expand Down
47 changes: 47 additions & 0 deletions plugins/inputs/sensors/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# sensors Input Plugin

Collect [lm-sensors](https://en.wikipedia.org/wiki/Lm_sensors) metrics - requires the lm-sensors
package installed.

This plugin collects sensor metrics with the `sensors` executable from the lm-sensor package.

### Configuration:
```
# Monitor sensors, requires lm-sensors package
[[inputs.sensors]]
## Remove numbers from field names.
## If true, a field name like 'temp1_input' will be changed to 'temp_input'.
# remove_numbers = true
```

### Measurements & Fields:
Fields are created dynamicaly depending on the sensors. All fields are float.

### Tags:

- All measurements have the following tags:
- chip
- feature

### Example Output:

#### Default
```
$ telegraf -config telegraf.conf -input-filter sensors -test
* Plugin: sensors, Collection 1
> sensors,chip=power_meter-acpi-0,feature=power1 power_average=0,power_average_interval=300 1466751326000000000
> sensors,chip=k10temp-pci-00c3,feature=temp1 temp_crit=70,temp_crit_hyst=65,temp_input=29,temp_max=70 1466751326000000000
> sensors,chip=k10temp-pci-00cb,feature=temp1 temp_input=29,temp_max=70 1466751326000000000
> sensors,chip=k10temp-pci-00d3,feature=temp1 temp_input=27.5,temp_max=70 1466751326000000000
> sensors,chip=k10temp-pci-00db,feature=temp1 temp_crit=70,temp_crit_hyst=65,temp_input=29.5,temp_max=70 1466751326000000000
```

#### With remove_numbers=false
```
* Plugin: sensors, Collection 1
> sensors,chip=power_meter-acpi-0,feature=power1 power1_average=0,power1_average_interval=300 1466753424000000000
> sensors,chip=k10temp-pci-00c3,feature=temp1 temp1_crit=70,temp1_crit_hyst=65,temp1_input=29.125,temp1_max=70 1466753424000000000
> sensors,chip=k10temp-pci-00cb,feature=temp1 temp1_input=29,temp1_max=70 1466753424000000000
> sensors,chip=k10temp-pci-00d3,feature=temp1 temp1_input=29.5,temp1_max=70 1466753424000000000
> sensors,chip=k10temp-pci-00db,feature=temp1 temp1_crit=70,temp1_crit_hyst=65,temp1_input=30,temp1_max=70 1466753424000000000
```
141 changes: 84 additions & 57 deletions plugins/inputs/sensors/sensors.go
Original file line number Diff line number Diff line change
@@ -1,91 +1,118 @@
// +build linux,sensors
// +build linux

package sensors

import (
"errors"
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"

"github.com/md14454/gosensors"
"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.
numberRegp = regexp.MustCompile("[0-9]+")
)

type Sensors struct {
Sensors []string
RemoveNumbers bool `toml:"remove_numbers"`
path string
}

func (_ *Sensors) Description() string {
return "Monitor sensors using lm-sensors package"
func (*Sensors) Description() string {
return "Monitor sensors, requires lm-sensors package"
}

var sensorsSampleConfig = `
## By default, telegraf gathers stats from all sensors detected by the
## lm-sensors module.
##
## Only collect stats from the selected sensors. Sensors are listed as
## <chip name>:<feature name>. This information can be found by running the
## sensors command, e.g. sensors -u
##
## A * as the feature name will return all features of the chip
##
# sensors = ["coretemp-isa-0000:Core 0", "coretemp-isa-0001:*"]
func (*Sensors) SampleConfig() string {
return `
## Remove numbers from field names.
## If true, a field name like 'temp1_input' will be changed to 'temp_input'.
# remove_numbers = true
`

func (_ *Sensors) SampleConfig() string {
return sensorsSampleConfig
}

func (s *Sensors) Gather(acc telegraf.Accumulator) error {
gosensors.Init()
defer gosensors.Cleanup()

for _, chip := range gosensors.GetDetectedChips() {
for _, feature := range chip.GetFeatures() {
chipName := chip.String()
featureLabel := feature.GetLabel()

if len(s.Sensors) != 0 {
var found bool

for _, sensor := range s.Sensors {
parts := strings.SplitN(sensor, ":", 2)
if len(s.path) == 0 {
return errors.New("sensors not found: verify that lm-sensors package is installed and that sensors is in your PATH")
}

if parts[0] == chipName {
if parts[1] == "*" || parts[1] == featureLabel {
found = true
break
}
}
}
return s.parse(acc)
}

if !found {
continue
}
// parse forks the command:
// sensors -u -A
// and parses the output to add it to the telegraf.Accumulator.
func (s *Sensors) parse(acc telegraf.Accumulator) error {
tags := map[string]string{}
fields := map[string]interface{}{}
chip := ""
cmd := execCommand(s.path, "-A", "-u")
out, err := internal.CombinedOutputTimeout(cmd, time.Second*5)
if err != nil {
return fmt.Errorf("failed to run command %s: %s - %s", strings.Join(cmd.Args, " "), err, string(out))
}
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
for _, line := range lines {
if len(line) == 0 {
acc.AddFields("sensors", fields, tags)
chip = ""
tags = map[string]string{}
fields = map[string]interface{}{}
continue
}
if len(chip) == 0 {
chip = line
tags["chip"] = chip
continue
}
if !strings.HasPrefix(line, " ") {
if len(tags) > 1 {
acc.AddFields("sensors", fields, tags)
}

tags := map[string]string{
"chip": chipName,
"adapter": chip.AdapterName(),
"feature-name": feature.Name,
"feature-label": featureLabel,
fields = map[string]interface{}{}
tags = map[string]string{
"chip": chip,
"feature": strings.TrimRight(snake(line), ":"),
}

fieldName := chipName + ":" + featureLabel

fields := map[string]interface{}{
fieldName: feature.GetValue(),
} else {
splitted := strings.Split(line, ":")
fieldName := strings.TrimSpace(splitted[0])
if s.RemoveNumbers {
fieldName = numberRegp.ReplaceAllString(fieldName, "")
}

acc.AddFields("sensors", fields, tags)
fieldValue, err := strconv.ParseFloat(strings.TrimSpace(splitted[1]), 64)
if err != nil {
return err
}
fields[fieldName] = fieldValue
}
}

acc.AddFields("sensors", fields, tags)
return nil
}

func init() {
s := Sensors{
RemoveNumbers: true,
}
path, _ := exec.LookPath("sensors")
if len(path) > 0 {
s.path = path
}
inputs.Add("sensors", func() telegraf.Input {
return &Sensors{}
return &s
})
}

// snake converts string to snake case
func snake(input string) string {
return strings.ToLower(strings.Replace(input, " ", "_", -1))
}
3 changes: 0 additions & 3 deletions plugins/inputs/sensors/sensors_nocompile.go

This file was deleted.

3 changes: 3 additions & 0 deletions plugins/inputs/sensors/sensors_notlinux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// +build !linux

package sensors
Loading

0 comments on commit 97de9ff

Please sign in to comment.