From f1f09b42bb74fa0ee3863771f57e61c7454769be Mon Sep 17 00:00:00 2001 From: devi1 Date: Tue, 3 Sep 2019 00:50:20 +0600 Subject: [PATCH] DHCP Lease Collector (#50) * DHCP Leases Collector Add Information about DHCP Leases: * Active MAC Address * Active Address * Hostname * Status * Expire time * Modified resource collector Add Boardname and RouterOS version metrics --- README.md | 1 + collector/collector.go | 7 ++++ collector/dhcp_lease_collector.go | 69 +++++++++++++++++++++++++++++++ collector/resource_collector.go | 15 ++++--- config/{test => }/config.test.yml | 5 +-- 5 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 collector/dhcp_lease_collector.go rename config/{test => }/config.test.yml (90%) diff --git a/README.md b/README.md index 02056e2..0e7528c 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ features: bgp: true dhcp: true dhcpv6: true + dhcpl: true routes: true pools: true optics: true diff --git a/collector/collector.go b/collector/collector.go index 0f3c096..4ee01b9 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -70,6 +70,13 @@ func WithDHCP() Option { } } +// WithDHCPL enables DHCP server leases +func WithDHCPL() Option { + return func(c *collector) { + c.collectors = append(c.collectors, newDHCPLCollector()) + } +} + // WithDHCPv6 enables DHCPv6 serrver metrics func WithDHCPv6() Option { return func(c *collector) { diff --git a/collector/dhcp_lease_collector.go b/collector/dhcp_lease_collector.go new file mode 100644 index 0000000..1a671ae --- /dev/null +++ b/collector/dhcp_lease_collector.go @@ -0,0 +1,69 @@ +package collector + +import ( + "strings" + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" + "gopkg.in/routeros.v2/proto" +) + +type dhcpLeaseCollector struct { + props []string + descriptions *prometheus.Desc +} + +func (c *dhcpLeaseCollector) init() { + c.props = []string{"active-mac-address", "status", "expires-after", "active-address", "host-name"} + + labelNames := []string{"name", "address", "activemacaddress", "status", "expiresafter", "activeaddress", "hostname"} + c.descriptions = description("dhcp", "leases_metrics", "number of metrics", labelNames) + +} + +func newDHCPLCollector() routerOSCollector { + c := &dhcpLeaseCollector{} + c.init() + return c +} + +func (c *dhcpLeaseCollector) describe(ch chan<- *prometheus.Desc) { + ch <- c.descriptions +} + +func (c *dhcpLeaseCollector) collect(ctx *collectorContext) error { + stats, err := c.fetch(ctx) + if err != nil { + return err + } + + for _, re := range stats { + c.collectMetric(ctx, re) + } + + return nil +} + +func (c *dhcpLeaseCollector) fetch(ctx *collectorContext) ([]*proto.Sentence, error) { + reply, err := ctx.client.Run("/ip/dhcp-server/lease/print", "=.proplist="+strings.Join(c.props, ",")) + if err != nil { + log.WithFields(log.Fields{ + "device": ctx.device.Name, + "error": err, + }).Error("error fetching DHCP leases metrics") + return nil, err + } + + return reply.Re, nil +} + +func (c *dhcpLeaseCollector) collectMetric(ctx *collectorContext, re *proto.Sentence) { + v := 1.0 + + activemacaddress := re.Map["active-mac-address"] + status := re.Map["status"] + expiresafter := re.Map["expires-after"] + activeaddress := re.Map["active-address"] + hostname := re.Map["host-name"] + + ctx.ch <- prometheus.MustNewConstMetric(c.descriptions, prometheus.CounterValue, v, ctx.device.Name, ctx.device.Address, activemacaddress, status, expiresafter, activeaddress, hostname) +} diff --git a/collector/resource_collector.go b/collector/resource_collector.go index 59f1e88..427a7cf 100644 --- a/collector/resource_collector.go +++ b/collector/resource_collector.go @@ -32,9 +32,9 @@ func newResourceCollector() routerOSCollector { } func (c *resourceCollector) init() { - c.props = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space", "uptime"} + c.props = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space", "uptime", "board-name", "version"} - labelNames := []string{"name", "address"} + labelNames := []string{"name", "address", "boardname", "version"} c.descriptions = make(map[string]*prometheus.Desc) for _, p := range c.props { c.descriptions[p] = descriptionForPropertyName("system", p, labelNames) @@ -54,7 +54,7 @@ func (c *resourceCollector) collect(ctx *collectorContext) error { } for _, re := range stats { - c.collectForStat(re, ctx) + c.collectForStat(re, ctx) } return nil @@ -74,7 +74,7 @@ func (c *resourceCollector) fetch(ctx *collectorContext) ([]*proto.Sentence, err } func (c *resourceCollector) collectForStat(re *proto.Sentence, ctx *collectorContext) { - for _, p := range c.props { + for _, p := range c.props[:6] { c.collectMetricForProperty(p, re, ctx) } } @@ -82,6 +82,11 @@ func (c *resourceCollector) collectForStat(re *proto.Sentence, ctx *collectorCon func (c *resourceCollector) collectMetricForProperty(property string, re *proto.Sentence, ctx *collectorContext) { var v float64 var err error +// const boardname = "BOARD" +// const version = "3.33.3" + + boardname := re.Map["board-name"] + version := re.Map["version"] if property == "uptime" { v, err = parseUptime(re.Map[property]) @@ -100,7 +105,7 @@ 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) + ctx.ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, ctx.device.Name, ctx.device.Address, boardname, version) } func parseUptime(uptime string) (float64, error) { diff --git a/config/test/config.test.yml b/config/config.test.yml similarity index 90% rename from config/test/config.test.yml rename to config/config.test.yml index ee2ba66..30016cf 100644 --- a/config/test/config.test.yml +++ b/config/config.test.yml @@ -1,5 +1,3 @@ ---- - devices: - name: test1 address: 192.168.1.1 @@ -14,8 +12,9 @@ features: bgp: true dhcp: true dhcpv6: true + dhcpl: true routes: true pools: true optics: true wlansta: true - wlanif: true + wlanif: true \ No newline at end of file