2020-02-10 19:55:10 +01:00
package collector
import (
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"gopkg.in/routeros.v2/proto"
2022-06-03 23:32:20 +02:00
"strconv"
2020-02-10 19:55:10 +01:00
)
type healthCollector struct {
props [ ] string
descriptions map [ string ] * prometheus . Desc
}
func newhealthCollector ( ) routerOSCollector {
c := & healthCollector { }
c . init ( )
return c
}
func ( c * healthCollector ) init ( ) {
2020-08-10 11:31:57 +02:00
c . props = [ ] string { "voltage" , "temperature" , "cpu-temperature" }
2020-02-10 19:55:10 +01:00
labelNames := [ ] string { "name" , "address" }
2020-08-10 11:31:57 +02:00
helpText := [ ] string { "Input voltage to the RouterOS board, in volts" , "Temperature of RouterOS board, in degrees Celsius" , "Temperature of RouterOS CPU, in degrees Celsius" }
2020-02-10 19:55:10 +01:00
c . descriptions = make ( map [ string ] * prometheus . Desc )
for i , p := range c . props {
c . descriptions [ p ] = descriptionForPropertyNameHelpText ( "health" , p , labelNames , helpText [ i ] )
}
}
func ( c * healthCollector ) describe ( ch chan <- * prometheus . Desc ) {
for _ , d := range c . descriptions {
ch <- d
}
}
func ( c * healthCollector ) collect ( ctx * collectorContext ) error {
stats , err := c . fetch ( ctx )
if err != nil {
return err
}
for _ , re := range stats {
2022-06-04 15:10:17 +02:00
if metric , ok := re . Map [ "name" ] ; ok {
c . collectMetricForProperty ( metric , re , ctx )
} else {
c . collectForStat ( re , ctx )
}
2020-02-10 19:55:10 +01:00
}
return nil
}
func ( c * healthCollector ) fetch ( ctx * collectorContext ) ( [ ] * proto . Sentence , error ) {
2022-06-03 23:32:20 +02:00
reply , err := ctx . client . Run ( "/system/health/print" )
2020-02-10 19:55:10 +01:00
if err != nil {
log . WithFields ( log . Fields {
"device" : ctx . device . Name ,
"error" : err ,
} ) . Error ( "error fetching system health metrics" )
return nil , err
}
return reply . Re , nil
}
func ( c * healthCollector ) collectForStat ( re * proto . Sentence , ctx * collectorContext ) {
2022-06-04 15:10:17 +02:00
for _ , p := range c . props [ : 3 ] {
c . collectMetricForProperty ( p , re , ctx )
}
}
func ( c * healthCollector ) collectMetricForProperty ( property string , re * proto . Sentence , ctx * collectorContext ) {
2020-02-10 19:55:10 +01:00
var v float64
var err error
2022-06-04 15:10:17 +02:00
name := property
value := re . Map [ property ]
if value == "" {
var ok bool
if value , ok = re . Map [ "value" ] ; ! ok {
return
}
2020-02-10 19:55:10 +01:00
}
2022-06-04 15:10:17 +02:00
v , err = strconv . ParseFloat ( value , 64 )
2020-02-10 19:55:10 +01:00
if err != nil {
log . WithFields ( log . Fields {
"device" : ctx . device . Name ,
2022-06-04 15:10:17 +02:00
"property" : name ,
"value" : value ,
2020-02-10 19:55:10 +01:00
"error" : err ,
} ) . Error ( "error parsing system health metric value" )
return
}
2022-06-04 15:10:17 +02:00
desc := c . descriptions [ name ]
2020-02-10 19:55:10 +01:00
ctx . ch <- prometheus . MustNewConstMetric ( desc , prometheus . GaugeValue , v , ctx . device . Name , ctx . device . Address )
}