2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright 2022 The Prometheus Authors
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// you may not use this file except in compliance with the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You may obtain a copy of the License at
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// http://www.apache.org/licenses/LICENSE-2.0
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Unless required by applicable law or agreed to in writing, software
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See the License for the specific language governing permissions and
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// limitations under the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//go:build !nonetclass && linux
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// +build !nonetclass,linux
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  collector  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io/fs" 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-07 00:25:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/alecthomas/kingpin/v2" 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-20 10:23:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/jsimonetti/rtnetlink/v2" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/mdlayher/ethtool" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/client_golang/prometheus" 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/procfs/sysfs" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netclassRTNLWithStats  =  kingpin . Flag ( "collector.netclass_rtnl.with-stats" ,  "Expose the statistics for each network device, replacing netdev collector." ) . Bool ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									operstateStr           =  [ ] string { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										"unknown" ,  "notpresent" ,  "down" ,  "lowerlayerdown" ,  "testing" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"dormant" ,  "up" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * netClassCollector )  netClassRTNLUpdate ( ch  chan <-  prometheus . Metric )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									linkModes  :=  make ( map [ string ] * ethtool . LinkMode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lms ,  err  :=  c . getLinkModes ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! errors . Is ( errors . Unwrap ( err ) ,  fs . ErrNotExist )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  fmt . Errorf ( "could not get link modes: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-11 01:51:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . logger . Info ( "ETHTOOL netlink interface unavailable, duplex and linkspeed are not scraped." ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  lm  :=  range  lms  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  c . ignoredDevicesPattern . MatchString ( lm . Interface . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  lm . SpeedMegabits  >=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												speedBytes  :=  uint64 ( lm . SpeedMegabits  *  1000  *  1000  /  8 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pushMetric ( ch ,  c . getFieldDesc ( "speed_bytes" ) ,  "speed_bytes" ,  speedBytes ,  prometheus . GaugeValue ,  lm . Interface . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											linkModes [ lm . Interface . Name ]  =  lm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get most attributes from Netlink
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									lMsgs ,  err  :=  c . getNetClassInfoRTNL ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "could not get net class info: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									relevantLinks  :=  make ( [ ] rtnetlink . LinkMessage ,  0 ,  len ( lMsgs ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  _ ,  msg  :=  range  lMsgs  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! c . ignoredDevicesPattern . MatchString ( msg . Attributes . Name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											relevantLinks  =  append ( relevantLinks ,  msg ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Read sysfs for attributes that Netlink doesn't expose
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sysfsAttrs ,  err  :=  getSysfsAttributes ( relevantLinks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "could not get sysfs device info: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Parse all the info and update metrics
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  msg  :=  range  relevantLinks  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										upDesc  :=  prometheus . NewDesc ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prometheus . BuildFQName ( namespace ,  c . subsystem ,  "up" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"Value is 1 if operstate is 'up', 0 otherwise." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											[ ] string { "device" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										upValue  :=  0.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  msg . Attributes . OperationalState  ==  rtnetlink . OperStateUp  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											upValue  =  1.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ch  <-  prometheus . MustNewConstMetric ( upDesc ,  prometheus . GaugeValue ,  upValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										infoDesc  :=  prometheus . NewDesc ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											prometheus . BuildFQName ( namespace ,  c . subsystem ,  "info" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"Non-numeric data of <iface>, value is always 1." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											[ ] string { "device" ,  "address" ,  "broadcast" ,  "duplex" ,  "operstate" ,  "ifalias" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										infoValue  :=  1.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ifalias  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  msg . Attributes . Alias  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ifalias  =  * msg . Attributes . Alias 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										duplex  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lm ,  lmExists  :=  linkModes [ msg . Attributes . Name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lmExists  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											duplex  =  lm . Duplex . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ifaceInfo  :=  sysfsAttrs [ msg . Attributes . Name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ch  <-  prometheus . MustNewConstMetric ( infoDesc ,  prometheus . GaugeValue ,  infoValue ,  msg . Attributes . Name ,  msg . Attributes . Address . String ( ) ,  msg . Attributes . Broadcast . String ( ) ,  duplex ,  operstateStr [ int ( msg . Attributes . OperationalState ) ] ,  ifalias ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "address_assign_type" ) ,  "address_assign_type" ,  ifaceInfo . AddrAssignType ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "carrier" ) ,  "carrier" ,  msg . Attributes . Carrier ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "carrier_changes_total" ) ,  "carrier_changes_total" ,  msg . Attributes . CarrierChanges ,  prometheus . CounterValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "carrier_up_changes_total" ) ,  "carrier_up_changes_total" ,  msg . Attributes . CarrierUpCount ,  prometheus . CounterValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "carrier_down_changes_total" ) ,  "carrier_down_changes_total" ,  msg . Attributes . CarrierDownCount ,  prometheus . CounterValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "device_id" ) ,  "device_id" ,  ifaceInfo . DevID ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "flags" ) ,  "flags" ,  msg . Flags ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "iface_id" ) ,  "iface_id" ,  msg . Index ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "iface_link_mode" ) ,  "iface_link_mode" ,  msg . Attributes . LinkMode ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "dormant" ) ,  "dormant" ,  msg . Attributes . LinkMode ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// kernel logic: IFLA_LINK attribute will be ignore when ifindex is the same as iflink
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// (dev->ifindex != dev_get_iflink(dev) && nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev)))
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// As interface ID is never 0, we assume msg.Attributes.Type 0  means iflink is omitted in RTM_GETLINK response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  msg . Attributes . Type  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pushMetric ( ch ,  c . getFieldDesc ( "iface_link" ) ,  "iface_link" ,  msg . Attributes . Type ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pushMetric ( ch ,  c . getFieldDesc ( "iface_link" ) ,  "iface_link" ,  msg . Index ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "mtu_bytes" ) ,  "mtu_bytes" ,  msg . Attributes . MTU ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "name_assign_type" ) ,  "name_assign_type" ,  ifaceInfo . NameAssignType ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "net_dev_group" ) ,  "net_dev_group" ,  msg . Attributes . NetDevGroup ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_queue_length" ) ,  "transmit_queue_length" ,  msg . Attributes . TxQueueLen ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "protocol_type" ) ,  "protocol_type" ,  msg . Type ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Skip statistics if argument collector.netclass_rtnl.with-stats is false or statistics are unavailable.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  netclassRTNLWithStats  ==  nil  ||  ! * netclassRTNLWithStats  ||  msg . Attributes . Stats64  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_packets_total" ) ,  "receive_packets_total" ,  msg . Attributes . Stats64 . RXPackets ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_packets_total" ) ,  "transmit_packets_total" ,  msg . Attributes . Stats64 . TXPackets ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_bytes_total" ) ,  "receive_bytes_total" ,  msg . Attributes . Stats64 . RXBytes ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_bytes_total" ) ,  "transmit_bytes_total" ,  msg . Attributes . Stats64 . TXBytes ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_errors_total" ) ,  "receive_errors_total" ,  msg . Attributes . Stats64 . RXErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_errors_total" ) ,  "transmit_errors_total" ,  msg . Attributes . Stats64 . TXErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_dropped_total" ) ,  "receive_dropped_total" ,  msg . Attributes . Stats64 . RXDropped ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_dropped_total" ) ,  "transmit_dropped_total" ,  msg . Attributes . Stats64 . TXDropped ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "multicast_total" ) ,  "multicast_total" ,  msg . Attributes . Stats64 . Multicast ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "collisions_total" ) ,  "collisions_total" ,  msg . Attributes . Stats64 . Collisions ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Detailed rx_errors.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_length_errors_total" ) ,  "receive_length_errors_total" ,  msg . Attributes . Stats64 . RXLengthErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_over_errors_total" ) ,  "receive_over_errors_total" ,  msg . Attributes . Stats64 . RXOverErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_crc_errors_total" ) ,  "receive_crc_errors_total" ,  msg . Attributes . Stats64 . RXCRCErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_frame_errors_total" ) ,  "receive_frame_errors_total" ,  msg . Attributes . Stats64 . RXFrameErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_fifo_errors_total" ) ,  "receive_fifo_errors_total" ,  msg . Attributes . Stats64 . RXFIFOErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_missed_errors_total" ) ,  "receive_missed_errors_total" ,  msg . Attributes . Stats64 . RXMissedErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Detailed tx_errors.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_aborted_errors_total" ) ,  "transmit_aborted_errors_total" ,  msg . Attributes . Stats64 . TXAbortedErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_carrier_errors_total" ) ,  "transmit_carrier_errors_total" ,  msg . Attributes . Stats64 . TXCarrierErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_fifo_errors_total" ) ,  "transmit_fifo_errors_total" ,  msg . Attributes . Stats64 . TXFIFOErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_heartbeat_errors_total" ) ,  "transmit_heartbeat_errors_total" ,  msg . Attributes . Stats64 . TXHeartbeatErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_window_errors_total" ) ,  "transmit_window_errors_total" ,  msg . Attributes . Stats64 . TXWindowErrors ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// For cslip, etc.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_compressed_total" ) ,  "receive_compressed_total" ,  msg . Attributes . Stats64 . RXCompressed ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "transmit_compressed_total" ) ,  "transmit_compressed_total" ,  msg . Attributes . Stats64 . TXCompressed ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pushMetric ( ch ,  c . getFieldDesc ( "receive_nohandler_total" ) ,  "receive_nohandler_total" ,  msg . Attributes . Stats64 . RXNoHandler ,  prometheus . GaugeValue ,  msg . Attributes . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * netClassCollector )  getNetClassInfoRTNL ( )  ( [ ] rtnetlink . LinkMessage ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									conn ,  err  :=  rtnetlink . Dial ( nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lMsgs ,  err  :=  conn . Link . List ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  lMsgs ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 02:22:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * netClassCollector )  getLinkModes ( )  ( [ ] * ethtool . LinkMode ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-21 07:38:04 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									conn ,  err  :=  ethtool . New ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lms ,  err  :=  conn . LinkModes ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  lms ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-05-25 06:10:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// getSysfsAttributes reads attributes that are absent from netlink but provided
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// by sysfs.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getSysfsAttributes ( links  [ ] rtnetlink . LinkMessage )  ( sysfs . NetClass ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netClass  :=  sysfs . NetClass { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  msg  :=  range  links  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										interfaceClass  :=  sysfs . NetClassIface { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ifName  :=  msg . Attributes . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										devPath  :=  filepath . Join ( "/sys" ,  "class" ,  "net" ,  ifName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// These three attributes hold a device-specific lock when
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// accessed, not the RTNL lock, so they are much less impactful
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// than reading most of the other attributes from sysfs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  attr  :=  range  [ ] string { "addr_assign_type" ,  "dev_id" ,  "name_assign_type" }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  sysfs . ParseNetClassAttribute ( devPath ,  attr ,  & interfaceClass ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										netClass [ ifName ]  =  interfaceClass 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  netClass ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}