# shellcheck shell=bash # no need for shebang - this file is loaded from charts.d.plugin # SPDX-License-Identifier: GPL-3.0-or-later # netdata # real-time performance and health monitoring, done right! # (C) 2016 Costa Tsaousis # # _update_every is a special variable - it holds the number of seconds # between the calls of the _update() function ap_update_every= ap_priority=6900 declare -A ap_devs=() # _check is called once, to find out if this chart should be enabled or not ap_check() { require_cmd iw || return 1 local ev ev=$(run iw dev | awk ' BEGIN { i = ""; ssid = ""; ap = 0; } /^[ \t]+Interface / { if( ap == 1 ) { print "ap_devs[" i "]=\"" ssid "\"" } i = $2; ssid = ""; ap = 0; } /^[ \t]+ssid / { ssid = $2; } /^[ \t]+type AP$/ { ap = 1; } END { if( ap == 1 ) { print "ap_devs[" i "]=\"" ssid "\"" } } ') eval "${ev}" # this should return: # - 0 to enable the chart # - 1 to disable the chart [ ${#ap_devs[@]} -gt 0 ] && return 0 error "no devices found in AP mode, with 'iw dev'" return 1 } # _create is called once, to create the charts ap_create() { local ssid dev for dev in "${!ap_devs[@]}"; do ssid="${ap_devs[${dev}]}" # create the chart with 3 dimensions cat << EOF CHART ap_clients.${dev} '' "Connected clients to ${ssid} on ${dev}" "clients" ${dev} ap.clients line $((ap_priority + 1)) $ap_update_every '' '' 'ap' DIMENSION clients '' absolute 1 1 CHART ap_bandwidth.${dev} '' "Bandwidth for ${ssid} on ${dev}" "kilobits/s" ${dev} ap.net area $((ap_priority + 2)) $ap_update_every '' '' 'ap' DIMENSION received '' incremental 8 1024 DIMENSION sent '' incremental -8 1024 CHART ap_packets.${dev} '' "Packets for ${ssid} on ${dev}" "packets/s" ${dev} ap.packets line $((ap_priority + 3)) $ap_update_every '' '' 'ap' DIMENSION received '' incremental 1 1 DIMENSION sent '' incremental -1 1 CHART ap_issues.${dev} '' "Transmit Issues for ${ssid} on ${dev}" "issues/s" ${dev} ap.issues line $((ap_priority + 4)) $ap_update_every '' '' 'ap' DIMENSION retries 'tx retries' incremental 1 1 DIMENSION failures 'tx failures' incremental -1 1 CHART ap_signal.${dev} '' "Average Signal for ${ssid} on ${dev}" "dBm" ${dev} ap.signal line $((ap_priority + 5)) $ap_update_every '' '' 'ap' DIMENSION signal 'average signal' absolute 1 1000 CHART ap_bitrate.${dev} '' "Bitrate for ${ssid} on ${dev}" "Mbps" ${dev} ap.bitrate line $((ap_priority + 6)) $ap_update_every '' '' 'ap' DIMENSION receive '' absolute 1 1000 DIMENSION transmit '' absolute -1 1000 DIMENSION expected 'expected throughput' absolute 1 1000 EOF done return 0 } # _update is called continuously, to collect the values ap_update() { # the first argument to this function is the microseconds since last update # pass this parameter to the BEGIN statement (see below). # do all the work to collect / calculate the values # for each dimension # remember: KEEP IT SIMPLE AND SHORT for dev in "${!ap_devs[@]}"; do echo echo "DEVICE ${dev}" iw "${dev}" station dump done | awk ' function zero_data() { dev = ""; c = 0; rb = 0; tb = 0; rp = 0; tp = 0; tr = 0; tf = 0; tt = 0; rt = 0; s = 0; g = 0; e = 0; } function print_device() { if(dev != "" && length(dev) > 0) { print "BEGIN ap_clients." dev; print "SET clients = " c; print "END"; print "BEGIN ap_bandwidth." dev; print "SET received = " rb; print "SET sent = " tb; print "END"; print "BEGIN ap_packets." dev; print "SET received = " rp; print "SET sent = " tp; print "END"; print "BEGIN ap_issues." dev; print "SET retries = " tr; print "SET failures = " tf; print "END"; if( c == 0 ) c = 1; print "BEGIN ap_signal." dev; print "SET signal = " int(s / c); print "END"; print "BEGIN ap_bitrate." dev; print "SET receive = " int(rt / c); print "SET transmit = " int(tt / c); print "SET expected = " int(e / c); print "END"; } zero_data(); } BEGIN { zero_data(); } /^DEVICE / { print_device(); dev = $2; } /^Station/ { c++; } /^[ \t]+rx bytes:/ { rb += $3; } /^[ \t]+tx bytes:/ { tb += $3; } /^[ \t]+rx packets:/ { rp += $3; } /^[ \t]+tx packets:/ { tp += $3; } /^[ \t]+tx retries:/ { tr += $3; } /^[ \t]+tx failed:/ { tf += $3; } /^[ \t]+signal:/ { x = $2; s += x * 1000; } /^[ \t]+rx bitrate:/ { x = $3; rt += x * 1000; } /^[ \t]+tx bitrate:/ { x = $3; tt += x * 1000; } /^[ \t]+expected throughput:(.*)Mbps/ { x=$3; sub(/Mbps/, "", x); e += x * 1000; } END { print_device(); } ' return 0 }