mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	Merge 3ca9f7d482 into be19d537cd
				
					
				
			This commit is contained in:
		
						commit
						5a0cea0ec2
					
				| 
						 | 
					@ -37,9 +37,20 @@ type arpCollector struct {
 | 
				
			||||||
	fs           procfs.FS
 | 
						fs           procfs.FS
 | 
				
			||||||
	deviceFilter deviceFilter
 | 
						deviceFilter deviceFilter
 | 
				
			||||||
	entries      *prometheus.Desc
 | 
						entries      *prometheus.Desc
 | 
				
			||||||
 | 
						states       *prometheus.Desc
 | 
				
			||||||
	logger       *slog.Logger
 | 
						logger       *slog.Logger
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var neighborStatesMap = map[uint16]string{
 | 
				
			||||||
 | 
						unix.NUD_INCOMPLETE: "incomplete",
 | 
				
			||||||
 | 
						unix.NUD_REACHABLE:  "reachable",
 | 
				
			||||||
 | 
						unix.NUD_STALE:      "stale",
 | 
				
			||||||
 | 
						unix.NUD_DELAY:      "delay",
 | 
				
			||||||
 | 
						unix.NUD_PROBE:      "probe",
 | 
				
			||||||
 | 
						unix.NUD_FAILED:     "failed",
 | 
				
			||||||
 | 
						unix.NUD_PERMANENT:  "permanent",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	registerCollector("arp", defaultEnabled, NewARPCollector)
 | 
						registerCollector("arp", defaultEnabled, NewARPCollector)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -59,6 +70,11 @@ func NewARPCollector(logger *slog.Logger) (Collector, error) {
 | 
				
			||||||
			"ARP entries by device",
 | 
								"ARP entries by device",
 | 
				
			||||||
			[]string{"device"}, nil,
 | 
								[]string{"device"}, nil,
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
 | 
							states: prometheus.NewDesc(
 | 
				
			||||||
 | 
								prometheus.BuildFQName(namespace, "arp", "states"),
 | 
				
			||||||
 | 
								"ARP states by device",
 | 
				
			||||||
 | 
								[]string{"device", "state"}, nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
		logger: logger,
 | 
							logger: logger,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -73,10 +89,10 @@ func getTotalArpEntries(deviceEntries []procfs.ARPEntry) map[string]uint32 {
 | 
				
			||||||
	return entries
 | 
						return entries
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getTotalArpEntriesRTNL() (map[string]uint32, error) {
 | 
					func getArpEntriesRTNL() (map[string]uint32, map[string]map[uint16]uint32, error) {
 | 
				
			||||||
	conn, err := rtnl.Dial(nil)
 | 
						conn, err := rtnl.Dial(nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer conn.Close()
 | 
						defer conn.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,29 +100,42 @@ func getTotalArpEntriesRTNL() (map[string]uint32, error) {
 | 
				
			||||||
	// restrict to AF_INET.
 | 
						// restrict to AF_INET.
 | 
				
			||||||
	neighbors, err := conn.Neighbours(nil, unix.AF_INET)
 | 
						neighbors, err := conn.Neighbours(nil, unix.AF_INET)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Map of interface name to ARP neighbor count.
 | 
						// Map of interface name to ARP neighbor count.
 | 
				
			||||||
	entries := make(map[string]uint32)
 | 
						entries := make(map[string]uint32)
 | 
				
			||||||
 | 
						// Map of map[InterfaceName]map[StateCode]CountOfTheState
 | 
				
			||||||
 | 
						states := make(map[string]map[uint16]uint32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, n := range neighbors {
 | 
						for _, n := range neighbors {
 | 
				
			||||||
		// Skip entries which have state NUD_NOARP to conform to output of /proc/net/arp.
 | 
							// Skip entries which have state NUD_NOARP to conform to output of /proc/net/arp.
 | 
				
			||||||
		if n.State&unix.NUD_NOARP == 0 {
 | 
							if n.State&unix.NUD_NOARP == unix.NUD_NOARP {
 | 
				
			||||||
			entries[n.Interface.Name]++
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							entries[n.Interface.Name]++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if _, ok := states[n.Interface.Name]; !ok {
 | 
				
			||||||
 | 
								states[n.Interface.Name] = make(map[uint16]uint32)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							states[n.Interface.Name][n.State]++
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return entries, nil
 | 
						return entries, states, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
 | 
					func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
 | 
				
			||||||
	var enumeratedEntry map[string]uint32
 | 
						var (
 | 
				
			||||||
 | 
							enumeratedEntry map[string]uint32
 | 
				
			||||||
 | 
							enumStates      map[string]map[uint16]uint32
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if *arpNetlink {
 | 
						if *arpNetlink {
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		enumeratedEntry, err = getTotalArpEntriesRTNL()
 | 
							enumeratedEntry, enumStates, err = getArpEntriesRTNL()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return fmt.Errorf("could not get ARP entries: %w", err)
 | 
								return fmt.Errorf("could not get ARP entries: %w", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -125,6 +154,13 @@ func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ch <- prometheus.MustNewConstMetric(
 | 
							ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
			c.entries, prometheus.GaugeValue, float64(entryCount), device)
 | 
								c.entries, prometheus.GaugeValue, float64(entryCount), device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if *arpNetlink {
 | 
				
			||||||
 | 
								for state, count := range enumStates[device] {
 | 
				
			||||||
 | 
									ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
 | 
										c.states, prometheus.GaugeValue, float64(count), device, neighborStatesMap[state])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue