1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
local ethtool = require "ethtool"
local pattern_device = "^%s*([^%s:]+):"
local pattern_metric = "_*[^0-9A-Za-z_]+_*"
local metric_fqnames = {
rx_bytes = "node_ethtool_received_bytes_total",
rx_dropped = "node_ethtool_received_dropped_total",
rx_errors = "node_ethtool_received_errors_total",
rx_packets = "node_ethtool_received_packets_total",
tx_bytes = "node_ethtool_transmitted_bytes_total",
tx_errors = "node_ethtool_transmitted_errors_total",
tx_packets = "node_ethtool_transmitted_packets_total",
-- link info
supported_port = "node_network_supported_port_info",
supported_speed = "node_network_supported_speed_bytes",
supported_autonegotiate = "node_network_autonegotiate_supported",
supported_pause = "node_network_pause_supported",
supported_asymmetricpause = "node_network_asymmetricpause_supported",
advertised_speed = "node_network_advertised_speed_bytes",
advertised_autonegotiate = "node_network_autonegotiate_advertised",
advertised_pause = "node_network_pause_advertised",
advertised_asymmetricpause = "node_network_asymmetricpause_advertised",
autonegotiate = "node_network_autonegotiate",
}
local metric_replacement_words = {
rx = "received",
tx = "transmitted",
}
local function get_devices()
local devices = {}
for line in io.lines("/proc/net/dev") do
local dev = string.match(line, pattern_device)
if dev then
table.insert(devices, dev)
end
end
return devices
end
local function replace_words(metric)
return string.gsub(metric, "(%a+)", function(word)
local replacement = metric_replacement_words[word]
if replacement then
return replacement
end
return word
end)
end
local function build_ethtool_fqname(metric)
local metricName = metric:gsub(pattern_metric, "_")
metricName = metricName:lower():gsub("^[%s_]+", "")
metricName = replace_words(metricName)
return "node_ethtool_" .. metricName
end
local function scrape()
local eth = ethtool.open()
local metrics = {}
for _, dev in ipairs(get_devices()) do
local stats = eth:statistics(dev)
if stats then
for m_name, m_value in pairs(stats) do
fqname = metric_fqnames[m_name]
if fqname == nil then
fqname = build_ethtool_fqname(m_name)
metric_fqnames[m_name] = fqname
end
local m = metrics[fqname]
if m == nil then
m = metric(fqname, "untyped")
metrics[fqname] = m
end
m({ device = dev }, m_value)
end
end
end
eth:close()
end
return { scrape = scrape }
|