You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.0 KiB

  1. #!/bin/sh
  2. . /usr/share/libubox/jshn.sh
  3. HOSTNAME="${COLLECTD_HOSTNAME:-localhost}"
  4. INTERVAL="${COLLECTD_INTERVAL:-60}"
  5. handle_cake() {
  6. local ifc ifr tin i
  7. ifc="$1"
  8. ifr="${ifc//[!0-9A-Za-z]/_}"
  9. # Overall
  10. json_get_vars bytes packets drops backlog qlen
  11. # Options
  12. json_select options
  13. json_get_vars bandwidth diffserv
  14. json_select ".."
  15. echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_bytes\" interval=$INTERVAL N:$bytes"
  16. echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_drops\" interval=$INTERVAL N:$drops"
  17. echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_backlog\" interval=$INTERVAL N:$backlog"
  18. # ash doesn't have arrays so prepare to get a little creative
  19. case "$diffserv" in
  20. diffserv3 | diffserv4) tns="BKBEVIVO"
  21. ;;
  22. *) tns="T0T1T2T3T4T5T6T7"
  23. ;;
  24. esac
  25. # Tins
  26. # Flows & delays indicate the state as of the last packet that flowed through, so they appear to get stuck.
  27. # Discard the results from a stuck tin.
  28. json_get_keys tins tins
  29. json_select tins
  30. i=0
  31. for tin in $tins; do
  32. json_select "$tin"
  33. json_get_vars threshold_rate sent_bytes sent_packets backlog_bytes target_us peak_delay_us avg_delay_us base_delay_us drops ecn_mark ack_drops sparse_flows bulk_flows unresponsive_flows
  34. eval osp="\$osp${ifr}t${i}"
  35. if [ "$osp" ] && [ "$osp" -eq "$sent_packets" ] ; then
  36. peak_delay_us=0; avg_delay_us=0; base_delay_us=0
  37. sparse_flows=0; bulk_flows=0; unresponsive_flows=0
  38. else
  39. eval "osp${ifr}t${i}=$sent_packets"
  40. fi
  41. tn=${tns:$((i<<1)):2}
  42. echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_bytes-$tn\" interval=$INTERVAL N:$sent_bytes"
  43. echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_thres-$tn\" interval=$INTERVAL N:$threshold_rate"
  44. echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_drops-$tn\" interval=$INTERVAL N:$drops:$ecn_mark:$ack_drops"
  45. echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_backlog-$tn\" interval=$INTERVAL N:$backlog_bytes"
  46. echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_flows-$tn\" interval=$INTERVAL N:$sparse_flows:$bulk_flows:$unresponsive_flows"
  47. echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_latencyus-$tn\" interval=$INTERVAL N:$target_us:$peak_delay_us:$avg_delay_us:$base_delay_us"
  48. json_select ..
  49. i=$((i+1))
  50. done
  51. json_select ..
  52. }
  53. handle_mq() {
  54. ifc="$1"
  55. # Overall
  56. json_get_vars bytes drops backlog
  57. echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_bytes\" interval=$INTERVAL N:$bytes"
  58. echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_drops\" interval=$INTERVAL N:$drops"
  59. echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_backlog\" interval=$INTERVAL N:$backlog"
  60. }
  61. process_qdisc() {
  62. local ifc jsn
  63. ifc="$1"
  64. jsn=$(tc -s -j qdisc show dev "$ifc") || return
  65. # strip leading & trailing []
  66. jsn="${jsn#[}" ; jsn="${jsn%]}"
  67. json_load "${jsn}"
  68. json_get_var qdisc kind
  69. case "$qdisc" in
  70. cake) handle_cake "$ifc"
  71. ;;
  72. mq) handle_mq "$ifc"
  73. ;;
  74. *) echo "Unknown qdisc type '$qdisc' on interface '$ifc'" 1>&2
  75. ;;
  76. esac
  77. json_cleanup
  78. }
  79. # while not orphaned
  80. while [ $(awk '$1 ~ "^PPid:" {print $2;exit}' /proc/$$/status) -ne 1 ] ; do
  81. for ifc in "$@" ; do
  82. process_qdisc "$ifc"
  83. done
  84. sleep "${INTERVAL%%.*}"
  85. done