Skip to content

Commit

Permalink
currentcollector: add new CurrentCollector type
Browse files Browse the repository at this point in the history
  • Loading branch information
mdlayher committed Oct 14, 2016
1 parent 399ff00 commit fcf496f
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 0 deletions.
91 changes: 91 additions & 0 deletions currentcollector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package lmsensorsexporter

import (
"github.com/mdlayher/lmsensors"
"github.com/prometheus/client_golang/prometheus"
)

// A CurrentCollector is a Prometheus collector for lmsensors current
// sensor metrics.
type CurrentCollector struct {
Amperes *prometheus.Desc
Alarm *prometheus.Desc

devices []*lmsensors.Device
}

var _ prometheus.Collector = &CurrentCollector{}

// NewCurrentCollector creates a new CurrentCollector.
func NewCurrentCollector(devices []*lmsensors.Device) *CurrentCollector {
const (
subsystem = "current"
)

var (
labels = []string{"device", "sensor", "details"}
)

return &CurrentCollector{
devices: devices,

Amperes: prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "amperes"),
"Current current detected by sensor in Amperes.",
labels,
nil,
),

Alarm: prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "alarm"),
"Whether or not a current sensor has triggered an alarm (1 - true, 0 - false).",
labels,
nil,
),
}
}

// Describe sends the descriptors of each metric over to the provided channel.
func (c *CurrentCollector) Describe(ch chan<- *prometheus.Desc) {
ds := []*prometheus.Desc{
c.Amperes,
c.Alarm,
}

for _, d := range ds {
ch <- d
}
}

// Collect sends the metric values for each metric created by the CurrentCollector
// to the provided prometheus Metric channel.
func (c *CurrentCollector) Collect(ch chan<- prometheus.Metric) {
for _, d := range c.devices {
for _, s := range d.Sensors {
cs, ok := s.(*lmsensors.CurrentSensor)
if !ok {
continue
}

labels := []string{
d.Name,
cs.Name,
cs.Label,
}

ch <- prometheus.MustNewConstMetric(
c.Amperes,
prometheus.GaugeValue,
cs.Input,
labels...,
)

ch <- prometheus.MustNewConstMetric(
c.Alarm,
prometheus.GaugeValue,
boolFloat64(cs.Alarm),
labels...,
)
}
}
}
112 changes: 112 additions & 0 deletions currentcollector_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package lmsensorsexporter

import (
"strings"
"testing"

"github.com/mdlayher/lmsensors"
)

func TestCurrentCollector(t *testing.T) {
tests := []struct {
name string
devices []*lmsensors.Device
match []string
noMatch []string
}{
{
name: "no devices",
match: []string{
`go_goroutines`,
},
noMatch: []string{
`lmsensors_current_alarm`,
`lmsensors_current_amperes`,
},
},
{
name: "one device, one sensor",
devices: []*lmsensors.Device{{
Name: "sfc-00",
Sensors: []lmsensors.Sensor{
&lmsensors.CurrentSensor{
Name: "curr1",
Label: "0.9V supply current",
Input: 7.613,
},
},
}},
match: []string{
`lmsensors_current_alarm{details="0.9V supply current",device="sfc-00",sensor="curr1"} 0`,
`lmsensors_current_amperes{details="0.9V supply current",device="sfc-00",sensor="curr1"} 7.613`,
},
},
{
name: "two devices, multiple sensors",
devices: []*lmsensors.Device{
{
Name: "sfc-00",
Sensors: []lmsensors.Sensor{
&lmsensors.CurrentSensor{
Name: "curr1",
Label: "0.9V supply current",
Input: 7.613,
},
&lmsensors.CurrentSensor{
Name: "curr2",
Label: "",
Input: 16.123,
Alarm: true,
},
},
},
{
Name: "sfc-01",
Sensors: []lmsensors.Sensor{
&lmsensors.FanSensor{
Name: "fan1",
Input: 1010,
},
&lmsensors.CurrentSensor{
Name: "curr1",
Input: 3.10,
},
},
},
},
match: []string{
`lmsensors_current_alarm{details="0.9V supply current",device="sfc-00",sensor="curr1"} 0`,
`lmsensors_current_alarm{details="",device="sfc-00",sensor="curr2"} 1`,
`lmsensors_current_alarm{details="",device="sfc-01",sensor="curr1"} 0`,
`lmsensors_current_amperes{details="0.9V supply current",device="sfc-00",sensor="curr1"} 7.613`,
`lmsensors_current_amperes{details="",device="sfc-00",sensor="curr2"} 16.123`,
`lmsensors_current_amperes{details="",device="sfc-01",sensor="curr1"} 3.1`,
},
noMatch: []string{
`lmsensors_fan_rpm`,
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := testCollector(t, NewCurrentCollector(tt.devices))

for _, m := range tt.match {
t.Run("match/"+m, func(t *testing.T) {
if !strings.Contains(got, m) {
t.Fatal("output did not contain expected metric")
}
})
}

for _, m := range tt.noMatch {
t.Run("nomatch/"+m, func(t *testing.T) {
if strings.Contains(got, m) {
t.Fatal("output contains unexpected metric")
}
})
}
})
}
}
1 change: 1 addition & 0 deletions lmsensorsexporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func (e *Exporter) withCollectors(fn func(cs []prometheus.Collector)) {
}

cs := []prometheus.Collector{
NewCurrentCollector(devices),
NewFanCollector(devices),
NewIntrusionCollector(devices),
NewTemperatureCollector(devices),
Expand Down

0 comments on commit fcf496f

Please sign in to comment.