Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid node_network_speed_bytes value -125000 for disconnected or virtualized NICs #1967

Closed
svalouch opened this issue Feb 11, 2021 · 3 comments · Fixed by #1989
Closed

Comments

@svalouch
Copy link

After upgrading to version 1.1.0 from 0.18.x or older in an oVirt / KVM virtual environment, we noticed that the metric node_network_speed_bytes is reported as -125000 when the file /sys/class/net/<nic>/speed contains the value -1, while previously the metric returned 0. The same behavior can be observed on physical wired connections when there is no cable plugged in, as I've just verified with my Arch Linux laptop.

I'd understand if it returned -1 since that's whats in the file to indicate that this interface "has no speed" (essentially a sentinel value) because it is either a complicated implementation of memcpy (VM), or has no connection (physical interface w/o cable) and this indicates the absence of information about the speed of the interface.

I've bisected this to commit 3ddc82c in PR #1580, included from version 1.0.0-rc.0 onward. I'm not fluent in golang, but judging from the commit message, it seems that the early division caused it to essentially become 0 due to loss of precision, and thus it stayed at 0 when the multiplications were applied. After the PR was applied, the -1 is brought to a high negative number before the division and so stays distinctly different from the raw input value or the value of 0 returned in previous versions.

IMHO, the value 0 before #1580 was merged was not entirely correct, but nevertheless adequate to indicate "no speed information for whatever reason". The new value of -125000 most certainly is not correct, as it is neither a well-known sentinel value like -1 nor an accurate indication of the speed of any network interface.

Thus, I propose special-casing the value of -1 to return either:

  • -1 (absence of information) or
  • 0 to reinstate the previous behavior.

Host operating system: output of uname -a

Linux hostname 4.18.0-240.10.1.el8_3.x86_64 #1 SMP Mon Jan 18 17:05:51 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
CentOS 8.3 running in oVirt (KVM), also observed on Debian Buster on the same hypervisor

node_exporter version: output of node_exporter --version

node_exporter, version 1.1.0 (branch: tarball, revision: 1.1.0)
  build user:       someone@builder
  build date:       20210206-20:29:17
  go version:       go1.15.8
  platform:         linux/amd64

node_exporter command line flags

None

Are you running node_exporter in Docker?

No

What did you do that produced an error?

Update to 1.1.0 from 0.18.3

What did you expect to see?

Either the value returned by 0.18.3:

$ url -s localhost:9100/metrics | grep -E '^node_network_speed_bytes'
node_network_speed_bytes{device="ens3"} 0

Or ideally the raw value to indicate the absence of information, which would be:

node_network_speed_bytes{device="ens3"} -1

What did you see instead?

$ curl -s localhost:9100/metrics | grep -E '^node_network_speed_bytes'
node_network_speed_bytes{device="ens3"} -125000
@roidelapluie
Copy link
Member

Interesting. Do you happen to know if -1 documented in the kernel as a special value? Are there other special values?

@svalouch
Copy link
Author

svalouch commented Feb 11, 2021

Good question, I haven't had much luck with the kernel source or documentation, the only thing I found was Documentation/ABI/testing/sysfs-class-net, which reads:

What:		/sys/class/net/<iface>/speed
Date:		October 2009
KernelVersion:	2.6.33
Contact:	netdev@vger.kernel.org
Description:
		Indicates the interface latest or current speed value. Value is
		an integer representing the link speed in Mbits/sec.

		Note: this attribute is only valid for interfaces that implement
		the ethtool get_link_ksettings method (mostly Ethernet).

It does not state what the attribute could read for "invalid" interfaces, though.

However, the ethtool tool treats 0 and -1 as unknown: netlink/settings.c#n471:

	if (tb[ETHTOOL_A_LINKMODES_SPEED]) {
		uint32_t val = mnl_attr_get_u32(tb[ETHTOOL_A_LINKMODES_SPEED]);

		print_banner(nlctx);
		if (val == 0 || val == (uint16_t)(-1) || val == (uint32_t)(-1))
			printf("\tSpeed: Unknown!\n");
		else
			printf("\tSpeed: %uMb/s\n", val);
	}

Since ethtool is closely related to the kernels network subsystem (and thus should know what could be returned) and treats anything else as valid speed value, I guess it would make sense to just copy its behavior:

  • if the speed pseudofile contains 0 or -1 return that value or decide whether to settle on a specific value for consistency
  • for everything else keep the current behavior

For reference, here are the outputs of ethtool and node-exporter:

laptop without cable plugged in

Intel Corporation Ethernet Connection I219-LM (rev 21)e1000e

Settings for enp0s31f6:
	Supported ports: [ TP ]
	Supported link modes:   10baseT/Half 10baseT/Full
	                        100baseT/Half 100baseT/Full
	                        1000baseT/Full
	Supported pause frame use: No
	Supports auto-negotiation: Yes
	Supported FEC modes: Not reported
	Advertised link modes:  10baseT/Half 10baseT/Full
	                        100baseT/Half 100baseT/Full
	                        1000baseT/Full
	Advertised pause frame use: No
	Advertised auto-negotiation: Yes
	Advertised FEC modes: Not reported
	Speed: Unknown!
	Duplex: Unknown! (255)
	Port: Twisted Pair
	PHYAD: 2
	Transceiver: internal
	Auto-negotiation: on
	MDI-X: Unknown (auto)
	Supports Wake-on: pumbg
	Wake-on: g
	Current message level: 0x00000007 (7)
			       drv probe link
	Link detected: no
$ $ curl -s localhost:9100/metrics | grep enp0s31f6
node_network_address_assign_type{device="enp0s31f6"} 0
node_network_carrier{device="enp0s31f6"} 0
node_network_carrier_changes_total{device="enp0s31f6"} 1
node_network_carrier_down_changes_total{device="enp0s31f6"} 1
node_network_carrier_up_changes_total{device="enp0s31f6"} 0
node_network_device_id{device="enp0s31f6"} 0
node_network_dormant{device="enp0s31f6"} 0
node_network_flags{device="enp0s31f6"} 4099
node_network_iface_id{device="enp0s31f6"} 2
node_network_iface_link{device="enp0s31f6"} 2
node_network_iface_link_mode{device="enp0s31f6"} 0
node_network_info{address="XX:XX:XX:XX:XX:XX",broadcast="ff:ff:ff:ff:ff:ff",device="enp0s31f6",duplex="unknown",ifalias="",operstate="down"} 1
node_network_mtu_bytes{device="enp0s31f6"} 1500
node_network_name_assign_type{device="enp0s31f6"} 4
node_network_net_dev_group{device="enp0s31f6"} 0
node_network_protocol_type{device="enp0s31f6"} 1
node_network_receive_bytes_total{device="enp0s31f6"} 0
node_network_receive_compressed_total{device="enp0s31f6"} 0
node_network_receive_drop_total{device="enp0s31f6"} 0
node_network_receive_errs_total{device="enp0s31f6"} 0
node_network_receive_fifo_total{device="enp0s31f6"} 0
node_network_receive_frame_total{device="enp0s31f6"} 0
node_network_receive_multicast_total{device="enp0s31f6"} 0
node_network_receive_packets_total{device="enp0s31f6"} 0
node_network_speed_bytes{device="enp0s31f6"} -125000
node_network_transmit_bytes_total{device="enp0s31f6"} 0
node_network_transmit_carrier_total{device="enp0s31f6"} 0
node_network_transmit_colls_total{device="enp0s31f6"} 0
node_network_transmit_compressed_total{device="enp0s31f6"} 0
node_network_transmit_drop_total{device="enp0s31f6"} 0
node_network_transmit_errs_total{device="enp0s31f6"} 0
node_network_transmit_fifo_total{device="enp0s31f6"} 0
node_network_transmit_packets_total{device="enp0s31f6"} 0
node_network_transmit_queue_length{device="enp0s31f6"} 1000
node_network_up{device="enp0s31f6"} 0

virtio-based VM interface, connected and working

Red Hat, Inc. Virtio network devicevirtio-pci

Settings for ens3:
        Supported ports: [ ]
        Supported link modes:   Not reported
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: Unknown!
        Duplex: Unknown! (255)
        Port: Other
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: off
        Link detected: yes
$ curl -s localhost:9100/metrics | grep ens3
node_arp_entries{device="ens3"} 4
node_network_address_assign_type{device="ens3"} 0
node_network_carrier{device="ens3"} 1
node_network_carrier_changes_total{device="ens3"} 2
node_network_carrier_down_changes_total{device="ens3"} 1
node_network_carrier_up_changes_total{device="ens3"} 1
node_network_device_id{device="ens3"} 0
node_network_dormant{device="ens3"} 0
node_network_flags{device="ens3"} 4099
node_network_iface_id{device="ens3"} 2
node_network_iface_link{device="ens3"} 2
node_network_iface_link_mode{device="ens3"} 0
node_network_info{address="XX:XX:XX:XX:XX:XX",broadcast="ff:ff:ff:ff:ff:ff",device="ens3",duplex="unknown",ifalias="",operstate="up"} 1
node_network_mtu_bytes{device="ens3"} 1500
node_network_name_assign_type{device="ens3"} 4
node_network_net_dev_group{device="ens3"} 0
node_network_protocol_type{device="ens3"} 1
node_network_receive_bytes_total{device="ens3"} 1.334205995e+09
node_network_receive_compressed_total{device="ens3"} 0
node_network_receive_drop_total{device="ens3"} 520453
node_network_receive_errs_total{device="ens3"} 0
node_network_receive_fifo_total{device="ens3"} 0
node_network_receive_frame_total{device="ens3"} 0
node_network_receive_multicast_total{device="ens3"} 0
node_network_receive_packets_total{device="ens3"} 3.404508e+06
node_network_speed_bytes{device="ens3"} -125000
node_network_transmit_bytes_total{device="ens3"} 1.34162633e+09
node_network_transmit_carrier_total{device="ens3"} 0
node_network_transmit_colls_total{device="ens3"} 0
node_network_transmit_compressed_total{device="ens3"} 0
node_network_transmit_drop_total{device="ens3"} 0
node_network_transmit_errs_total{device="ens3"} 0
node_network_transmit_fifo_total{device="ens3"} 0
node_network_transmit_packets_total{device="ens3"} 1.654007e+06
node_network_transmit_queue_length{device="ens3"} 1000
node_network_up{device="ens3"} 1

@SuperQ
Copy link
Member

SuperQ commented Mar 4, 2021

Thanks for the report, I'm just catching up on some of these issues.

For "unknown" like this, we tend to not expose data, rather than report negative numbers.

SuperQ added a commit that referenced this issue Mar 4, 2021
Some devices (ex virtual) don't have a speed and report `-1` as the
speed value. Skip reporting speed for these devices.

Fixes: #1967

Signed-off-by: Ben Kochie <superq@gmail.com>
SuperQ added a commit that referenced this issue Mar 17, 2021
Some devices (ex virtual) don't have a speed and report `-1` as the
speed value. Add a flag to allow ignoring speed on these devices.

Fixes: #1967

Signed-off-by: Ben Kochie <superq@gmail.com>
SuperQ added a commit that referenced this issue Mar 18, 2021
Some devices (ex virtual) don't have a speed and report `-1` as the
speed value. Add a flag to allow ignoring speed on these devices.

Fixes: #1967

Signed-off-by: Ben Kochie <superq@gmail.com>
oblitorum pushed a commit to shatteredsilicon/node_exporter that referenced this issue Apr 9, 2024
Some devices (ex virtual) don't have a speed and report `-1` as the
speed value. Add a flag to allow ignoring speed on these devices.

Fixes: prometheus#1967

Signed-off-by: Ben Kochie <superq@gmail.com>
oblitorum pushed a commit to shatteredsilicon/node_exporter that referenced this issue Apr 9, 2024
Some devices (ex virtual) don't have a speed and report `-1` as the
speed value. Add a flag to allow ignoring speed on these devices.

Fixes: prometheus#1967

Signed-off-by: Ben Kochie <superq@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants