diff --git a/Gopkg.lock b/Gopkg.lock index cab2aee..3e3f739 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,98 +3,130 @@ [[projects]] branch = "master" + digest = "1:0c5485088ce274fac2e931c1b979f2619345097b39d91af3239977114adf0320" name = "github.com/beorn7/perks" packages = ["quantile"] + pruneopts = "" revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9" [[projects]] + digest = "1:bcb38c8fc9b21bb8682ce2d605a7d4aeb618abc7f827e3ac0b27c0371fdb23fb" name = "github.com/golang/protobuf" packages = ["proto"] + pruneopts = "" revision = "925541529c1fa6821df4e44ce2723319eb2be768" version = "v1.0.0" [[projects]] + digest = "1:4c23ced97a470b17d9ffd788310502a077b9c1f60221a85563e49696276b4147" name = "github.com/matttproud/golang_protobuf_extensions" packages = ["pbutil"] + pruneopts = "" revision = "3247c84500bff8d9fb6d579d800f20b3e091582c" version = "v1.0.0" [[projects]] + digest = "1:4142d94383572e74b42352273652c62afec5b23f325222ed09198f46009022d1" name = "github.com/prometheus/client_golang" packages = [ "prometheus", - "prometheus/promhttp" + "prometheus/promhttp", ] + pruneopts = "" revision = "c5b7fccd204277076155f10851dad72b76a49317" version = "v0.8.0" [[projects]] branch = "master" + digest = "1:60aca47f4eeeb972f1b9da7e7db51dee15ff6c59f7b401c1588b8e6771ba15ef" name = "github.com/prometheus/client_model" packages = ["go"] + pruneopts = "" revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" [[projects]] branch = "master" + digest = "1:545c0adfcd1c5a3d155cfada997c426d3e4b358ba26cf7a1ace99fd9230e63de" name = "github.com/prometheus/common" packages = [ "expfmt", "internal/bitbucket.org/ww/goautoneg", "model", - "version" + "version", ] + pruneopts = "" revision = "e4aa40a9169a88835b849a6efb71e05dc04b88f0" [[projects]] branch = "master" + digest = "1:9a89d28f6d0bacb0b31d66f85a51f2b4f52592807c3aed15a889e816143412ae" name = "github.com/prometheus/procfs" packages = [ ".", "internal/util", "nfs", - "xfs" + "xfs", ] + pruneopts = "" revision = "54d17b57dd7d4a3aa092476596b3f8a933bde349" [[projects]] + digest = "1:8cf46b6c18a91068d446e26b67512cf16f1540b45d90b28b9533706a127f0ca6" name = "github.com/sirupsen/logrus" packages = ["."] + pruneopts = "" revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc" version = "v1.0.5" [[projects]] branch = "master" + digest = "1:7ef4735e2c2cbc87694bc94485cd083de688f04ebcd8f956112bfa5d27385a2c" name = "golang.org/x/crypto" packages = ["ssh/terminal"] + pruneopts = "" revision = "c3a3ad6d03f7a915c0f7e194b7152974bb73d287" [[projects]] branch = "master" + digest = "1:b58b9b589abdd52776c26b01d3585d6a03f3b5f09e3efa4f4f842daebac7ee9b" name = "golang.org/x/sys" packages = [ "unix", - "windows" + "windows", ] + pruneopts = "" revision = "d8e400bc7db4870d786864138af681469693d18c" [[projects]] branch = "v2" + digest = "1:c5fc3d7afc6248e05aef3392af584dfcd2ce774c9e4bcc58e9c6e6329f85770f" name = "gopkg.in/routeros.v2" packages = [ ".", - "proto" + "proto", ] + pruneopts = "" revision = "2dc19c12445caefdc2d128f7331dcc83284211ef" [[projects]] + digest = "1:5fe876313b07628905b2181e537faabe45032cb9c79c01b49b51c25a0a40040d" name = "gopkg.in/yaml.v2" packages = ["."] + pruneopts = "" revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5" version = "v2.1.1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "ff563df52a1af77a9de6d6c3bd29b66cac02221b5d9357d63f32e8503399d301" + input-imports = [ + "github.com/prometheus/client_golang/prometheus", + "github.com/prometheus/client_golang/prometheus/promhttp", + "github.com/prometheus/common/version", + "github.com/sirupsen/logrus", + "gopkg.in/routeros.v2", + "gopkg.in/routeros.v2/proto", + "gopkg.in/yaml.v2", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/VERSION b/VERSION index 39e88d3..90a27f9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.4-DEVEL +1.0.5 diff --git a/collector/resource_collector.go b/collector/resource_collector.go index a90248a..e1db6f2 100644 --- a/collector/resource_collector.go +++ b/collector/resource_collector.go @@ -1,14 +1,24 @@ package collector import ( + "regexp" "strconv" "strings" + "time" "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" "gopkg.in/routeros.v2/proto" ) +var uptimeRegex *regexp.Regexp +var uptimeParts [5]time.Duration + +func init() { + uptimeRegex = regexp.MustCompile(`(?:(\d*)w)?(?:(\d*)d)?(?:(\d*)h)?(?:(\d*)m)?(?:(\d*)s)`) + uptimeParts = [5]time.Duration{time.Hour * 168, time.Hour * 24, time.Hour, time.Minute, time.Second} +} + type resourceCollector struct { props []string descriptions map[string]*prometheus.Desc @@ -21,7 +31,7 @@ func newResourceCollector() routerOSCollector { } func (c *resourceCollector) init() { - c.props = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space"} + c.props = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space", "uptime"} labelNames := []string{"name", "address"} c.descriptions = make(map[string]*prometheus.Desc) @@ -69,7 +79,15 @@ func (c *resourceCollector) collectForStat(re *proto.Sentence, ctx *collectorCon } func (c *resourceCollector) collectMetricForProperty(property string, re *proto.Sentence, ctx *collectorContext) { - v, err := strconv.ParseFloat(re.Map[property], 64) + var v float64 + var err error + + if property == "uptime" { + v, err = parseUptime(re.Map[property]) + } else { + v, err = strconv.ParseFloat(re.Map[property], 64) + } + if err != nil { log.WithFields(log.Fields{ "device": ctx.device.Name, @@ -83,3 +101,24 @@ func (c *resourceCollector) collectMetricForProperty(property string, re *proto. desc := c.descriptions[property] ctx.ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, ctx.device.Name, ctx.device.Address) } + +func parseUptime(uptime string) (float64, error) { + var u time.Duration + + for i, match := range uptimeRegex.FindAllStringSubmatch(uptime, -1)[0] { + if match != "" && i != 0 { + v, err := strconv.Atoi(match) + if err != nil { + log.WithFields(log.Fields{ + "uptime": uptime, + "value": match, + "error": err, + }).Error("error parsing uptime field value") + return float64(0), err + } + u += time.Duration(v) * uptimeParts[i-1] + } + } + + return u.Seconds(), nil +} diff --git a/collector/resource_collector_test.go b/collector/resource_collector_test.go new file mode 100644 index 0000000..d84fc48 --- /dev/null +++ b/collector/resource_collector_test.go @@ -0,0 +1,27 @@ +package collector + +import ( + "testing" +) + +func TestParseUptime(t *testing.T) { + + uptimes := []struct { + u string + v float64 + }{ + {"3d3h42m53s", 272573}, + {"15w3d3h42m53s", 9344573}, + {"42m53s", 2573}, + } + + for _, uptime := range uptimes { + seconds, err := parseUptime(uptime.u) + if err != nil { + t.Error(err) + } + if seconds != uptime.v { + t.Errorf("seconds : %f != v : %f\n", seconds, uptime.v) + } + } +} diff --git a/main.go b/main.go index 66124c7..9e60638 100644 --- a/main.go +++ b/main.go @@ -131,7 +131,7 @@ func startServer() { `)) }) - log.Info("Listening on", *port) + log.Info("Listening on ", *port) log.Fatal(http.ListenAndServe(*port, nil)) }