diff options
author | Ben Kochie <superq@gmail.com> | 2019-04-25 10:07:56 +0200 |
---|---|---|
committer | Johannes 'fish' Ziemke <github@freigeist.org> | 2019-04-25 10:07:56 +0200 |
commit | 78b9eb9c2c4366d6523a2ccbea6e9b0aad1104fe (patch) | |
tree | d98ad12ce2f06bfd3408769c5e1137318c636844 | |
parent | 36e3b2a923e551830b583ecd43c8f9a9726576cf (diff) | |
download | prometheus_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.md | 1 | ||||
-rw-r--r-- | collector/netdev_darwin.go | 111 |
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 @@ | |||
16 | package collector | 16 | package collector |
17 | 17 | ||
18 | import ( | 18 | import ( |
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 | */ | ||
33 | import "C" | ||
34 | |||
35 | func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) { | 30 | func 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 | |||
65 | func 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 | |||
75 | type 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 | |||
90 | type 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 | } | ||