Skip to content

Commit a0d25b8

Browse files
committed
prometheus-node-exporter-ucode: order output
-netdev -netclass Fix metric output to be ordered per-metric, and not per-device as is done by node_exporter. In testing, netdev and netclass scrape time increased a mean 2msec as a result of the extra loops. In netdev, we skip some checks since the format of /proc/net/dev is stable. Signed-off-by: Paul Donald <newtwen+github@gmail.com>
1 parent 5a4c758 commit a0d25b8

File tree

2 files changed

+58
-28
lines changed

2 files changed

+58
-28
lines changed
Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,52 @@
11
const root = "/sys/class/net/";
22
const devices = fs.lsdir(root);
3+
const dev_length = length(devices);
34

4-
if (length(devices) < 1)
5+
if (dev_length < 1)
56
return false;
67

78
const m_info = gauge("node_network_info");
89
const m_speed = gauge("node_network_speed_bytes");
910
const metrics = {
1011
addr_assign_type: gauge("node_network_address_assign_type"),
11-
carrier: gauge("node_network_carrier"),
12+
carrier: gauge("node_network_carrier"),
1213
carrier_changes: counter("node_network_carrier_changes_total"),
1314
carrier_down_count: counter("node_network_carrier_down_changes_total"),
1415
carrier_up_count: counter("node_network_carrier_up_changes_total"),
15-
dev_id: gauge("node_network_device_id"),
16-
dormant: gauge("node_network_dormant"),
17-
flags: gauge("node_network_flags"),
18-
ifindex: gauge("node_network_iface_id"),
19-
iflink: gauge("node_network_iface_link"),
20-
link_mode: gauge("node_network_iface_link_mode"),
21-
mtu: gauge("node_network_mtu_bytes"),
16+
dev_id: gauge("node_network_device_id"),
17+
dormant: gauge("node_network_dormant"),
18+
flags: gauge("node_network_flags"),
19+
ifindex: gauge("node_network_iface_id"),
20+
iflink: gauge("node_network_iface_link"),
21+
link_mode: gauge("node_network_iface_link_mode"),
22+
mtu: gauge("node_network_mtu_bytes"),
2223
name_assign_type: gauge("node_network_name_assign_type"),
2324
netdev_group: gauge("node_network_net_dev_group"),
24-
type: gauge("node_network_protocol_type"),
25+
type: gauge("node_network_protocol_type"),
2526
tx_queue_len: gauge("node_network_transmit_queue_length"),
2627
};
2728

28-
for (let device in devices) {
29-
const devroot = root + device + "/";
29+
for (let i = 0; i < dev_length; i++) {
30+
const devroot = root + devices[i] + "/";
3031

3132
m_info({
32-
device,
33+
device: devices[i],
3334
address: oneline(devroot + "address"),
3435
broadcast: oneline(devroot + "broadcast"),
3536
duplex: oneline(devroot + "duplex"),
3637
operstate: oneline(devroot + "operstate"),
3738
ifalias: oneline(devroot + "ifalias"),
3839
}, 1);
40+
}
3941

40-
for (let m in metrics) {
41-
let line = oneline(devroot + m);
42-
metrics[m]({ device }, line);
42+
for (let m in metrics) {
43+
for (let i = 0; i < dev_length; i++) {
44+
metrics[m]({ device: devices[i] }, oneline(root + devices[i] + "/" + m));
4345
}
46+
}
4447

45-
const speed = int(oneline(devroot + "speed"));
48+
for (let i = 0; i < dev_length; i++) {
49+
const speed = int(oneline(root + devices[i] + "/" + "speed"));
4650
if (speed > 0)
47-
m_speed({ device }, speed * 1000 * 1000 / 8);
51+
m_speed({ device: devices[i] }, speed * 1000 * 1000 / 8);
4852
}

utils/prometheus-node-exporter-ucode/files/base/netdev.uc

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
let f = fs.open("/proc/net/dev");
1+
const f = fs.open("/proc/net/dev");
22

33
if (!f)
44
return false;
55

6-
const m = [
6+
const metrics = [
77
null,
88
counter("node_network_receive_bytes_total"),
99
counter("node_network_receive_packets_total"),
@@ -23,18 +23,44 @@ const m = [
2323
counter("node_network_transmit_compressed_total"),
2424
];
2525

26+
// Per-counter results array
27+
/* results[i] = { dev1: value, dev2: value, ... } */
28+
let results = [];
29+
for (let i = 0; i < length(metrics); i++)
30+
results[i] = {};
31+
32+
// Parse file first
2633
let line;
27-
while (line = nextline(f)) {
34+
for (let k = 0; line = nextline(f); k++) {
35+
if (k < 2)
36+
continue; // skip the header lines
2837
const x = wsplit(ltrim(line), " ");
2938

30-
if (length(x) < 2)
31-
continue;
39+
const dev = substr(x[0], 0, -1);
40+
41+
for (let i = 1; i < length(x); i++) {
42+
results[i][dev] = x[i];
43+
}
44+
}
3245

33-
if (substr(x[0], -1) != ":")
46+
// Build label objects
47+
let label_cache = {};
48+
for (let i = 1; i < length(results); i++) {
49+
for (let dev in results[i]) {
50+
if (!(dev in label_cache))
51+
label_cache[dev] = { device: dev };
52+
}
53+
}
54+
55+
// Emit metrics grouped by counter
56+
for (let i = 1; i < length(metrics); i++) {
57+
const metric = metrics[i];
58+
if (!metric)
3459
continue;
3560

36-
const count = min(length(x), length(m));
37-
const labels = { device: substr(x[0], 0, -1) };
38-
for (let i = 1; i < count; i++)
39-
m[i](labels, x[i]);
61+
for (let dev in results[i]) {
62+
metric(label_cache[dev], results[i][dev]);
63+
}
4064
}
65+
66+
return true;

0 commit comments

Comments
 (0)