- #!/bin/sh
-
- . /usr/share/libubox/jshn.sh
-
- HOSTNAME="${COLLECTD_HOSTNAME:-localhost}"
- INTERVAL="${COLLECTD_INTERVAL:-60}"
-
- handle_cake() {
- local ifc ifr tin i
-
- ifc="$1"
- ifr="${ifc//[!0-9A-Za-z]/_}"
-
- # Overall
- json_get_vars bytes packets drops backlog qlen
-
- # Options
- json_select options
- json_get_vars bandwidth diffserv
- json_select ".."
-
- echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_bytes\" interval=$INTERVAL N:$bytes"
- echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_drops\" interval=$INTERVAL N:$drops"
- echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_backlog\" interval=$INTERVAL N:$backlog"
-
- # ash doesn't have arrays so prepare to get a little creative
- case "$diffserv" in
- diffserv3 | diffserv4) tns="BKBEVIVO"
- ;;
- *) tns="T0T1T2T3T4T5T6T7"
- ;;
- esac
-
- # Tins
- # Flows & delays indicate the state as of the last packet that flowed through, so they appear to get stuck.
- # Discard the results from a stuck tin.
- json_get_keys tins tins
- json_select tins
- i=0
- for tin in $tins; do
- json_select "$tin"
- 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
-
- eval osp="\$osp${ifr}t${i}"
- if [ "$osp" ] && [ "$osp" -eq "$sent_packets" ] ; then
- peak_delay_us=0; avg_delay_us=0; base_delay_us=0
- sparse_flows=0; bulk_flows=0; unresponsive_flows=0
- else
- eval "osp${ifr}t${i}=$sent_packets"
- fi
-
- tn=${tns:$((i<<1)):2}
-
- echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_bytes-$tn\" interval=$INTERVAL N:$sent_bytes"
- echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_thres-$tn\" interval=$INTERVAL N:$threshold_rate"
- echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_drops-$tn\" interval=$INTERVAL N:$drops:$ecn_mark:$ack_drops"
- echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_backlog-$tn\" interval=$INTERVAL N:$backlog_bytes"
- echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_flows-$tn\" interval=$INTERVAL N:$sparse_flows:$bulk_flows:$unresponsive_flows"
- echo "PUTVAL \"$HOSTNAME/sqmcake-$ifc/qdisct_latencyus-$tn\" interval=$INTERVAL N:$target_us:$peak_delay_us:$avg_delay_us:$base_delay_us"
-
- json_select ..
- i=$((i+1))
- done
- json_select ..
- }
-
- handle_mq() {
- ifc="$1"
-
- # Overall
- json_get_vars bytes drops backlog
-
- echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_bytes\" interval=$INTERVAL N:$bytes"
- echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_drops\" interval=$INTERVAL N:$drops"
- echo "PUTVAL \"$HOSTNAME/sqm-$ifc/qdisc_backlog\" interval=$INTERVAL N:$backlog"
- }
-
- process_qdisc() {
- local ifc jsn
-
- ifc="$1"
- jsn=$(tc -s -j qdisc show dev "$ifc") || return
-
- # strip leading & trailing []
- jsn="${jsn#[}" ; jsn="${jsn%]}"
-
- json_load "${jsn}"
- json_get_var qdisc kind
-
- case "$qdisc" in
- cake) handle_cake "$ifc"
- ;;
- mq) handle_mq "$ifc"
- ;;
-
- *) echo "Unknown qdisc type '$qdisc' on interface '$ifc'" 1>&2
- ;;
- esac
- json_cleanup
- }
-
- # while not orphaned
- while [ $(awk '$1 ~ "^PPid:" {print $2;exit}' /proc/$$/status) -ne 1 ] ; do
- for ifc in "$@" ; do
- process_qdisc "$ifc"
- done
- sleep "${INTERVAL%%.*}"
- done
|