Merge pull request #513 from mdlayher/wifi-bss-info

Add synthetic node_wifi_station_info metric for BSS information
This commit is contained in:
Julius Volz 2017-03-16 22:06:56 +01:00 committed by GitHub
commit edf1630f93
3 changed files with 60 additions and 0 deletions

View file

@ -2158,6 +2158,9 @@ node_wifi_station_connected_seconds_total{device="wlan0"} 30
# HELP node_wifi_station_inactive_seconds The number of seconds since any wireless activity has occurred on a station. # HELP node_wifi_station_inactive_seconds The number of seconds since any wireless activity has occurred on a station.
# TYPE node_wifi_station_inactive_seconds gauge # TYPE node_wifi_station_inactive_seconds gauge
node_wifi_station_inactive_seconds{device="wlan0"} 0.4 node_wifi_station_inactive_seconds{device="wlan0"} 0.4
# HELP node_wifi_station_info Labeled WiFi interface station information as provided by the operating system.
# TYPE node_wifi_station_info gauge
node_wifi_station_info{bssid="00:11:22:33:44:55",device="wlan0",mode="client",ssid="Example"} 1
# HELP node_wifi_station_receive_bits_per_second The current WiFi receive bitrate of a station, in bits per second. # HELP node_wifi_station_receive_bits_per_second The current WiFi receive bitrate of a station, in bits per second.
# TYPE node_wifi_station_receive_bits_per_second gauge # TYPE node_wifi_station_receive_bits_per_second gauge
node_wifi_station_receive_bits_per_second{device="wlan0"} 1.28e+08 node_wifi_station_receive_bits_per_second{device="wlan0"} 1.28e+08

View file

@ -0,0 +1,5 @@
{
"ssid": "Example",
"bssid": "ABEiM0RV",
"status": 1
}

View file

@ -28,6 +28,7 @@ import (
type wifiCollector struct { type wifiCollector struct {
InterfaceFrequencyHertz *prometheus.Desc InterfaceFrequencyHertz *prometheus.Desc
StationInfo *prometheus.Desc
StationConnectedSecondsTotal *prometheus.Desc StationConnectedSecondsTotal *prometheus.Desc
StationInactiveSeconds *prometheus.Desc StationInactiveSeconds *prometheus.Desc
@ -51,6 +52,7 @@ var _ wifiStater = &wifi.Client{}
// wifiStater is an interface used to swap out a *wifi.Client for end to end tests. // wifiStater is an interface used to swap out a *wifi.Client for end to end tests.
type wifiStater interface { type wifiStater interface {
BSS(ifi *wifi.Interface) (*wifi.BSS, error)
Close() error Close() error
Interfaces() ([]*wifi.Interface, error) Interfaces() ([]*wifi.Interface, error)
StationInfo(ifi *wifi.Interface) (*wifi.StationInfo, error) StationInfo(ifi *wifi.Interface) (*wifi.StationInfo, error)
@ -74,6 +76,13 @@ func NewWifiCollector() (Collector, error) {
nil, nil,
), ),
StationInfo: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "station_info"),
"Labeled WiFi interface station information as provided by the operating system.",
[]string{"device", "bssid", "ssid", "mode"},
nil,
),
StationConnectedSecondsTotal: prometheus.NewDesc( StationConnectedSecondsTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "station_connected_seconds_total"), prometheus.BuildFQName(Namespace, subsystem, "station_connected_seconds_total"),
"The total number of seconds a station has been connected to an access point.", "The total number of seconds a station has been connected to an access point.",
@ -163,6 +172,27 @@ func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error {
ifi.Name, ifi.Name,
) )
bss, err := stat.BSS(ifi)
if err != nil {
if os.IsNotExist(err) {
continue
}
return fmt.Errorf("failed to retrieve BSS for device %s: %v",
ifi.Name, err)
}
// Synthetic metric which provides WiFi station info, such as SSID, BSSID, etc.
ch <- prometheus.MustNewConstMetric(
c.StationInfo,
prometheus.GaugeValue,
1,
ifi.Name,
bss.BSSID.String(),
bss.SSID,
bssStatusMode(bss.Status),
)
info, err := stat.StationInfo(ifi) info, err := stat.StationInfo(ifi)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -241,6 +271,17 @@ func mHzToHz(mHz int) float64 {
return float64(mHz) * 1000 * 1000 return float64(mHz) * 1000 * 1000
} }
func bssStatusMode(status wifi.BSSStatus) string {
switch status {
case wifi.BSSStatusAuthenticated, wifi.BSSStatusAssociated:
return "client"
case wifi.BSSStatusIBSSJoined:
return "ad-hoc"
default:
return "unknown"
}
}
// All code below this point is used to assist with end-to-end tests for // 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. // the wifi collector, since wifi devices are not available in CI.
@ -273,6 +314,17 @@ func (s *mockWifiStater) unmarshalJSONFile(filename string, v interface{}) error
func (s *mockWifiStater) Close() error { return nil } func (s *mockWifiStater) Close() error { return nil }
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
}
func (s *mockWifiStater) Interfaces() ([]*wifi.Interface, error) { func (s *mockWifiStater) Interfaces() ([]*wifi.Interface, error) {
var ifis []*wifi.Interface var ifis []*wifi.Interface
if err := s.unmarshalJSONFile("interfaces.json", &ifis); err != nil { if err := s.unmarshalJSONFile("interfaces.json", &ifis); err != nil {