Files
mikrotik-exporter/collector/device.go
Steve Brunton be3ca4608c update logging (#5)
* removed Zap logging and switched to logrus
* "deprecating" the prometheus.go file and fixed up logging stuff on a couple more files.
* removed uber zap from glide
* well that sure messed things up
2017-11-29 22:42:59 -05:00

109 lines
2.7 KiB
Go

package collector
import (
"strings"
"fmt"
"strconv"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
"gopkg.in/routeros.v2"
"gopkg.in/routeros.v2/proto"
)
const (
apiPort = ":8728"
)
var (
interfaceLabelNames = []string{"name", "address", "interface"}
InterfaceProps = []string{"name", "rx-byte", "tx-byte", "rx-packet", "tx-packet", "rx-error", "tx-error", "rx-drop", "tx-drop"}
resourceLabelNames = []string{"name", "address"}
ResourceProps = []string{"free-memory", "total-memory", "cpu-load", "free-hdd-space", "total-hdd-space"}
)
type Device struct {
address string
name string
user string
password string
iDesc map[string]*prometheus.Desc // interface level descriptions for device
rDesc map[string]*prometheus.Desc // resource level descriptions for device
}
func metricStringCleanup(in string) string {
return strings.Replace(in, "-", "_", -1)
}
func (d *Device) fetchInterfaceMetrics() ([]*proto.Sentence, error) {
log.WithFields(log.Fields{
"device": d.name,
}).Debug("fetching interface metrics")
// grab a connection to the device
c, err := routeros.Dial(d.address+apiPort, d.user, d.password)
if err != nil {
log.WithFields(log.Fields{
"device": d.name,
"error": err,
}).Error("error dialing device")
return nil, err
}
defer c.Close()
reply, err := c.Run("/interface/print", "?disabled=false",
"?running=true", "=.proplist="+strings.Join(InterfaceProps, ","))
if err != nil {
log.WithFields(log.Fields{
"device": d.name,
"error": err,
}).Error("error fetching interface metrics")
return nil, err
}
return reply.Re, nil
}
func (d *Device) Update(ch chan<- prometheus.Metric) error {
stats, err := d.fetchInterfaceMetrics()
// if there is no error, deal with the response
if err == nil {
for _, re := range stats {
var intf string
for _, p := range InterfaceProps {
if p == "name" {
intf = re.Map[p]
} else {
desc, ok := d.iDesc[p]
if !ok {
desc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "interface", metricStringCleanup(p)),
fmt.Sprintf("interface property statistic %s", p),
interfaceLabelNames,
nil,
)
d.iDesc[p] = desc
}
v, err := strconv.ParseFloat(re.Map[p], 64)
if err == nil {
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, d.name, d.address, intf)
} else {
log.WithFields(log.Fields{
"device": d.name,
"interface": intf,
"property": p,
"value": re.Map[p],
"error": err,
}).Error("error parsing interface metric value")
}
}
}
}
}
return nil
}