From b3760f7ec0152e630c8b46742cb114c04a0d0bcf Mon Sep 17 00:00:00 2001 From: Petko Bordjukov Date: Thu, 5 Nov 2015 15:44:37 +0200 Subject: [PATCH] Collectd wifi stats gathering --- files/all/etc/collectd.conf | 5 + files/all/etc/sudoers | 189 ++++++++++++++++++ .../all/usr/share/collectd/wlstats-gather.sh | 2 + .../usr/share/collectd/wlstats-gatherer.sh | 132 ++++++++++++ 4 files changed, 328 insertions(+) create mode 100644 files/all/etc/sudoers create mode 100755 files/all/usr/share/collectd/wlstats-gather.sh create mode 100755 files/all/usr/share/collectd/wlstats-gatherer.sh diff --git a/files/all/etc/collectd.conf b/files/all/etc/collectd.conf index 994069d..7cc0a2c 100644 --- a/files/all/etc/collectd.conf +++ b/files/all/etc/collectd.conf @@ -88,3 +88,8 @@ LoadPlugin iwinfo # CacheTimeout 120 # CacheFlush 900 # + +LoadPlugin exec + + Exec "nobody" "/usr/share/collectd/wlstats_gather.sh" + \ No newline at end of file diff --git a/files/all/etc/sudoers b/files/all/etc/sudoers new file mode 100644 index 0000000..1118cfa --- /dev/null +++ b/files/all/etc/sudoers @@ -0,0 +1,189 @@ +# +# OpenWrt Config file for collectd(1). +# Please read collectd.conf(5) for a list of options. +# http://collectd.org/ +# + +Hostname "ap-bulgaria-1-ac" +#FQDNLookup true +BaseDir "/var/lib/collectd" +PIDFile "/var/run/collectd.pid" +#PluginDir "/usr/lib/collectd" +#TypesDB "/usr/share/collectd/types.db" +Interval 10 +ReadThreads 2 + +#LoadPlugin syslog +#LoadPlugin logfile + +# +# LogLevel info +# + +# +# LogLevel info +# File STDOUT +# Timestamp true +# + +LoadPlugin cpu +#LoadPlugin df +#LoadPlugin disk +LoadPlugin interface +LoadPlugin load +#LoadPlugin memory +LoadPlugin network +#LoadPlugin ping +#LoadPlugin processes +#LoadPlugin rrdtool +#LoadPlugin serial +LoadPlugin iwinfo + +# +# FSType tmpfs +# IgnoreSelected true +# ReportByDevice false +# ReportReserved false +# ReportInodes false +# + +# +# Disk "/^[hs]d[a-f][0-9]?$/" +# IgnoreSelected false +# + +# +# Interface "eth0" +# Interface "br-lan" +# IgnoreSelected false +# + + +# Server "ff18::efc0:4a42" "25826" + Server "10.100.0.1" +# Listen "ff18::efc0:4a42" "25826" +# Listen "239.192.74.66" "25826" +# TimeToLive "128" + Forward false +# CacheFlush 20 + ReportStats true + + +# +# Host "host.foo.bar" +# Interval 1.0 +# Timeout 0.9 +# TTL 255 +# SourceAddress "1.2.3.4" +# Device "eth0" +# MaxMissed -1 +# + +# +# Process "name" +# + +# +# DataDir "/var/lib/collectd/rrd" +# CacheTimeout 120 +# CacheFlush 900 +# + +LoadPlugin exec + + Exec "nobody" "/usr/share/collectd/wlstats_gather.sh" + +root@OpenWrt:/usr/share/collectd# cat /etc/sudoers +## sudoers file. +## +## This file MUST be edited with the 'visudo' command as root. +## Failure to use 'visudo' may result in syntax or file permission errors +## that prevent sudo from running. +## +## See the sudoers man page for the details on how to write a sudoers file. +## + +## +## Host alias specification +## +## Groups of machines. These may include host names (optionally with wildcards), +## IP addresses, network numbers or netgroups. +# Host_Alias WEBSERVERS = www1, www2, www3 + +## +## User alias specification +## +## Groups of users. These may consist of user names, uids, Unix groups, +## or netgroups. +# User_Alias ADMINS = millert, dowdy, mikef + +## +## Cmnd alias specification +## +## Groups of commands. Often used to group related commands together. +# Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ +# /usr/bin/pkill, /usr/bin/top +# Cmnd_Alias REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff + +## +## Defaults specification +## +## You may wish to keep some of the following environment variables +## when running commands via sudo. +## +## Locale settings +# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" +## +## Run X applications through sudo; HOME is used to find the +## .Xauthority file. Note that other programs use HOME to find +## configuration files and this may lead to privilege escalation! +# Defaults env_keep += "HOME" +## +## X11 resource path settings +# Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" +## +## Desktop path settings +# Defaults env_keep += "QTDIR KDEDIR" +## +## Allow sudo-run commands to inherit the callers' ConsoleKit session +# Defaults env_keep += "XDG_SESSION_COOKIE" +## +## Uncomment to enable special input methods. Care should be taken as +## this may allow users to subvert the command being run via sudo. +# Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" +## +## Uncomment to enable logging of a command's output, except for +## sudoreplay and reboot. Use sudoreplay to play back logged sessions. +# Defaults log_output +# Defaults!/usr/bin/sudoreplay !log_output +# Defaults!/usr/local/bin/sudoreplay !log_output +# Defaults!REBOOT !log_output + +## +## Runas alias specification +## + +## +## User privilege specification +## +root ALL=(ALL) ALL + +## Uncomment to allow members of group wheel to execute any command +# %wheel ALL=(ALL) ALL + +## Same thing without a password +# %wheel ALL=(ALL) NOPASSWD: ALL + +## Uncomment to allow members of group sudo to execute any command +# %sudo ALL=(ALL) ALL + +## Uncomment to allow any user to run sudo if they know the password +## of the user they are running the command as (root by default). +# Defaults targetpw # Ask for the password of the target user +# ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' + +nobody ALL = (root) NOPASSWD: /usr/share/collectd/wlstats_gatherer.sh + +## Read drop-in files from /etc/sudoers.d +## (the '#' here does not indicate a comment) +#includedir /etc/sudoers.d diff --git a/files/all/usr/share/collectd/wlstats-gather.sh b/files/all/usr/share/collectd/wlstats-gather.sh new file mode 100755 index 0000000..f5ecd9a --- /dev/null +++ b/files/all/usr/share/collectd/wlstats-gather.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sudo /usr/share/collectd/wlstats_gatherer.sh "${COLLECTD_HOSTNAME:-localhost}" "${COLLECTD_INTERVAL:-10}" diff --git a/files/all/usr/share/collectd/wlstats-gatherer.sh b/files/all/usr/share/collectd/wlstats-gatherer.sh new file mode 100755 index 0000000..45c3162 --- /dev/null +++ b/files/all/usr/share/collectd/wlstats-gatherer.sh @@ -0,0 +1,132 @@ +#!/bin/sh +# +# Simple wireless statistics gatherer for collectd +# +# Description: Simple wireless statistics gatherer for collectd +# Prereqs: OpenWRT compatible system / wlinfo / wl +# Used via: Collectd exec plugin type +# Author: Vladimir Vitkov +# Petko Bordjukov +# +# Version: 0.1 +# Date: 2015.05.25 +# +# Changelog: 2015.05.25 - Initial version +# 2015.11. + +# Variable Definition +_HOSTNAME=$1 +_PERIOD=10 +_PLUGIN='wlstats' + +# Binaries +_iwinfo='iwinfo' +_iw='iw' + +# main loop +while true ; do + for _phy in /sys/kernel/debug/ieee80211/phy*; do + for _netdev in $_phy/netdev:* ; do + # single cat call + _metric_group="$(basename ${_phy})-$(basename ${_netdev})" + + for _metric in "num_buffered_multicast" "dtim_count" "num_sta_ps" "num_mcast_sta" "txpower"; do + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}/gauge-${_metric} interval=${_PERIOD} N:$(cat ${_netdev}/${_metric} 2>/dev/null)" + done + + _stations=`ls -1 ${_netdev}/stations/ | wc -l` + _vht_stations=`grep -r 'VHT supported' ${_netdev}/stations/*/vht_capa 2>/dev/null | wc -l` + _ht_stations=`grep -r 'ht supported' ${_netdev}/stations/*/ht_capa 2>/dev/null | wc -l` + + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}/gauge-stations interval=${_PERIOD} N:${_stations}" + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}/gauge-ht_stations interval=${_PERIOD} N:${_ht_stations}" + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}/gauge-vht_stations interval=${_PERIOD} N:${_vht_stations}" + + if [ $_stations -gt 0 ]; then + for _metric in "tx_retry_count" "tx_retry_failed" "rx_dropped" "rx_duplicates" "current_tx_rate" "beacon_loss_count" "last_signal" "connected_time" "inactive_ms" "num_ps_buf_frames"; do + _avg_value=`awk 2>/dev/null '{sum+=$1} END { print sum/NR}' ${_netdev}/stations/*/${_metric}` + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}/gauge-avg_${_metric} interval=${_PERIOD} N:${_avg_value}" + done + fi + + if [ -d "${_phy}/ath9k" ]; then + _interface=$(echo ${_netdev} | sed 's/.*\://') + ${_iw} dev ${_interface} survey dump | grep -A 5 'in use' > /tmp/${_interface}.survey + cat /tmp/${_interface}.survey | grep 'channel' | sed 's/ ms$//' | sed $'s/\t//g' | \ + sed 's/ /_/g' | awk -vhostname="${_HOSTNAME}" \ + -vplugin="${_PLUGIN}" \ + -vmetric_group="${_metric_group}-ath9k-survey" \ + -vinterval="${_PERIOD}" \ + -F : \ + '{printf "PUTVAL %s/%s-%s/counter-%s interval=%s N:%s\n", hostname, plugin, metric_group, tolower($1), interval, $2}' + elif [ -d "${_phy}/ath10k" ]; then + _interface=$(echo ${_netdev} | sed 's/.*\://') + _interface=$(echo ${_netdev} | sed 's/.*\://') + ${_iw} dev ${_interface} survey dump | grep -A 3 'in use' > /tmp/${_interface}.survey + cat /tmp/${_interface}.survey | grep 'channel' | sed 's/ ms$//' | sed $'s/\t//g' | \ + sed 's/ /_/g' | awk -vhostname="${_HOSTNAME}" \ + -vplugin="${_PLUGIN}" \ + -vmetric_group="${_metric_group}-ath10k-survey" \ + -vinterval="${_PERIOD}" \ + -F : \ + '{printf "PUTVAL %s/%s-%s/gauge-%s interval=%s N:%s\n", hostname, plugin, metric_group, tolower($1), interval, $2}' + fi + + done + + _metric_group="$(basename ${_phy})" + + if [ -d "${_phy}/ath9k" ]; then + cat $_phy/ath9k/recv | \ + sed 's/^ *\(.*\w\) *: *\([^ ]\)*$/\1:\2/g' | \ + sed 's/ /_/' | awk -vhostname="${_HOSTNAME}" \ + -vplugin="${_PLUGIN}" \ + -vmetric_group="${_metric_group}-ath9k-recv" \ + -vinterval="${_PERIOD}" \ + -F : \ + '{printf "PUTVAL %s/%s-%s/counter-%s interval=%s N:%s\n", hostname, plugin, metric_group, tolower($1), interval, $2}' + + cat $_phy/ath9k/phy_err | \ + sed 's/^ *\(.*\w\) *: *\([^ ]\)*$/\1:\2/g' | \ + sed 's/ /_/' | awk -vhostname="${_HOSTNAME}" \ + -vplugin="${_PLUGIN}" \ + -vmetric_group="${_metric_group}-ath9k-phy_err" \ + -vinterval="${_PERIOD}" \ + -F : \ + '{printf "PUTVAL %s/%s-%s/counter-%s interval=%s N:%s\n", hostname, plugin, metric_group, tolower($1), interval, $2}' + + cat $_phy/ath9k/dfs_stats | grep '^ ' | \ + sed 's/^ *\(.*\w\) *: *\([^ ]\)*$/\1:\2/g' | \ + sed 's/ /_/g' | \ + sed 's/\.//g' | awk -vhostname="${_HOSTNAME}" \ + -vplugin="${_PLUGIN}" \ + -vmetric_group="${_metric_group}-ath9k-dfs_stats" \ + -vinterval="${_PERIOD}" \ + -F : \ + '{printf "PUTVAL %s/%s-%s/counter-%s interval=%s N:%s\n", hostname, plugin, metric_group, tolower($1), interval, $2}' + + for _queue in $_phy/ath9k/qlen*; do + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}-ath9k/gauge-$(basename $_queue) interval=${_PERIOD} N:$(cat ${_queue})" + done + + elif [ -d "${_phy}/ath10k" ]; then + cat $_phy/ath10k/dfs_stats | grep ':.*[0-9]$' | \ + sed 's/^ *\(.*\w\) *: *\([^ ]\)*$/\1:\2/g' | \ + sed 's/ /_/g' | \ + sed 's/\.//g' | awk -vhostname="${_HOSTNAME}" \ + -vplugin="${_PLUGIN}" \ + -vmetric_group="${_metric_group}-ath10k-dfs_stats" \ + -vinterval="${_PERIOD}" \ + -F : \ + '{printf "PUTVAL %s/%s-%s/counter-%s interval=%s N:%s\n", hostname, plugin, metric_group, tolower($1), interval, $2}' + fi + + for _metric in ${_phy}/statistics/* ; do + _metric_name="$(basename ${_metric})" + echo -e "PUTVAL ${_HOSTNAME}/${_PLUGIN}-${_metric_group}-statistics/counter-$(echo ${_metric_name}) N:$(cat ${_metric} 2>/dev/null)" + done + + done + + sleep ${_PERIOD} +done