Merge pull request #75 from mmilata/conntrack-collector

Add connection tracking collector
This commit is contained in:
Steve Brunton 2021-03-22 22:33:30 -04:00 committed by GitHub
commit 0b8aa8515c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 113 additions and 30 deletions

View File

@ -175,6 +175,13 @@ func WithIpsec() Option {
}
}
// WithConntrack enables firewall/NAT connection tracking metrics
func WithConntrack() Option {
return func(c *collector) {
c.collectors = append(c.collectors, newConntrackCollector())
}
}
// Option applies options to collector
type Option func(*collector)

View File

@ -0,0 +1,68 @@
package collector
import (
"strconv"
"strings"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"gopkg.in/routeros.v2/proto"
)
type conntrackCollector struct {
props []string
totalEntriesDesc *prometheus.Desc
maxEntriesDesc *prometheus.Desc
}
func newConntrackCollector() routerOSCollector {
const prefix = "conntrack"
labelNames := []string{"name", "address"}
return &conntrackCollector{
props: []string{"total-entries", "max-entries"},
totalEntriesDesc: description(prefix, "entries", "Number of tracked connections", labelNames),
maxEntriesDesc: description(prefix, "max_entries", "Conntrack table capacity", labelNames),
}
}
func (c *conntrackCollector) describe(ch chan<- *prometheus.Desc) {
ch <- c.totalEntriesDesc
ch <- c.maxEntriesDesc
}
func (c *conntrackCollector) collect(ctx *collectorContext) error {
reply, err := ctx.client.Run("/ip/firewall/connection/tracking/print", "=.proplist="+strings.Join(c.props, ","))
if err != nil {
log.WithFields(log.Fields{
"device": ctx.device.Name,
"error": err,
}).Error("error fetching conntrack table metrics")
return err
}
for _, re := range reply.Re {
c.collectMetricForProperty("total-entries", c.totalEntriesDesc, re, ctx)
c.collectMetricForProperty("max-entries", c.maxEntriesDesc, re, ctx)
}
return nil
}
func (c *conntrackCollector) collectMetricForProperty(property string, desc *prometheus.Desc, re *proto.Sentence, ctx *collectorContext) {
if re.Map[property] == "" {
return
}
v, err := strconv.ParseFloat(re.Map[property], 64)
if err != nil {
log.WithFields(log.Fields{
"device": ctx.device.Name,
"property": property,
"value": re.Map[property],
"error": err,
}).Error("error parsing conntrack metric value")
return
}
ctx.ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, v, ctx.device.Name, ctx.device.Address)
}

View File

@ -11,21 +11,22 @@ import (
type Config struct {
Devices []Device `yaml:"devices"`
Features struct {
BGP bool `yaml:"bgp,omitempty"`
DHCP bool `yaml:"dhcp,omitempty"`
DHCPL bool `yaml:"dhcpl,omitempty"`
DHCPv6 bool `yaml:"dhcpv6,omitempty"`
Firmware bool `yaml:"firmware,omitempty"`
Health bool `yaml:"health,omitempty"`
Routes bool `yaml:"routes,omitempty"`
POE bool `yaml:"poe,omitempty"`
Pools bool `yaml:"pools,omitempty"`
Optics bool `yaml:"optics,omitempty"`
W60G bool `yaml:"w60g,omitempty"`
WlanSTA bool `yaml:"wlansta,omitempty"`
WlanIF bool `yaml:"wlanif,omitempty"`
Monitor bool `yaml:"monitor,omitempty"`
Ipsec bool `yaml:"ipsec,omitempty"`
BGP bool `yaml:"bgp,omitempty"`
Conntrack bool `yaml:"conntrack,omitempty"`
DHCP bool `yaml:"dhcp,omitempty"`
DHCPL bool `yaml:"dhcpl,omitempty"`
DHCPv6 bool `yaml:"dhcpv6,omitempty"`
Firmware bool `yaml:"firmware,omitempty"`
Health bool `yaml:"health,omitempty"`
Routes bool `yaml:"routes,omitempty"`
POE bool `yaml:"poe,omitempty"`
Pools bool `yaml:"pools,omitempty"`
Optics bool `yaml:"optics,omitempty"`
W60G bool `yaml:"w60g,omitempty"`
WlanSTA bool `yaml:"wlansta,omitempty"`
WlanIF bool `yaml:"wlanif,omitempty"`
Monitor bool `yaml:"monitor,omitempty"`
Ipsec bool `yaml:"ipsec,omitempty"`
} `yaml:"features,omitempty"`
}

View File

@ -10,6 +10,7 @@ devices:
features:
bgp: true
conntrack: true
dhcp: true
dhcpv6: true
dhcpl: true

View File

@ -20,6 +20,7 @@ func TestShouldParse(t *testing.T) {
assertDevice("test1", "192.168.1.1", "foo", "bar", c.Devices[0], t)
assertDevice("test2", "192.168.2.1", "test", "123", c.Devices[1], t)
assertFeature("BGP", c.Features.BGP, t)
assertFeature("Conntrack", c.Features.Conntrack, t)
assertFeature("DHCP", c.Features.DHCP, t)
assertFeature("DHCPv6", c.Features.DHCPv6, t)
assertFeature("Pools", c.Features.Pools, t)

35
main.go
View File

@ -36,21 +36,22 @@ var (
user = flag.String("user", "", "user for authentication with single device")
ver = flag.Bool("version", false, "find the version of binary")
withBgp = flag.Bool("with-bgp", false, "retrieves BGP routing infrormation")
withRoutes = flag.Bool("with-routes", false, "retrieves routing table information")
withDHCP = flag.Bool("with-dhcp", false, "retrieves DHCP server metrics")
withDHCPL = flag.Bool("with-dhcpl", false, "retrieves DHCP server lease metrics")
withDHCPv6 = flag.Bool("with-dhcpv6", false, "retrieves DHCPv6 server metrics")
withFirmware = flag.Bool("with-firmware", false, "retrieves firmware versions")
withHealth = flag.Bool("with-health", false, "retrieves board Health metrics")
withPOE = flag.Bool("with-poe", false, "retrieves PoE metrics")
withPools = flag.Bool("with-pools", false, "retrieves IP(v6) pool metrics")
withOptics = flag.Bool("with-optics", false, "retrieves optical diagnostic metrics")
withW60G = flag.Bool("with-w60g", false, "retrieves w60g interface metrics")
withWlanSTA = flag.Bool("with-wlansta", false, "retrieves connected wlan station metrics")
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")
withBgp = flag.Bool("with-bgp", false, "retrieves BGP routing infrormation")
withConntrack = flag.Bool("with-conntrack", false, "retrieves connection tracking metrics")
withRoutes = flag.Bool("with-routes", false, "retrieves routing table information")
withDHCP = flag.Bool("with-dhcp", false, "retrieves DHCP server metrics")
withDHCPL = flag.Bool("with-dhcpl", false, "retrieves DHCP server lease metrics")
withDHCPv6 = flag.Bool("with-dhcpv6", false, "retrieves DHCPv6 server metrics")
withFirmware = flag.Bool("with-firmware", false, "retrieves firmware versions")
withHealth = flag.Bool("with-health", false, "retrieves board Health metrics")
withPOE = flag.Bool("with-poe", false, "retrieves PoE metrics")
withPools = flag.Bool("with-pools", false, "retrieves IP(v6) pool metrics")
withOptics = flag.Bool("with-optics", false, "retrieves optical diagnostic metrics")
withW60G = flag.Bool("with-w60g", false, "retrieves w60g interface metrics")
withWlanSTA = flag.Bool("with-wlansta", false, "retrieves connected wlan station metrics")
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
@ -241,6 +242,10 @@ func collectorOptions() []collector.Option {
opts = append(opts, collector.WithIpsec())
}
if *withConntrack || cfg.Features.Conntrack {
opts = append(opts, collector.WithConntrack())
}
if *timeout != collector.DefaultTimeout {
opts = append(opts, collector.WithTimeout(*timeout))
}