| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | // Copyright 2017 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 04:35:24 -07:00
										 |  |  | //go:build !nowifi
 | 
					
						
							| 
									
										
										
										
											2020-06-12 01:26:30 -07:00
										 |  |  | // +build !nowifi
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | package collector | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2020-06-15 13:27:14 -07:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	"log/slog" | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-07 00:25:05 -08:00
										 |  |  | 	"github.com/alecthomas/kingpin/v2" | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	"github.com/mdlayher/wifi" | 
					
						
							|  |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type wifiCollector struct { | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 	interfaceFrequencyHertz *prometheus.Desc | 
					
						
							|  |  |  | 	stationInfo             *prometheus.Desc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stationConnectedSecondsTotal *prometheus.Desc | 
					
						
							|  |  |  | 	stationInactiveSeconds       *prometheus.Desc | 
					
						
							|  |  |  | 	stationReceiveBitsPerSecond  *prometheus.Desc | 
					
						
							|  |  |  | 	stationTransmitBitsPerSecond *prometheus.Desc | 
					
						
							| 
									
										
										
										
											2018-11-19 10:15:54 -08:00
										 |  |  | 	stationReceiveBytesTotal     *prometheus.Desc | 
					
						
							|  |  |  | 	stationTransmitBytesTotal    *prometheus.Desc | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 	stationSignalDBM             *prometheus.Desc | 
					
						
							|  |  |  | 	stationTransmitRetriesTotal  *prometheus.Desc | 
					
						
							|  |  |  | 	stationTransmitFailedTotal   *prometheus.Desc | 
					
						
							|  |  |  | 	stationBeaconLossTotal       *prometheus.Desc | 
					
						
							| 
									
										
										
										
											2019-12-31 08:19:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	logger *slog.Logger | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 	collectorWifi = kingpin.Flag("collector.wifi.fixtures", "test fixtures to use for wifi collector metrics").Default("").String() | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							| 
									
										
										
										
											2018-08-07 01:27:20 -07:00
										 |  |  | 	registerCollector("wifi", defaultDisabled, NewWifiCollector) | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var _ wifiStater = &wifi.Client{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // wifiStater is an interface used to swap out a *wifi.Client for end to end tests.
 | 
					
						
							|  |  |  | type wifiStater interface { | 
					
						
							| 
									
										
										
										
											2017-03-13 13:20:42 -07:00
										 |  |  | 	BSS(ifi *wifi.Interface) (*wifi.BSS, error) | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | 	Close() error | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	Interfaces() ([]*wifi.Interface, error) | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 	StationInfo(ifi *wifi.Interface) ([]*wifi.StationInfo, error) | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 08:44:53 -08:00
										 |  |  | // NewWifiCollector returns a new Collector exposing Wifi statistics.
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | func NewWifiCollector(logger *slog.Logger) (Collector, error) { | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	const ( | 
					
						
							|  |  |  | 		subsystem = "wifi" | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		labels = []string{"device", "mac_address"} | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &wifiCollector{ | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		interfaceFrequencyHertz: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "interface_frequency_hertz"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The current frequency a WiFi interface is operating at, in hertz.", | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 			[]string{"device"}, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationInfo: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_info"), | 
					
						
							| 
									
										
										
										
											2017-03-13 13:20:42 -07:00
										 |  |  | 			"Labeled WiFi interface station information as provided by the operating system.", | 
					
						
							|  |  |  | 			[]string{"device", "bssid", "ssid", "mode"}, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationConnectedSecondsTotal: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_connected_seconds_total"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The total number of seconds a station has been connected to an access point.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationInactiveSeconds: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_inactive_seconds"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The number of seconds since any wireless activity has occurred on a station.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationReceiveBitsPerSecond: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_receive_bits_per_second"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The current WiFi receive bitrate of a station, in bits per second.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationTransmitBitsPerSecond: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_transmit_bits_per_second"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The current WiFi transmit bitrate of a station, in bits per second.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 10:15:54 -08:00
										 |  |  | 		stationReceiveBytesTotal: prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_receive_bytes_total"), | 
					
						
							|  |  |  | 			"The total number of bytes received by a WiFi station.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		stationTransmitBytesTotal: prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_transmit_bytes_total"), | 
					
						
							|  |  |  | 			"The total number of bytes transmitted by a WiFi station.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationSignalDBM: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_signal_dbm"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The current WiFi signal strength, in decibel-milliwatts (dBm).", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationTransmitRetriesTotal: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_transmit_retries_total"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The total number of times a station has had to retry while sending a packet.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationTransmitFailedTotal: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_transmit_failed_total"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The total number of times a station has failed to send a packet.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		stationBeaconLossTotal: prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, subsystem, "station_beacon_loss_total"), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			"The total number of times a station has detected a beacon loss.", | 
					
						
							|  |  |  | 			labels, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		), | 
					
						
							| 
									
										
										
										
											2019-12-31 08:19:37 -08:00
										 |  |  | 		logger: logger, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error { | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | 	stat, err := newWifiStater(*collectorWifi) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-18 01:19:48 -07:00
										 |  |  | 		// Cannot access wifi metrics, report no error.
 | 
					
						
							| 
									
										
										
										
											2020-06-15 13:27:14 -07:00
										 |  |  | 		if errors.Is(err, os.ErrNotExist) { | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 			c.logger.Debug("wifi collector metrics are not available for this system") | 
					
						
							| 
									
										
										
										
											2020-02-19 07:11:29 -08:00
										 |  |  | 			return ErrNoData | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-06-15 13:27:14 -07:00
										 |  |  | 		if errors.Is(err, os.ErrPermission) { | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 			c.logger.Debug("wifi collector got permission denied when accessing metrics") | 
					
						
							| 
									
										
										
										
											2020-02-19 07:11:29 -08:00
										 |  |  | 			return ErrNoData | 
					
						
							| 
									
										
										
										
											2017-08-18 01:19:48 -07:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-29 05:51:31 -08:00
										 |  |  | 		return fmt.Errorf("failed to access wifi data: %w", err) | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	defer stat.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ifis, err := stat.Interfaces() | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-11-29 05:51:31 -08:00
										 |  |  | 		return fmt.Errorf("failed to retrieve wifi interfaces: %w", err) | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, ifi := range ifis { | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 		// Some virtual devices have no "name" and should be skipped.
 | 
					
						
							|  |  |  | 		if ifi.Name == "" { | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 		c.logger.Debug("probing wifi device with type", "wifi", ifi.Name, "type", ifi.Type) | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 			c.interfaceFrequencyHertz, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			mHzToHz(ifi.Frequency), | 
					
						
							|  |  |  | 			ifi.Name, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 		// When a statistic is not available for a given interface, package wifi
 | 
					
						
							| 
									
										
										
										
											2020-06-15 13:27:14 -07:00
										 |  |  | 		// returns a os.ErrNotExist error.  We leverage this to only export
 | 
					
						
							|  |  |  | 		// metrics which are actually valid for given interface types.
 | 
					
						
							| 
									
										
										
										
											2017-03-13 13:20:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 		bss, err := stat.BSS(ifi) | 
					
						
							|  |  |  | 		switch { | 
					
						
							|  |  |  | 		case err == nil: | 
					
						
							|  |  |  | 			c.updateBSSStats(ch, ifi.Name, bss) | 
					
						
							| 
									
										
										
										
											2020-06-15 13:27:14 -07:00
										 |  |  | 		case errors.Is(err, os.ErrNotExist): | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 			c.logger.Debug("BSS information not found for wifi device", "name", ifi.Name) | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2017-03-13 13:20:42 -07:00
										 |  |  | 			return fmt.Errorf("failed to retrieve BSS for device %s: %v", | 
					
						
							|  |  |  | 				ifi.Name, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		stations, err := stat.StationInfo(ifi) | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 		switch { | 
					
						
							|  |  |  | 		case err == nil: | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 			for _, station := range stations { | 
					
						
							|  |  |  | 				c.updateStationStats(ch, ifi.Name, station) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-06-15 13:27:14 -07:00
										 |  |  | 		case errors.Is(err, os.ErrNotExist): | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 			c.logger.Debug("station information not found for wifi device", "name", ifi.Name) | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			return fmt.Errorf("failed to retrieve station info for device %q: %v", | 
					
						
							| 
									
										
										
										
											2017-01-16 21:54:18 -08:00
										 |  |  | 				ifi.Name, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:25:01 -07:00
										 |  |  | func (c *wifiCollector) updateBSSStats(ch chan<- prometheus.Metric, device string, bss *wifi.BSS) { | 
					
						
							|  |  |  | 	// Synthetic metric which provides wifi station info, such as SSID, BSSID, etc.
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		c.stationInfo, | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		1, | 
					
						
							|  |  |  | 		device, | 
					
						
							|  |  |  | 		bss.BSSID.String(), | 
					
						
							|  |  |  | 		bss.SSID, | 
					
						
							|  |  |  | 		bssStatusMode(bss.Status), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | func (c *wifiCollector) updateStationStats(ch chan<- prometheus.Metric, device string, info *wifi.StationInfo) { | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationConnectedSecondsTotal, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		info.Connected.Seconds(), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationInactiveSeconds, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		info.Inactive.Seconds(), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationReceiveBitsPerSecond, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(info.ReceiveBitrate), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationTransmitBitsPerSecond, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(info.TransmitBitrate), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 10:15:54 -08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		c.stationReceiveBytesTotal, | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(info.ReceivedBytes), | 
					
						
							|  |  |  | 		device, | 
					
						
							|  |  |  | 		info.HardwareAddr.String(), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		c.stationTransmitBytesTotal, | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(info.TransmittedBytes), | 
					
						
							|  |  |  | 		device, | 
					
						
							|  |  |  | 		info.HardwareAddr.String(), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationSignalDBM, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(info.Signal), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationTransmitRetriesTotal, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(info.TransmitRetries), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationTransmitFailedTotal, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(info.TransmitFailed), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							| 
									
										
										
										
											2017-03-16 14:04:49 -07:00
										 |  |  | 		c.stationBeaconLossTotal, | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(info.BeaconLoss), | 
					
						
							|  |  |  | 		device, | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 		info.HardwareAddr.String(), | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mHzToHz(mHz int) float64 { | 
					
						
							|  |  |  | 	return float64(mHz) * 1000 * 1000 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-13 13:20:42 -07:00
										 |  |  | func bssStatusMode(status wifi.BSSStatus) string { | 
					
						
							|  |  |  | 	switch status { | 
					
						
							|  |  |  | 	case wifi.BSSStatusAuthenticated, wifi.BSSStatusAssociated: | 
					
						
							|  |  |  | 		return "client" | 
					
						
							|  |  |  | 	case wifi.BSSStatusIBSSJoined: | 
					
						
							|  |  |  | 		return "ad-hoc" | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return "unknown" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | // All code below this point is used to assist with end-to-end tests for
 | 
					
						
							|  |  |  | // the wifi collector, since wifi devices are not available in CI.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // newWifiStater determines if mocked test fixtures from files should be used for
 | 
					
						
							|  |  |  | // collecting wifi metrics, or if package wifi should be used.
 | 
					
						
							|  |  |  | func newWifiStater(fixtures string) (wifiStater, error) { | 
					
						
							|  |  |  | 	if fixtures != "" { | 
					
						
							|  |  |  | 		return &mockWifiStater{ | 
					
						
							|  |  |  | 			fixtures: fixtures, | 
					
						
							|  |  |  | 		}, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return wifi.New() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var _ wifiStater = &mockWifiStater{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type mockWifiStater struct { | 
					
						
							|  |  |  | 	fixtures string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *mockWifiStater) unmarshalJSONFile(filename string, v interface{}) error { | 
					
						
							| 
									
										
										
										
											2022-07-27 11:59:39 -07:00
										 |  |  | 	b, err := os.ReadFile(filepath.Join(s.fixtures, filename)) | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return json.Unmarshal(b, v) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 09:41:35 -08:00
										 |  |  | func (s *mockWifiStater) Close() error { return nil } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-13 13:20:42 -07:00
										 |  |  | func (s *mockWifiStater) BSS(ifi *wifi.Interface) (*wifi.BSS, error) { | 
					
						
							|  |  |  | 	p := filepath.Join(ifi.Name, "bss.json") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var bss wifi.BSS | 
					
						
							|  |  |  | 	if err := s.unmarshalJSONFile(p, &bss); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &bss, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | func (s *mockWifiStater) Interfaces() ([]*wifi.Interface, error) { | 
					
						
							|  |  |  | 	var ifis []*wifi.Interface | 
					
						
							|  |  |  | 	if err := s.unmarshalJSONFile("interfaces.json", &ifis); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ifis, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | func (s *mockWifiStater) StationInfo(ifi *wifi.Interface) ([]*wifi.StationInfo, error) { | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 	p := filepath.Join(ifi.Name, "stationinfo.json") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 	var stations []*wifi.StationInfo | 
					
						
							|  |  |  | 	if err := s.unmarshalJSONFile(p, &stations); err != nil { | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-16 07:02:25 -07:00
										 |  |  | 	return stations, nil | 
					
						
							| 
									
										
										
										
											2017-01-09 11:37:59 -08:00
										 |  |  | } |