node_exporter/collector/netdev_freebsd.go

111 lines
2.9 KiB
Go
Raw Normal View History

2015-05-12 13:18:05 +00:00
// +build !nonetdev
package collector
import (
"errors"
"fmt"
"strconv"
"github.com/prometheus/client_golang/prometheus"
)
/*
2015-06-24 12:02:12 +00:00
#cgo CFLAGS: -D_IFI_OQDROPS
2015-05-12 13:18:05 +00:00
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
*/
import "C"
const (
netDevSubsystem = "network"
)
type netDevCollector struct {
metrics map[string]*prometheus.CounterVec
2015-05-12 13:18:05 +00:00
}
func init() {
Factories["netdev"] = NewNetDevCollector
}
2015-06-24 12:02:12 +00:00
// Takes a prometheus registry and returns a new Collector exposing
// Network device stats.
2015-06-23 13:49:18 +00:00
func NewNetDevCollector() (Collector, error) {
2015-05-12 13:18:05 +00:00
return &netDevCollector{
metrics: map[string]*prometheus.CounterVec{},
2015-05-12 13:18:05 +00:00
}, nil
}
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
netDev, err := getNetDevStats()
if err != nil {
2015-06-24 12:02:12 +00:00
return fmt.Errorf("couldn't get netstats: %s", err)
2015-05-12 13:18:05 +00:00
}
for direction, devStats := range netDev {
for dev, stats := range devStats {
for t, value := range stats {
key := direction + "_" + t
if _, ok := c.metrics[key]; !ok {
c.metrics[key] = prometheus.NewCounterVec(
prometheus.CounterOpts{
2015-05-12 13:18:05 +00:00
Namespace: Namespace,
Subsystem: netDevSubsystem,
Name: key,
Help: fmt.Sprintf("%s %s from getifaddrs().", t, direction),
},
[]string{"device"},
)
}
v, err := strconv.ParseFloat(value, 64)
if err != nil {
2015-06-24 12:02:12 +00:00
return fmt.Errorf("invalid value %s in netstats: %s", value, err)
2015-05-12 13:18:05 +00:00
}
c.metrics[key].WithLabelValues(dev).Set(v)
}
}
}
for _, m := range c.metrics {
m.Collect(ch)
}
return err
}
func getNetDevStats() (map[string]map[string]map[string]string, error) {
netDev := map[string]map[string]map[string]string{}
netDev["transmit"] = map[string]map[string]string{}
netDev["receive"] = map[string]map[string]string{}
var ifap, ifa *C.struct_ifaddrs
if C.getifaddrs(&ifap) == -1 {
return nil, errors.New("getifaddrs() failed!")
}
2015-06-24 12:02:12 +00:00
defer C.freeifaddrs(ifap)
2015-05-12 13:18:05 +00:00
for ifa = ifap; ifa != nil; ifa = ifa.ifa_next {
if ifa.ifa_addr.sa_family == C.AF_LINK {
receive := map[string]string{}
transmit := map[string]string{}
data := (*C.struct_if_data)(ifa.ifa_data)
receive["packets"] = strconv.Itoa(int(data.ifi_ipackets))
transmit["packets"] = strconv.Itoa(int(data.ifi_opackets))
receive["errs"] = strconv.Itoa(int(data.ifi_ierrors))
transmit["errs"] = strconv.Itoa(int(data.ifi_oerrors))
receive["bytes"] = strconv.Itoa(int(data.ifi_ibytes))
transmit["bytes"] = strconv.Itoa(int(data.ifi_obytes))
receive["multicast"] = strconv.Itoa(int(data.ifi_imcasts))
transmit["multicast"] = strconv.Itoa(int(data.ifi_omcasts))
receive["drop"] = strconv.Itoa(int(data.ifi_iqdrops))
2015-06-24 12:02:12 +00:00
transmit["drop"] = strconv.Itoa(int(data.ifi_oqdrops))
2015-05-12 13:18:05 +00:00
netDev["receive"][C.GoString(ifa.ifa_name)] = receive
netDev["transmit"][C.GoString(ifa.ifa_name)] = transmit
}
}
return netDev, nil
}