ap.chart.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # shellcheck shell=bash
  2. # no need for shebang - this file is loaded from charts.d.plugin
  3. # SPDX-License-Identifier: GPL-3.0-or-later
  4. # netdata
  5. # real-time performance and health monitoring, done right!
  6. # (C) 2016 Costa Tsaousis <costa@tsaousis.gr>
  7. #
  8. # _update_every is a special variable - it holds the number of seconds
  9. # between the calls of the _update() function
  10. ap_update_every=
  11. ap_priority=6900
  12. declare -A ap_devs=()
  13. # _check is called once, to find out if this chart should be enabled or not
  14. ap_check() {
  15. require_cmd iw || return 1
  16. local ev
  17. ev=$(run iw dev | awk '
  18. BEGIN {
  19. i = "";
  20. ssid = "";
  21. ap = 0;
  22. }
  23. /^[ \t]+Interface / {
  24. if( ap == 1 ) {
  25. print "ap_devs[" i "]=\"" ssid "\""
  26. }
  27. i = $2;
  28. ssid = "";
  29. ap = 0;
  30. }
  31. /^[ \t]+ssid / { ssid = $2; }
  32. /^[ \t]+type AP$/ { ap = 1; }
  33. END {
  34. if( ap == 1 ) {
  35. print "ap_devs[" i "]=\"" ssid "\""
  36. }
  37. }
  38. ')
  39. eval "${ev}"
  40. # this should return:
  41. # - 0 to enable the chart
  42. # - 1 to disable the chart
  43. [ ${#ap_devs[@]} -gt 0 ] && return 0
  44. error "no devices found in AP mode, with 'iw dev'"
  45. return 1
  46. }
  47. # _create is called once, to create the charts
  48. ap_create() {
  49. local ssid dev
  50. for dev in "${!ap_devs[@]}"; do
  51. ssid="${ap_devs[${dev}]}"
  52. # create the chart with 3 dimensions
  53. cat << EOF
  54. CHART ap_clients.${dev} '' "Connected clients to ${ssid} on ${dev}" "clients" ${dev} ap.clients line $((ap_priority + 1)) $ap_update_every '' '' 'ap'
  55. DIMENSION clients '' absolute 1 1
  56. CHART ap_bandwidth.${dev} '' "Bandwidth for ${ssid} on ${dev}" "kilobits/s" ${dev} ap.net area $((ap_priority + 2)) $ap_update_every '' '' 'ap'
  57. DIMENSION received '' incremental 8 1024
  58. DIMENSION sent '' incremental -8 1024
  59. CHART ap_packets.${dev} '' "Packets for ${ssid} on ${dev}" "packets/s" ${dev} ap.packets line $((ap_priority + 3)) $ap_update_every '' '' 'ap'
  60. DIMENSION received '' incremental 1 1
  61. DIMENSION sent '' incremental -1 1
  62. CHART ap_issues.${dev} '' "Transmit Issues for ${ssid} on ${dev}" "issues/s" ${dev} ap.issues line $((ap_priority + 4)) $ap_update_every '' '' 'ap'
  63. DIMENSION retries 'tx retries' incremental 1 1
  64. DIMENSION failures 'tx failures' incremental -1 1
  65. CHART ap_signal.${dev} '' "Average Signal for ${ssid} on ${dev}" "dBm" ${dev} ap.signal line $((ap_priority + 5)) $ap_update_every '' '' 'ap'
  66. DIMENSION signal 'average signal' absolute 1 1000
  67. CHART ap_bitrate.${dev} '' "Bitrate for ${ssid} on ${dev}" "Mbps" ${dev} ap.bitrate line $((ap_priority + 6)) $ap_update_every '' '' 'ap'
  68. DIMENSION receive '' absolute 1 1000
  69. DIMENSION transmit '' absolute -1 1000
  70. DIMENSION expected 'expected throughput' absolute 1 1000
  71. EOF
  72. done
  73. return 0
  74. }
  75. # _update is called continuously, to collect the values
  76. ap_update() {
  77. # the first argument to this function is the microseconds since last update
  78. # pass this parameter to the BEGIN statement (see below).
  79. # do all the work to collect / calculate the values
  80. # for each dimension
  81. # remember: KEEP IT SIMPLE AND SHORT
  82. for dev in "${!ap_devs[@]}"; do
  83. echo
  84. echo "DEVICE ${dev}"
  85. iw "${dev}" station dump
  86. done | awk '
  87. function zero_data() {
  88. dev = "";
  89. c = 0;
  90. rb = 0;
  91. tb = 0;
  92. rp = 0;
  93. tp = 0;
  94. tr = 0;
  95. tf = 0;
  96. tt = 0;
  97. rt = 0;
  98. s = 0;
  99. g = 0;
  100. e = 0;
  101. }
  102. function print_device() {
  103. if(dev != "" && length(dev) > 0) {
  104. print "BEGIN ap_clients." dev;
  105. print "SET clients = " c;
  106. print "END";
  107. print "BEGIN ap_bandwidth." dev;
  108. print "SET received = " rb;
  109. print "SET sent = " tb;
  110. print "END";
  111. print "BEGIN ap_packets." dev;
  112. print "SET received = " rp;
  113. print "SET sent = " tp;
  114. print "END";
  115. print "BEGIN ap_issues." dev;
  116. print "SET retries = " tr;
  117. print "SET failures = " tf;
  118. print "END";
  119. if( c == 0 ) c = 1;
  120. print "BEGIN ap_signal." dev;
  121. print "SET signal = " int(s / c);
  122. print "END";
  123. print "BEGIN ap_bitrate." dev;
  124. print "SET receive = " int(rt / c);
  125. print "SET transmit = " int(tt / c);
  126. print "SET expected = " int(e / c);
  127. print "END";
  128. }
  129. zero_data();
  130. }
  131. BEGIN {
  132. zero_data();
  133. }
  134. /^DEVICE / {
  135. print_device();
  136. dev = $2;
  137. }
  138. /^Station/ { c++; }
  139. /^[ \t]+rx bytes:/ { rb += $3; }
  140. /^[ \t]+tx bytes:/ { tb += $3; }
  141. /^[ \t]+rx packets:/ { rp += $3; }
  142. /^[ \t]+tx packets:/ { tp += $3; }
  143. /^[ \t]+tx retries:/ { tr += $3; }
  144. /^[ \t]+tx failed:/ { tf += $3; }
  145. /^[ \t]+signal:/ { x = $2; s += x * 1000; }
  146. /^[ \t]+rx bitrate:/ { x = $3; rt += x * 1000; }
  147. /^[ \t]+tx bitrate:/ { x = $3; tt += x * 1000; }
  148. /^[ \t]+expected throughput:(.*)Mbps/ {
  149. x=$3;
  150. sub(/Mbps/, "", x);
  151. e += x * 1000;
  152. }
  153. END {
  154. print_device();
  155. }
  156. '
  157. return 0
  158. }