监控无线接口

导航到

如果你已经阅读了我之前的几篇文章,你会发现我一直在研究路由器和无线设备。我正在使用 InfluxDB 建立一个更大、更复杂的 IoT 监控“参考架构”,为此,我使用了各种不同的设备。我正在重新使用我的 Pine-64 设备(见这里),并希望能够监控无线接口的统计数据。结果,竟然没有 Telegraf 插件可以做到这一点!什么?!所以我写了这一个。

如果你曾经使用过 cat /proc/net/wireless,你会知道,尽管输出很简单且很有帮助,但有人决定一个两行的标题是一个好主意。这并不是一个好主意。

ubuntu@pine64:~$ cat /proc/net/wireless
Inter-| sta-| Quality | Discarded packets | Missed | WE
 face | tus | link level noise | nwid crypt frag retry misc | beacon | 22
 wlan0: 0000 0. -256. -256. 0 0 0 0 0 0
 wlan1: 0000 42. -73. -256. 0 0 0 0 0 0
ubuntu@pine64:~$

我的意思是,它看起来很漂亮,但它真的不适合轻松解析为有意义的内容。无论如何,既然我开始写另一个 Telegraf 插件,解析它正是我需要做的事情。这就是我必须编写的代码,以解析该标题并将其组合成有意义的内容,以便存储在 InfluxDB 中:

func loadWirelessTable(table []byte, dumpZeros bool) (map[string]interface{}, map[string]string, error) {
	metrics := map[string]interface{}{}
	tags := map[string]string{}
	myLines := strings.Split(string(table), "\n")
	for x := 0; x < len(myLines)-1; x++ {
		f := strings.SplitN(myLines[x], ":", 2)
		f[0] = strings.Trim(f[0], " ")
		f[1] = strings.Trim(f[1], " ")
		if f[0] == "BSSID" {
			tags[strings.Replace(strings.Trim(f[0], " "), " ", "_", -1)] = strings.Replace(strings.Trim(string(f[1]), " "), " ", "_", -1)
			continue
		}
		n, err := strconv.ParseInt(strings.Trim(f[1], " "), 10, 64)
		if err != nil {
			tags[strings.Replace(strings.Trim(f[0], " "), " ", "_", -1)] = strings.Replace(strings.Trim(f[1], " "), " ", "_", -1)
			continue
		}
		if n == 0 {
			if dumpZeros {
				continue
			}
		}
		metrics[strings.Trim(f[0], " ")] = n

	}
	tags["interface"] = "airport"
	return metrics, tags, nil

}

所有这些,都是为了让我们可以看到这个:

Google ChromeScreenSnapz002

在 Chronograf 中!太棒了!注意我如何将多行标题转换为“quality_level”等独立值,并通过替换空格为下划线等使其更适合 InfluxDB。现在我们可以监控无线接口的所有各个方面了!所以,既然我正在运行最新的 Chronograf 版本

Google ChromeScreenSnapz001

我有一个方便的仪表,可以显示我的活动无线界面的RSSI!当然,由于这个新插件(将在Telegraf的某个版本中推出!),它依赖于/proc/net/wireless,因此它**只**适用于Linux。

但是等等,我没有忘记所有那些Mac用户。经过一番Google搜索,我发现了一种从Mac OS获取无线信息的大致类似方法。它隐藏得很深,不太容易访问,但我还是为您找到了它。它以更合理的方式格式化输出,使得它非常**简单**地集成到InfluxDB中。

$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
     agrCtlRSSI: -63
     agrExtRSSI: 0
    agrCtlNoise: -95
    agrExtNoise: 0
          state: running
        op mode: station
     lastTxRate: 65
        maxRate: 72
lastAssocStatus: 0
    802.11 auth: open
      link auth: wpa2-psk
          BSSID: 36:c3:d2:e3:ed:8e
           SSID: Influx-IoT2
            MCS: 7
        channel: 3
$

这大大减少了编写代码的工作量

func loadWirelessTable(table []byte, dumpZeros bool) (map[string]interface{}, map[string]string, error) {
	metrics := map[string]interface{}{}
	tags := map[string]string{}
	myLines := strings.Split(string(table), "\n")
	for x := 0; x < len(myLines)-1; x++ {
		f := strings.SplitN(myLines[x], ":", 2)
		f[0] = strings.Trim(f[0], " ")
		f[1] = strings.Trim(f[1], " ")
		if f[0] == "BSSID" {
			tags[strings.Replace(strings.Trim(f[0], " "), " ", "_", -1)] = strings.Replace(strings.Trim(string(f[1]), " "), " ", "_", -1)
			continue
		}
		n, err := strconv.ParseInt(strings.Trim(f[1], " "), 10, 64)
		if err != nil {
			tags[strings.Replace(strings.Trim(f[0], " "), " ", "_", -1)] = strings.Replace(strings.Trim(f[1], " "), " ", "_", -1)
			continue
		}
		if n == 0 {
			if dumpZeros {
				continue
			}
		}
		metrics[strings.Trim(f[0], " ")] = n

	}
	tags["interface"] = "airport"
	return metrics, tags, nil

}

非常合理,不是吗?它将所有这些读数转换成漂亮的标签和字段

Google ChromeScreenSnapz004

并且在我的Mac上给出了类似的仪表

Google ChromeScreenSnapz003

非常巧妙!

现在,你可能想知道我为什么要费这么大功夫,只是为了能够监控无线接口的RSSI。这是一个非常好的问题!你看,在物联网的世界里,你将会有一些网关设备,它们将通过无线接口收集数据——你知道的,为了与无线传感器连接。因此,能够监控这些无线接口的健康和活动状态非常重要。我添加了Mac版本的,只是因为它很简单,我也想这么做。

所以,请继续关注。我将添加一系列关于我连接到这个无线网关数据收集器的传感器的博客文章。这实际上是一个更大项目的组成部分,即构建一个更大、更专注于工业物联网的演示平台。