mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	Use 64-bit Darwin netstat counters (#1319)
Avoid 32-bit counter rollovers. Signed-off-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
		
							parent
							
								
									36e3b2a923
								
							
						
					
					
						commit
						78b9eb9c2c
					
				| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
* [CHANGE] Split cpufreq metrics into a separate collector #1253
 | 
			
		||||
* [ENHANCEMENT] Add Infiniband counters #1120
 | 
			
		||||
* [ENHANCEMENT] Move network_up labels into new metric network_info #1236
 | 
			
		||||
* [ENHANCEMENT] Use 64-bit counters for Darwin netstat
 | 
			
		||||
* [FEATURE] Add a flag to disable exporter metrics #1148
 | 
			
		||||
* [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197
 | 
			
		||||
* [FEATURE] Add uname collector for FreeBSD #1239
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,52 +16,101 @@
 | 
			
		|||
package collector
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"net"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/common/log"
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <ifaddrs.h>
 | 
			
		||||
#include <net/if.h>
 | 
			
		||||
*/
 | 
			
		||||
import "C"
 | 
			
		||||
 | 
			
		||||
func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) {
 | 
			
		||||
	netDev := map[string]map[string]string{}
 | 
			
		||||
 | 
			
		||||
	var ifap, ifa *C.struct_ifaddrs
 | 
			
		||||
	if C.getifaddrs(&ifap) == -1 {
 | 
			
		||||
		return nil, errors.New("getifaddrs() failed")
 | 
			
		||||
	ifs, err := net.Interfaces()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.New("net.Interfaces() failed")
 | 
			
		||||
	}
 | 
			
		||||
	defer C.freeifaddrs(ifap)
 | 
			
		||||
 | 
			
		||||
	for ifa = ifap; ifa != nil; ifa = ifa.ifa_next {
 | 
			
		||||
		if ifa.ifa_addr.sa_family == C.AF_LINK {
 | 
			
		||||
			dev := C.GoString(ifa.ifa_name)
 | 
			
		||||
			if ignore.MatchString(dev) {
 | 
			
		||||
				log.Debugf("Ignoring device: %s", dev)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			devStats := map[string]string{}
 | 
			
		||||
			data := (*C.struct_if_data)(ifa.ifa_data)
 | 
			
		||||
			devStats["receive_packets"] = strconv.FormatUint(uint64(data.ifi_ipackets), 10)
 | 
			
		||||
			devStats["transmit_packets"] = strconv.FormatUint(uint64(data.ifi_opackets), 10)
 | 
			
		||||
			devStats["receive_errs"] = strconv.FormatUint(uint64(data.ifi_ierrors), 10)
 | 
			
		||||
			devStats["transmit_errs"] = strconv.FormatUint(uint64(data.ifi_oerrors), 10)
 | 
			
		||||
			devStats["receive_bytes"] = strconv.FormatUint(uint64(data.ifi_ibytes), 10)
 | 
			
		||||
			devStats["transmit_bytes"] = strconv.FormatUint(uint64(data.ifi_obytes), 10)
 | 
			
		||||
			devStats["receive_multicast"] = strconv.FormatUint(uint64(data.ifi_imcasts), 10)
 | 
			
		||||
			devStats["transmit_multicast"] = strconv.FormatUint(uint64(data.ifi_omcasts), 10)
 | 
			
		||||
			netDev[dev] = devStats
 | 
			
		||||
	for _, iface := range ifs {
 | 
			
		||||
		ifaceData, err := getIfaceData(iface.Index)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Debugf("failed to load data for interface %q: %v", iface.Name, err)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ignore.MatchString(iface.Name) {
 | 
			
		||||
			log.Debugf("Ignoring device: %s", iface.Name)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		devStats := map[string]string{}
 | 
			
		||||
		devStats["receive_packets"] = strconv.FormatUint(ifaceData.Data.Ipackets, 10)
 | 
			
		||||
		devStats["transmit_packets"] = strconv.FormatUint(ifaceData.Data.Opackets, 10)
 | 
			
		||||
		devStats["receive_errs"] = strconv.FormatUint(ifaceData.Data.Ierrors, 10)
 | 
			
		||||
		devStats["transmit_errs"] = strconv.FormatUint(ifaceData.Data.Oerrors, 10)
 | 
			
		||||
		devStats["receive_bytes"] = strconv.FormatUint(ifaceData.Data.Ibytes, 10)
 | 
			
		||||
		devStats["transmit_bytes"] = strconv.FormatUint(ifaceData.Data.Obytes, 10)
 | 
			
		||||
		devStats["receive_multicast"] = strconv.FormatUint(ifaceData.Data.Imcasts, 10)
 | 
			
		||||
		devStats["transmit_multicast"] = strconv.FormatUint(ifaceData.Data.Omcasts, 10)
 | 
			
		||||
		netDev[iface.Name] = devStats
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return netDev, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getIfaceData(index int) (*ifMsghdr2, error) {
 | 
			
		||||
	var data ifMsghdr2
 | 
			
		||||
	rawData, err := unix.SysctlRaw("net", unix.AF_ROUTE, 0, 0, unix.NET_RT_IFLIST2, index)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	err = binary.Read(bytes.NewReader(rawData), binary.LittleEndian, &data)
 | 
			
		||||
	return &data, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ifMsghdr2 struct {
 | 
			
		||||
	Msglen    uint16
 | 
			
		||||
	Version   uint8
 | 
			
		||||
	Type      uint8
 | 
			
		||||
	Addrs     int32
 | 
			
		||||
	Flags     int32
 | 
			
		||||
	Index     uint16
 | 
			
		||||
	_         [2]byte
 | 
			
		||||
	SndLen    int32
 | 
			
		||||
	SndMaxlen int32
 | 
			
		||||
	SndDrops  int32
 | 
			
		||||
	Timer     int32
 | 
			
		||||
	Data      ifData64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ifData64 struct {
 | 
			
		||||
	Type       uint8
 | 
			
		||||
	Typelen    uint8
 | 
			
		||||
	Physical   uint8
 | 
			
		||||
	Addrlen    uint8
 | 
			
		||||
	Hdrlen     uint8
 | 
			
		||||
	Recvquota  uint8
 | 
			
		||||
	Xmitquota  uint8
 | 
			
		||||
	Unused1    uint8
 | 
			
		||||
	Mtu        uint32
 | 
			
		||||
	Metric     uint32
 | 
			
		||||
	Baudrate   uint64
 | 
			
		||||
	Ipackets   uint64
 | 
			
		||||
	Ierrors    uint64
 | 
			
		||||
	Opackets   uint64
 | 
			
		||||
	Oerrors    uint64
 | 
			
		||||
	Collisions uint64
 | 
			
		||||
	Ibytes     uint64
 | 
			
		||||
	Obytes     uint64
 | 
			
		||||
	Imcasts    uint64
 | 
			
		||||
	Omcasts    uint64
 | 
			
		||||
	Iqdrops    uint64
 | 
			
		||||
	Noproto    uint64
 | 
			
		||||
	Recvtiming uint32
 | 
			
		||||
	Xmittiming uint32
 | 
			
		||||
	Lastchange unix.Timeval32
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue