Add synthetic node_wifi_station_info metric for BSS information

This commit is contained in:
Matt Layher 2017-03-13 16:20:42 -04:00
parent a02e469b07
commit 69368b7f9c
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.
# TYPE node_wifi_station_inactive_seconds gauge
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.
# TYPE node_wifi_station_receive_bits_per_second gauge
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 {
InterfaceFrequencyHertz *prometheus.Desc
StationInfo *prometheus.Desc
StationConnectedSecondsTotal *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.
type wifiStater interface {
BSS(ifi *wifi.Interface) (*wifi.BSS, error)
Close() error
Interfaces() ([]*wifi.Interface, error)
StationInfo(ifi *wifi.Interface) (*wifi.StationInfo, error)
@ -74,6 +76,13 @@ func NewWifiCollector() (Collector, error) {
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(
prometheus.BuildFQName(Namespace, subsystem, "station_connected_seconds_total"),
"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,
)
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)
if err != nil {
if os.IsNotExist(err) {
@ -241,6 +271,17 @@ func mHzToHz(mHz int) float64 {
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
// 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) 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) {
var ifis []*wifi.Interface
if err := s.unmarshalJSONFile("interfaces.json", &ifis); err != nil {