11package collector
22
33import (
4+ "regexp"
45 "strconv"
56 "strings"
7+ "time"
68
79 "github.com/prometheus/client_golang/prometheus"
810 log "github.com/sirupsen/logrus"
911 "gopkg.in/routeros.v2/proto"
1012)
1113
14+ var uptimeRegex * regexp.Regexp
15+ var uptimeParts [5 ]time.Duration
16+
17+ func init () {
18+ uptimeRegex = regexp .MustCompile (`(?:(\d*)w)?(?:(\d*)d)?(?:(\d*)h)?(?:(\d*)m)?(?:(\d*)s)` )
19+ uptimeParts = [5 ]time.Duration {time .Hour * 168 , time .Hour * 24 , time .Hour , time .Minute , time .Second }
20+ }
21+
1222type resourceCollector struct {
1323 props []string
1424 descriptions map [string ]* prometheus.Desc
@@ -21,7 +31,7 @@ func newResourceCollector() routerOSCollector {
2131}
2232
2333func (c * resourceCollector ) init () {
24- c .props = []string {"free-memory" , "total-memory" , "cpu-load" , "free-hdd-space" , "total-hdd-space" }
34+ c .props = []string {"free-memory" , "total-memory" , "cpu-load" , "free-hdd-space" , "total-hdd-space" , "uptime" }
2535
2636 labelNames := []string {"name" , "address" }
2737 c .descriptions = make (map [string ]* prometheus.Desc )
@@ -69,7 +79,15 @@ func (c *resourceCollector) collectForStat(re *proto.Sentence, ctx *collectorCon
6979}
7080
7181func (c * resourceCollector ) collectMetricForProperty (property string , re * proto.Sentence , ctx * collectorContext ) {
72- v , err := strconv .ParseFloat (re .Map [property ], 64 )
82+ var v float64
83+ var err error
84+
85+ if property == "uptime" {
86+ v , err = parseUptime (re .Map [property ])
87+ } else {
88+ v , err = strconv .ParseFloat (re .Map [property ], 64 )
89+ }
90+
7391 if err != nil {
7492 log .WithFields (log.Fields {
7593 "device" : ctx .device .Name ,
@@ -83,3 +101,24 @@ func (c *resourceCollector) collectMetricForProperty(property string, re *proto.
83101 desc := c .descriptions [property ]
84102 ctx .ch <- prometheus .MustNewConstMetric (desc , prometheus .CounterValue , v , ctx .device .Name , ctx .device .Address )
85103}
104+
105+ func parseUptime (uptime string ) (float64 , error ) {
106+ var u time.Duration
107+
108+ for i , match := range uptimeRegex .FindAllStringSubmatch (uptime , - 1 )[0 ] {
109+ if match != "" && i != 0 {
110+ v , err := strconv .Atoi (match )
111+ if err != nil {
112+ log .WithFields (log.Fields {
113+ "uptime" : uptime ,
114+ "value" : match ,
115+ "error" : err ,
116+ }).Error ("error parsing uptime field value" )
117+ return float64 (0 ), err
118+ }
119+ u += time .Duration (v ) * uptimeParts [i - 1 ]
120+ }
121+ }
122+
123+ return u .Seconds (), nil
124+ }
0 commit comments