Skip to content

Commit d680b93

Browse files
committed
Collect survey info in wifi collector
1 parent be19d53 commit d680b93

File tree

4 files changed

+305
-0
lines changed

4 files changed

+305
-0
lines changed

collector/fixtures/e2e-64k-page-output.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,6 +3376,46 @@ node_wifi_station_transmit_failed_total{device="wlan0",mac_address="aa:bb:cc:dd:
33763376
# TYPE node_wifi_station_transmit_retries_total counter
33773377
node_wifi_station_transmit_retries_total{device="wlan0",mac_address="01:02:03:04:05:06"} 20
33783378
node_wifi_station_transmit_retries_total{device="wlan0",mac_address="aa:bb:cc:dd:ee:ff"} 10
3379+
# HELP node_wifi_survey_channel_time_active_seconds The time the radio spent on the channel while it was active in seconds.
3380+
# TYPE node_wifi_survey_channel_time_active_seconds counter
3381+
node_wifi_survey_channel_time_active_seconds{device="wlan0",frequency="2412"} 80
3382+
node_wifi_survey_channel_time_active_seconds{device="wlan0",frequency="2437"} 40
3383+
# HELP node_wifi_survey_channel_time_bss_rx_seconds The time the radio spent on the channel receiving data from a BSS in seconds.
3384+
# TYPE node_wifi_survey_channel_time_bss_rx_seconds counter
3385+
node_wifi_survey_channel_time_bss_rx_seconds{device="wlan0",frequency="2412"} 15
3386+
node_wifi_survey_channel_time_bss_rx_seconds{device="wlan0",frequency="2437"} 8
3387+
# HELP node_wifi_survey_channel_time_busy_seconds The time the radio spent on the channel while it was busy in seconds.
3388+
# TYPE node_wifi_survey_channel_time_busy_seconds counter
3389+
node_wifi_survey_channel_time_busy_seconds{device="wlan0",frequency="2412"} 30
3390+
node_wifi_survey_channel_time_busy_seconds{device="wlan0",frequency="2437"} 15
3391+
# HELP node_wifi_survey_channel_time_ext_busy_seconds The time the radio spent on the channel while it was busy with external traffic in seconds.
3392+
# TYPE node_wifi_survey_channel_time_ext_busy_seconds counter
3393+
node_wifi_survey_channel_time_ext_busy_seconds{device="wlan0",frequency="2412"} 5
3394+
node_wifi_survey_channel_time_ext_busy_seconds{device="wlan0",frequency="2437"} 2
3395+
# HELP node_wifi_survey_channel_time_rx_seconds The time the radio spent on the channel receiving data in seconds.
3396+
# TYPE node_wifi_survey_channel_time_rx_seconds counter
3397+
node_wifi_survey_channel_time_rx_seconds{device="wlan0",frequency="2412"} 20
3398+
node_wifi_survey_channel_time_rx_seconds{device="wlan0",frequency="2437"} 10
3399+
# HELP node_wifi_survey_channel_time_scan_seconds The time the radio spent on the channel while it was scanning in seconds.
3400+
# TYPE node_wifi_survey_channel_time_scan_seconds counter
3401+
node_wifi_survey_channel_time_scan_seconds{device="wlan0",frequency="2412"} 2
3402+
node_wifi_survey_channel_time_scan_seconds{device="wlan0",frequency="2437"} 1
3403+
# HELP node_wifi_survey_channel_time_seconds The time the radio spent on the channel in seconds.
3404+
# TYPE node_wifi_survey_channel_time_seconds counter
3405+
node_wifi_survey_channel_time_seconds{device="wlan0",frequency="2412"} 120
3406+
node_wifi_survey_channel_time_seconds{device="wlan0",frequency="2437"} 60
3407+
# HELP node_wifi_survey_channel_time_tx_seconds The time the radio spent on the channel transmitting data in seconds.
3408+
# TYPE node_wifi_survey_channel_time_tx_seconds counter
3409+
node_wifi_survey_channel_time_tx_seconds{device="wlan0",frequency="2412"} 10
3410+
node_wifi_survey_channel_time_tx_seconds{device="wlan0",frequency="2437"} 5
3411+
# HELP node_wifi_survey_in_use Indicates if the channel is currently in use (1 for in use, 0 for not in use).
3412+
# TYPE node_wifi_survey_in_use gauge
3413+
node_wifi_survey_in_use{device="wlan0",frequency="2412"} 1
3414+
node_wifi_survey_in_use{device="wlan0",frequency="2437"} 0
3415+
# HELP node_wifi_survey_noise_dbm The noise level in decibel-milliwatts (dBm).
3416+
# TYPE node_wifi_survey_noise_dbm gauge
3417+
node_wifi_survey_noise_dbm{device="wlan0",frequency="2412"} -95
3418+
node_wifi_survey_noise_dbm{device="wlan0",frequency="2437"} -92
33793419
# HELP node_xfrm_acquire_error_packets_total State hasn’t been fully acquired before use
33803420
# TYPE node_xfrm_acquire_error_packets_total counter
33813421
node_xfrm_acquire_error_packets_total 24532

collector/fixtures/e2e-output.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,6 +3398,46 @@ node_wifi_station_transmit_failed_total{device="wlan0",mac_address="aa:bb:cc:dd:
33983398
# TYPE node_wifi_station_transmit_retries_total counter
33993399
node_wifi_station_transmit_retries_total{device="wlan0",mac_address="01:02:03:04:05:06"} 20
34003400
node_wifi_station_transmit_retries_total{device="wlan0",mac_address="aa:bb:cc:dd:ee:ff"} 10
3401+
# HELP node_wifi_survey_channel_time_active_seconds The time the radio spent on the channel while it was active in seconds.
3402+
# TYPE node_wifi_survey_channel_time_active_seconds counter
3403+
node_wifi_survey_channel_time_active_seconds{device="wlan0",frequency="2412"} 80
3404+
node_wifi_survey_channel_time_active_seconds{device="wlan0",frequency="2437"} 40
3405+
# HELP node_wifi_survey_channel_time_bss_rx_seconds The time the radio spent on the channel receiving data from a BSS in seconds.
3406+
# TYPE node_wifi_survey_channel_time_bss_rx_seconds counter
3407+
node_wifi_survey_channel_time_bss_rx_seconds{device="wlan0",frequency="2412"} 15
3408+
node_wifi_survey_channel_time_bss_rx_seconds{device="wlan0",frequency="2437"} 8
3409+
# HELP node_wifi_survey_channel_time_busy_seconds The time the radio spent on the channel while it was busy in seconds.
3410+
# TYPE node_wifi_survey_channel_time_busy_seconds counter
3411+
node_wifi_survey_channel_time_busy_seconds{device="wlan0",frequency="2412"} 30
3412+
node_wifi_survey_channel_time_busy_seconds{device="wlan0",frequency="2437"} 15
3413+
# HELP node_wifi_survey_channel_time_ext_busy_seconds The time the radio spent on the channel while it was busy with external traffic in seconds.
3414+
# TYPE node_wifi_survey_channel_time_ext_busy_seconds counter
3415+
node_wifi_survey_channel_time_ext_busy_seconds{device="wlan0",frequency="2412"} 5
3416+
node_wifi_survey_channel_time_ext_busy_seconds{device="wlan0",frequency="2437"} 2
3417+
# HELP node_wifi_survey_channel_time_rx_seconds The time the radio spent on the channel receiving data in seconds.
3418+
# TYPE node_wifi_survey_channel_time_rx_seconds counter
3419+
node_wifi_survey_channel_time_rx_seconds{device="wlan0",frequency="2412"} 20
3420+
node_wifi_survey_channel_time_rx_seconds{device="wlan0",frequency="2437"} 10
3421+
# HELP node_wifi_survey_channel_time_scan_seconds The time the radio spent on the channel while it was scanning in seconds.
3422+
# TYPE node_wifi_survey_channel_time_scan_seconds counter
3423+
node_wifi_survey_channel_time_scan_seconds{device="wlan0",frequency="2412"} 2
3424+
node_wifi_survey_channel_time_scan_seconds{device="wlan0",frequency="2437"} 1
3425+
# HELP node_wifi_survey_channel_time_seconds The time the radio spent on the channel in seconds.
3426+
# TYPE node_wifi_survey_channel_time_seconds counter
3427+
node_wifi_survey_channel_time_seconds{device="wlan0",frequency="2412"} 120
3428+
node_wifi_survey_channel_time_seconds{device="wlan0",frequency="2437"} 60
3429+
# HELP node_wifi_survey_channel_time_tx_seconds The time the radio spent on the channel transmitting data in seconds.
3430+
# TYPE node_wifi_survey_channel_time_tx_seconds counter
3431+
node_wifi_survey_channel_time_tx_seconds{device="wlan0",frequency="2412"} 10
3432+
node_wifi_survey_channel_time_tx_seconds{device="wlan0",frequency="2437"} 5
3433+
# HELP node_wifi_survey_in_use Indicates if the channel is currently in use (1 for in use, 0 for not in use).
3434+
# TYPE node_wifi_survey_in_use gauge
3435+
node_wifi_survey_in_use{device="wlan0",frequency="2412"} 1
3436+
node_wifi_survey_in_use{device="wlan0",frequency="2437"} 0
3437+
# HELP node_wifi_survey_noise_dbm The noise level in decibel-milliwatts (dBm).
3438+
# TYPE node_wifi_survey_noise_dbm gauge
3439+
node_wifi_survey_noise_dbm{device="wlan0",frequency="2412"} -95
3440+
node_wifi_survey_noise_dbm{device="wlan0",frequency="2437"} -92
34013441
# HELP node_xfrm_acquire_error_packets_total State hasn’t been fully acquired before use
34023442
# TYPE node_xfrm_acquire_error_packets_total counter
34033443
node_xfrm_acquire_error_packets_total 24532
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[
2+
{
3+
"interfaceindex": 3,
4+
"frequency": 2412,
5+
"noise": -95,
6+
"channeltime": 120000000000,
7+
"channeltimeactive": 80000000000,
8+
"channeltimebusy": 30000000000,
9+
"channeltimeextbusy": 5000000000,
10+
"channeltimebssrx": 15000000000,
11+
"channeltimerx": 20000000000,
12+
"channeltimetx": 10000000000,
13+
"channeltimescan": 2000000000,
14+
"inuse": true
15+
},
16+
{
17+
"interfaceindex": 3,
18+
"frequency": 2437,
19+
"noise": -92,
20+
"channeltime": 60000000000,
21+
"channeltimeactive": 40000000000,
22+
"channeltimebusy": 15000000000,
23+
"channeltimeextbusy": 2000000000,
24+
"channeltimebssrx": 8000000000,
25+
"channeltimerx": 10000000000,
26+
"channeltimetx": 5000000000,
27+
"channeltimescan": 1000000000,
28+
"inuse": false
29+
}
30+
]

collector/wifi_linux.go

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ type wifiCollector struct {
4444
stationTransmitFailedTotal *prometheus.Desc
4545
stationBeaconLossTotal *prometheus.Desc
4646

47+
surveyNoiseDBM *prometheus.Desc
48+
surveyChannelTimeSeconds *prometheus.Desc
49+
surveyChannelTimeActiveSeconds *prometheus.Desc
50+
surveyChannelTimeBusySeconds *prometheus.Desc
51+
surveyChannelTimeExtBusySeconds *prometheus.Desc
52+
surveyChannelTimeBssRxSeconds *prometheus.Desc
53+
surveyChannelTimeRxSeconds *prometheus.Desc
54+
surveyChannelTimeTxSeconds *prometheus.Desc
55+
surveyChannelTimeScanSeconds *prometheus.Desc
56+
surveyInUse *prometheus.Desc
57+
4758
logger *slog.Logger
4859
}
4960

@@ -63,6 +74,7 @@ type wifiStater interface {
6374
Close() error
6475
Interfaces() ([]*wifi.Interface, error)
6576
StationInfo(ifi *wifi.Interface) ([]*wifi.StationInfo, error)
77+
SurveyInfo(ifi *wifi.Interface) ([]*wifi.SurveyInfo, error)
6678
}
6779

6880
// NewWifiCollector returns a new Collector exposing Wifi statistics.
@@ -159,6 +171,77 @@ func NewWifiCollector(logger *slog.Logger) (Collector, error) {
159171
labels,
160172
nil,
161173
),
174+
175+
surveyNoiseDBM: prometheus.NewDesc(
176+
prometheus.BuildFQName(namespace, subsystem, "survey_noise_dbm"),
177+
"The noise level in decibel-milliwatts (dBm).",
178+
[]string{"device", "frequency_mhz"},
179+
nil,
180+
),
181+
182+
surveyChannelTimeSeconds: prometheus.NewDesc(
183+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_seconds"),
184+
"The time the radio spent on the channel in seconds.",
185+
[]string{"device", "frequency_mhz"},
186+
nil,
187+
),
188+
189+
surveyChannelTimeActiveSeconds: prometheus.NewDesc(
190+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_active_seconds"),
191+
"The time the radio spent on the channel while it was active in seconds.",
192+
[]string{"device", "frequency_mhz"},
193+
nil,
194+
),
195+
196+
surveyChannelTimeBusySeconds: prometheus.NewDesc(
197+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_busy_seconds"),
198+
"The time the radio spent on the channel while it was busy in seconds.",
199+
[]string{"device", "frequency_mhz"},
200+
nil,
201+
),
202+
203+
surveyChannelTimeExtBusySeconds: prometheus.NewDesc(
204+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_ext_busy_seconds"),
205+
"The time the radio spent on the channel while it was busy with external traffic in seconds.",
206+
[]string{"device", "frequency_mhz"},
207+
nil,
208+
),
209+
210+
surveyChannelTimeBssRxSeconds: prometheus.NewDesc(
211+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_bss_rx_seconds"),
212+
"The time the radio spent on the channel receiving data from a BSS in seconds.",
213+
[]string{"device", "frequency_mhz"},
214+
nil,
215+
),
216+
217+
surveyChannelTimeRxSeconds: prometheus.NewDesc(
218+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_rx_seconds"),
219+
"The time the radio spent on the channel receiving data in seconds.",
220+
[]string{"device", "frequency_mhz"},
221+
nil,
222+
),
223+
224+
surveyChannelTimeTxSeconds: prometheus.NewDesc(
225+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_tx_seconds"),
226+
"The time the radio spent on the channel transmitting data in seconds.",
227+
[]string{"device", "frequency_mhz"},
228+
nil,
229+
),
230+
231+
surveyChannelTimeScanSeconds: prometheus.NewDesc(
232+
prometheus.BuildFQName(namespace, subsystem, "survey_channel_time_scan_seconds"),
233+
"The time the radio spent on the channel while it was scanning in seconds.",
234+
[]string{"device", "frequency_mhz"},
235+
nil,
236+
),
237+
238+
surveyInUse: prometheus.NewDesc(
239+
prometheus.BuildFQName(namespace, subsystem, "survey_in_use"),
240+
"Indicates if the channel is currently in use (1 for in use, 0 for not in use).",
241+
[]string{"device", "frequency_mhz"},
242+
nil,
243+
),
244+
162245
logger: logger,
163246
}, nil
164247
}
@@ -227,6 +310,19 @@ func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error {
227310
return fmt.Errorf("failed to retrieve station info for device %q: %v",
228311
ifi.Name, err)
229312
}
313+
314+
surveys, err := stat.SurveyInfo(ifi)
315+
switch {
316+
case err == nil:
317+
for _, survey := range surveys {
318+
c.updateSurveyStats(ch, ifi.Name, survey)
319+
}
320+
case errors.Is(err, os.ErrNotExist):
321+
c.logger.Debug("survey information not found for wifi device", "name", ifi.Name)
322+
default:
323+
return fmt.Errorf("failed to retrieve survey info for device %q: %v",
324+
ifi.Name, err)
325+
}
230326
}
231327

232328
return nil
@@ -327,6 +423,94 @@ func (c *wifiCollector) updateStationStats(ch chan<- prometheus.Metric, device s
327423
)
328424
}
329425

426+
func (c *wifiCollector) updateSurveyStats(ch chan<- prometheus.Metric, device string, info *wifi.SurveyInfo) {
427+
frequencyMHz := fmt.Sprintf("%d", info.Frequency)
428+
429+
ch <- prometheus.MustNewConstMetric(
430+
c.surveyNoiseDBM,
431+
prometheus.GaugeValue,
432+
float64(info.Noise),
433+
device,
434+
frequencyMHz,
435+
)
436+
437+
ch <- prometheus.MustNewConstMetric(
438+
c.surveyChannelTimeSeconds,
439+
prometheus.CounterValue,
440+
info.ChannelTime.Seconds(),
441+
device,
442+
frequencyMHz,
443+
)
444+
445+
ch <- prometheus.MustNewConstMetric(
446+
c.surveyChannelTimeActiveSeconds,
447+
prometheus.CounterValue,
448+
info.ChannelTimeActive.Seconds(),
449+
device,
450+
frequencyMHz,
451+
)
452+
453+
ch <- prometheus.MustNewConstMetric(
454+
c.surveyChannelTimeBusySeconds,
455+
prometheus.CounterValue,
456+
info.ChannelTimeBusy.Seconds(),
457+
device,
458+
frequencyMHz,
459+
)
460+
461+
ch <- prometheus.MustNewConstMetric(
462+
c.surveyChannelTimeExtBusySeconds,
463+
prometheus.CounterValue,
464+
info.ChannelTimeExtBusy.Seconds(),
465+
device,
466+
frequencyMHz,
467+
)
468+
469+
ch <- prometheus.MustNewConstMetric(
470+
c.surveyChannelTimeBssRxSeconds,
471+
prometheus.CounterValue,
472+
info.ChannelTimeBssRx.Seconds(),
473+
device,
474+
frequencyMHz,
475+
)
476+
477+
ch <- prometheus.MustNewConstMetric(
478+
c.surveyChannelTimeRxSeconds,
479+
prometheus.CounterValue,
480+
info.ChannelTimeRx.Seconds(),
481+
device,
482+
frequencyMHz,
483+
)
484+
485+
ch <- prometheus.MustNewConstMetric(
486+
c.surveyChannelTimeTxSeconds,
487+
prometheus.CounterValue,
488+
info.ChannelTimeTx.Seconds(),
489+
device,
490+
frequencyMHz,
491+
)
492+
493+
ch <- prometheus.MustNewConstMetric(
494+
c.surveyChannelTimeScanSeconds,
495+
prometheus.CounterValue,
496+
info.ChannelTimeScan.Seconds(),
497+
device,
498+
frequencyMHz,
499+
)
500+
501+
var inUseValue float64
502+
if info.InUse {
503+
inUseValue = 1
504+
}
505+
ch <- prometheus.MustNewConstMetric(
506+
c.surveyInUse,
507+
prometheus.GaugeValue,
508+
inUseValue,
509+
device,
510+
frequencyMHz,
511+
)
512+
}
513+
330514
func mHzToHz(mHz int) float64 {
331515
return float64(mHz) * 1000 * 1000
332516
}
@@ -404,3 +588,14 @@ func (s *mockWifiStater) StationInfo(ifi *wifi.Interface) ([]*wifi.StationInfo,
404588

405589
return stations, nil
406590
}
591+
592+
func (s *mockWifiStater) SurveyInfo(ifi *wifi.Interface) ([]*wifi.SurveyInfo, error) {
593+
p := filepath.Join(ifi.Name, "surveyinfo.json")
594+
595+
var surveyInfo []*wifi.SurveyInfo
596+
if err := s.unmarshalJSONFile(p, &surveyInfo); err != nil {
597+
return nil, err
598+
}
599+
600+
return surveyInfo, nil
601+
}

0 commit comments

Comments
 (0)