diff --git a/collector/collector.go b/collector/collector.go index 3142056..6517b37 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -175,6 +175,13 @@ func WithIpsec() Option { } } +// WithInternet enables internet access metrics +func WithInternet() Option { + return func(c *collector) { + c.collectors = append(c.collectors, newInternetCollector()) + } +} + // Option applies options to collector type Option func(*collector) diff --git a/collector/internet_collector.go b/collector/internet_collector.go new file mode 100644 index 0000000..2fee5f3 --- /dev/null +++ b/collector/internet_collector.go @@ -0,0 +1,81 @@ +package collector + +import ( + "strings" + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" +) + +type internetCollector struct { + props []string + descriptions map[string]*prometheus.Desc +} + +func newInternetCollector() routerOSCollector { + c := &internetCollector{} + c.init() + return c +} + +func (c *internetCollector) init() { + // Properties other than 'name' that will be used in .proplist + c.props = []string{"state"} + // Description for the returned values in the metric + labelNames := []string{"devicename", "interface"} + c.descriptions = make(map[string]*prometheus.Desc) + for _, p := range c.props { + c.descriptions[p] = descriptionForPropertyName("internet", p, labelNames) + } +} + +func (c *internetCollector) describe(ch chan<- *prometheus.Desc) { + for _, d := range c.descriptions { + ch <- d + } +} + +func (c *internetCollector) collect(ctx *collectorContext) error { + reply, err := ctx.client.Run("/interface/detect-internet/state/print", "=.proplist=name,"+strings.Join(c.props, ",")) + if err != nil { + log.WithFields(log.Fields{ + "device": ctx.device.Name, + "error": err, + }).Error("error fetching detect-internet state") + return err + } + + for _, e := range reply.Re { + for _, prop := range c.props { + v, ok := e.Map[prop] + if !ok { + continue + } + + value := float64(c.valueForProp(prop, v)) + ctx.ch <- prometheus.MustNewConstMetric(c.descriptions[prop], prometheus.GaugeValue, value, ctx.device.Name, e.Map["name"]) + } + } + + return nil +} + +// Here are the corresponding values for detect-internet's output: +// - internet: 2 +// - wan: 1 +// - lan: 0 +func (c *internetCollector) valueForProp(name, value string) int { + switch { + case name == "state": + return func(v string) int { + if v == "internet" { + return 2 + } + if v == "wan" { + return 1 + } + return 0 + }(value) + default: + return 0 + } +} diff --git a/config/config.go b/config/config.go index ee6e99f..72a1a02 100644 --- a/config/config.go +++ b/config/config.go @@ -27,6 +27,7 @@ type Config struct { WlanIF bool `yaml:"wlanif,omitempty"` Monitor bool `yaml:"monitor,omitempty"` Ipsec bool `yaml:"ipsec,omitempty"` + Internet bool `yaml:"internet,omitempty"` } `yaml:"features,omitempty"` } diff --git a/main.go b/main.go index 88e2a3b..67ce1f8 100644 --- a/main.go +++ b/main.go @@ -51,8 +51,8 @@ var ( withWlanIF = flag.Bool("with-wlanif", false, "retrieves wlan interface metrics") withMonitor = flag.Bool("with-monitor", false, "retrieves ethernet interface monitor info") withIpsec = flag.Bool("with-ipsec", false, "retrieves ipsec metrics") - - cfg *config.Config + withInternet = flag.Bool("with-internet", false, "retrieves detect-internet interfaces") + cfg *config.Config appVersion = "DEVELOPMENT" shortSha = "0xDEADBEEF" @@ -241,12 +241,16 @@ func collectorOptions() []collector.Option { opts = append(opts, collector.WithIpsec()) } + if *withInternet || cfg.Features.Internet { + opts = append(opts, collector.WithInternet()) + } + if *timeout != collector.DefaultTimeout { opts = append(opts, collector.WithTimeout(*timeout)) } if *tls || cfg.Features.TLS { - fmt.Printf("TLS activated\n"); + fmt.Printf("TLS activated\n") opts = append(opts, collector.WithTLS(*insecure)) }