aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Kochie <superq@gmail.com>2019-04-25 10:07:56 +0200
committerJohannes 'fish' Ziemke <github@freigeist.org>2019-04-25 10:07:56 +0200
commit78b9eb9c2c4366d6523a2ccbea6e9b0aad1104fe (patch)
treed98ad12ce2f06bfd3408769c5e1137318c636844
parent36e3b2a923e551830b583ecd43c8f9a9726576cf (diff)
downloadprometheus_node_collector-78b9eb9c2c4366d6523a2ccbea6e9b0aad1104fe.tar.bz2
prometheus_node_collector-78b9eb9c2c4366d6523a2ccbea6e9b0aad1104fe.tar.xz
prometheus_node_collector-78b9eb9c2c4366d6523a2ccbea6e9b0aad1104fe.zip
Use 64-bit Darwin netstat counters (#1319)
Avoid 32-bit counter rollovers. Signed-off-by: Ben Kochie <superq@gmail.com>
-rw-r--r--CHANGELOG.md1
-rw-r--r--collector/netdev_darwin.go111
2 files changed, 81 insertions, 31 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 08a9bf4..9237e24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,7 @@
25* [CHANGE] Split cpufreq metrics into a separate collector #1253 25* [CHANGE] Split cpufreq metrics into a separate collector #1253
26* [ENHANCEMENT] Add Infiniband counters #1120 26* [ENHANCEMENT] Add Infiniband counters #1120
27* [ENHANCEMENT] Move network_up labels into new metric network_info #1236 27* [ENHANCEMENT] Move network_up labels into new metric network_info #1236
28* [ENHANCEMENT] Use 64-bit counters for Darwin netstat
28* [FEATURE] Add a flag to disable exporter metrics #1148 29* [FEATURE] Add a flag to disable exporter metrics #1148
29* [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197 30* [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197
30* [FEATURE] Add uname collector for FreeBSD #1239 31* [FEATURE] Add uname collector for FreeBSD #1239
diff --git a/collector/netdev_darwin.go b/collector/netdev_darwin.go
index 9e7a14b..b02ed40 100644
--- a/collector/netdev_darwin.go
+++ b/collector/netdev_darwin.go
@@ -16,52 +16,101 @@
16package collector 16package collector
17 17
18import ( 18import (
19 "bytes"
20 "encoding/binary"
19 "errors" 21 "errors"
22 "net"
20 "regexp" 23 "regexp"
21 "strconv" 24 "strconv"
22 25
23 "github.com/prometheus/common/log" 26 "github.com/prometheus/common/log"
27 "golang.org/x/sys/unix"
24) 28)
25 29
26/*
27#include <stdio.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <ifaddrs.h>
31#include <net/if.h>
32*/
33import "C"
34
35func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) { 30func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) {
36 netDev := map[string]map[string]string{} 31 netDev := map[string]map[string]string{}
37 32
38 var ifap, ifa *C.struct_ifaddrs 33 ifs, err := net.Interfaces()
39 if C.getifaddrs(&ifap) == -1 { 34 if err != nil {
40 return nil, errors.New("getifaddrs() failed") 35 return nil, errors.New("net.Interfaces() failed")
41 } 36 }
42 defer C.freeifaddrs(ifap)
43 37
44 for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { 38 for _, iface := range ifs {
45 if ifa.ifa_addr.sa_family == C.AF_LINK { 39 ifaceData, err := getIfaceData(iface.Index)
46 dev := C.GoString(ifa.ifa_name) 40 if err != nil {
47 if ignore.MatchString(dev) { 41 log.Debugf("failed to load data for interface %q: %v", iface.Name, err)
48 log.Debugf("Ignoring device: %s", dev) 42 continue
49 continue 43 }
50 }
51 44
52 devStats := map[string]string{} 45 if ignore.MatchString(iface.Name) {
53 data := (*C.struct_if_data)(ifa.ifa_data) 46 log.Debugf("Ignoring device: %s", iface.Name)
54 devStats["receive_packets"] = strconv.FormatUint(uint64(data.ifi_ipackets), 10) 47 continue
55 devStats["transmit_packets"] = strconv.FormatUint(uint64(data.ifi_opackets), 10)
56 devStats["receive_errs"] = strconv.FormatUint(uint64(data.ifi_ierrors), 10)
57 devStats["transmit_errs"] = strconv.FormatUint(uint64(data.ifi_oerrors), 10)
58 devStats["receive_bytes"] = strconv.FormatUint(uint64(data.ifi_ibytes), 10)
59 devStats["transmit_bytes"] = strconv.FormatUint(uint64(data.ifi_obytes), 10)
60 devStats["receive_multicast"] = strconv.FormatUint(uint64(data.ifi_imcasts), 10)
61 devStats["transmit_multicast"] = strconv.FormatUint(uint64(data.ifi_omcasts), 10)
62 netDev[dev] = devStats
63 } 48 }
49
50 devStats := map[string]string{}
51 devStats["receive_packets"] = strconv.FormatUint(ifaceData.Data.Ipackets, 10)
52 devStats["transmit_packets"] = strconv.FormatUint(ifaceData.Data.Opackets, 10)
53 devStats["receive_errs"] = strconv.FormatUint(ifaceData.Data.Ierrors, 10)
54 devStats["transmit_errs"] = strconv.FormatUint(ifaceData.Data.Oerrors, 10)
55 devStats["receive_bytes"] = strconv.FormatUint(ifaceData.Data.Ibytes, 10)
56 devStats["transmit_bytes"] = strconv.FormatUint(ifaceData.Data.Obytes, 10)
57 devStats["receive_multicast"] = strconv.FormatUint(ifaceData.Data.Imcasts, 10)
58 devStats["transmit_multicast"] = strconv.FormatUint(ifaceData.Data.Omcasts, 10)
59 netDev[iface.Name] = devStats
64 } 60 }
65 61
66 return netDev, nil 62 return netDev, nil
67} 63}
64
65func getIfaceData(index int) (*ifMsghdr2, error) {
66 var data ifMsghdr2
67 rawData, err := unix.SysctlRaw("net", unix.AF_ROUTE, 0, 0, unix.NET_RT_IFLIST2, index)
68 if err != nil {
69 return nil, err
70 }
71 err = binary.Read(bytes.NewReader(rawData), binary.LittleEndian, &data)
72 return &data, err
73}
74
75type ifMsghdr2 struct {
76 Msglen uint16
77 Version uint8
78 Type uint8
79 Addrs int32
80 Flags int32
81 Index uint16
82 _ [2]byte
83 SndLen int32
84 SndMaxlen int32
85 SndDrops int32
86 Timer int32
87 Data ifData64
88}
89
90type ifData64 struct {
91 Type uint8
92 Typelen uint8
93 Physical uint8
94 Addrlen uint8
95 Hdrlen uint8
96 Recvquota uint8
97 Xmitquota uint8
98 Unused1 uint8
99 Mtu uint32
100 Metric uint32
101 Baudrate uint64
102 Ipackets uint64
103 Ierrors uint64
104 Opackets uint64
105 Oerrors uint64
106 Collisions uint64
107 Ibytes uint64
108 Obytes uint64
109 Imcasts uint64
110 Omcasts uint64
111 Iqdrops uint64
112 Noproto uint64
113 Recvtiming uint32
114 Xmittiming uint32
115 Lastchange unix.Timeval32
116}