Private GIT

Skip to content
Snippets Groups Projects
Commit 5698d182 authored by Richard Mitchell's avatar Richard Mitchell
Browse files

Add bridge restart metric

parent 424bd30a
Branches
Tags
No related merge requests found
...@@ -53,6 +53,11 @@ Some sensor type values you might find useful: ...@@ -53,6 +53,11 @@ Some sensor type values you might find useful:
* `ZLLPresence`: the presence sensor in the Hue motion sensor * `ZLLPresence`: the presence sensor in the Hue motion sensor
* `ZLLLightLevel`: the light level sensor in the Hue motion sensor * `ZLLLightLevel`: the light level sensor in the Hue motion sensor
## General metrics
* `hue_group_scrapes_failed`, `hue_light_scrapes_failed`, `hue_sensor_scrapes_failed`: count of failures when trying to scrape from the Hue API.
* `hue_bridge_restarts`: count of times the bridge has restarted (*estimated based on sensor data*).
## Metric structure ## Metric structure
> Hey, why didn't you combine the metrics for brightness and hue and saturation and on and reachable? > Hey, why didn't you combine the metrics for brightness and hue and saturation and on and reachable?
......
package main package main
import ( import (
"math"
hue "github.com/collinux/gohue" hue "github.com/collinux/gohue"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
log "github.com/prometheus/common/log" log "github.com/prometheus/common/log"
...@@ -16,6 +18,7 @@ type sensorCollector struct { ...@@ -16,6 +18,7 @@ type sensorCollector struct {
sensorBattery *prometheus.GaugeVec sensorBattery *prometheus.GaugeVec
sensorReachable *prometheus.GaugeVec sensorReachable *prometheus.GaugeVec
sensorScrapesFailed prometheus.Counter sensorScrapesFailed prometheus.Counter
bridgeRestarts prometheus.Counter
} }
var variableSensorLabelNames = []string{ var variableSensorLabelNames = []string{
...@@ -37,6 +40,13 @@ func contains(a []string, x string) bool { ...@@ -37,6 +40,13 @@ func contains(a []string, x string) bool {
return false return false
} }
func max(a, b int64) int64 {
if a > b {
return a
}
return b
}
// NewSensorCollector Create a new Hue collector for sensors // NewSensorCollector Create a new Hue collector for sensors
func NewSensorCollector(namespace string, bridge Bridge, ignoreTypes []string, matchNames bool) prometheus.Collector { func NewSensorCollector(namespace string, bridge Bridge, ignoreTypes []string, matchNames bool) prometheus.Collector {
c := sensorCollector{ c := sensorCollector{
...@@ -96,6 +106,14 @@ func NewSensorCollector(namespace string, bridge Bridge, ignoreTypes []string, m ...@@ -96,6 +106,14 @@ func NewSensorCollector(namespace string, bridge Bridge, ignoreTypes []string, m
Help: "Count of scrapes of sensor data from the Hue bridge that have failed", Help: "Count of scrapes of sensor data from the Hue bridge that have failed",
}, },
), ),
bridgeRestarts: prometheus.NewCounter(
prometheus.CounterOpts{
Namespace: namespace,
Subsystem: "bridge",
Name: "restarts",
Help: "Count of number of bridge restarts detected",
},
),
} }
return c return c
...@@ -108,6 +126,7 @@ func (c sensorCollector) Describe(ch chan<- *prometheus.Desc) { ...@@ -108,6 +126,7 @@ func (c sensorCollector) Describe(ch chan<- *prometheus.Desc) {
c.sensorOn.Describe(ch) c.sensorOn.Describe(ch)
c.sensorReachable.Describe(ch) c.sensorReachable.Describe(ch)
c.sensorScrapesFailed.Describe(ch) c.sensorScrapesFailed.Describe(ch)
c.bridgeRestarts.Describe(ch)
} }
func (c sensorCollector) recordSensor(sensor hue.Sensor, sensorName string, deviceID string, sensorValue float64) { func (c sensorCollector) recordSensor(sensor hue.Sensor, sensorName string, deviceID string, sensorValue float64) {
...@@ -149,6 +168,8 @@ func (c sensorCollector) Collect(ch chan<- prometheus.Metric) { ...@@ -149,6 +168,8 @@ func (c sensorCollector) Collect(ch chan<- prometheus.Metric) {
c.sensorScrapesFailed.Inc() c.sensorScrapesFailed.Inc()
} }
sensorNames := make(map[string]string) sensorNames := make(map[string]string)
sensorLastUpdatedHistory := make(map[string]int64)
restartDetected := false
for _, sensor := range sensors { for _, sensor := range sensors {
var sensorValue float64 var sensorValue float64
...@@ -179,7 +200,10 @@ func (c sensorCollector) Collect(ch chan<- prometheus.Metric) { ...@@ -179,7 +200,10 @@ func (c sensorCollector) Collect(ch chan<- prometheus.Metric) {
} else { } else {
continue continue
} }
if sensorLastUpdatedHistory[sensor.UniqueID] > math.MinInt64 && sensor.State.LastUpdated.Unix() == math.MinInt64 {
restartDetected = true
}
sensorLastUpdatedHistory[sensor.UniqueID] = sensor.State.LastUpdated.Unix()
c.recordSensor(sensor, sensor.Name, deviceID, sensorValue) c.recordSensor(sensor, sensor.Name, deviceID, sensorValue)
} }
// kinda inefficient looping over them twice, but simplies code when name matching is enabled // kinda inefficient looping over them twice, but simplies code when name matching is enabled
...@@ -201,13 +225,22 @@ func (c sensorCollector) Collect(ch chan<- prometheus.Metric) { ...@@ -201,13 +225,22 @@ func (c sensorCollector) Collect(ch chan<- prometheus.Metric) {
sensorName = sensor.Name sensorName = sensor.Name
} }
} }
if sensorLastUpdatedHistory[sensor.UniqueID] > math.MinInt64 && sensor.State.LastUpdated.Unix() == math.MinInt64 {
restartDetected = true
}
sensorLastUpdatedHistory[sensor.UniqueID] = sensor.State.LastUpdated.Unix()
c.recordSensor(sensor, sensorName, deviceID, sensorValue) c.recordSensor(sensor, sensorName, deviceID, sensorValue)
} }
if restartDetected {
c.bridgeRestarts.Inc()
}
c.sensorValue.Collect(ch) c.sensorValue.Collect(ch)
c.sensorBattery.Collect(ch) c.sensorBattery.Collect(ch)
c.sensorLastUpdated.Collect(ch) c.sensorLastUpdated.Collect(ch)
c.sensorOn.Collect(ch) c.sensorOn.Collect(ch)
c.sensorReachable.Collect(ch) c.sensorReachable.Collect(ch)
c.sensorScrapesFailed.Collect(ch) c.sensorScrapesFailed.Collect(ch)
c.bridgeRestarts.Collect(ch)
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment