X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=plugins.d%2Ftc-qos-helper.sh;h=074fece9a5e3d571618a69a0c3942ac7b11cd0ea;hb=315c388516a4750eab4b64d38f8bddd58b4e5aa4;hp=bff5217d28a449e81d96ec0fb55e34a14631045d;hpb=6911559e3af6b73b7be8fb1171b4645121ebe1ab;p=netdata.git diff --git a/plugins.d/tc-qos-helper.sh b/plugins.d/tc-qos-helper.sh index bff5217d..074fece9 100755 --- a/plugins.d/tc-qos-helper.sh +++ b/plugins.d/tc-qos-helper.sh @@ -1,42 +1,159 @@ #!/usr/bin/env bash +# netdata +# real-time performance and health monitoring, done right! +# (C) 2016 Costa Tsaousis +# GPL v3+ +# +# This script is a helper to allow netdata collect tc data. +# tc output parsing has been implemented in C, inside netdata +# This script allows setting names to dimensions. + export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin" +export LC_ALL=C + + +# ----------------------------------------------------------------------------- +# find /var/run/fireqos + +# the default +fireqos_run_dir="/var/run/fireqos" + +function realdir { + local r="$1" + local t=$(readlink "$r") + + while [ "$t" ] + do + r=$(cd $(dirname "$r") && cd $(dirname "$t") && pwd -P)/$(basename "$t") + t=$(readlink "$r") + done + + dirname "$r" +} + +if [ ! -d "${fireqos_run_dir}" ] + then + + # the fireqos executable - we will use it to find its config + fireqos="$(which fireqos 2>/dev/null || command -v fireqos 2>/dev/null)" + + if [ ! -z "${fireqos}" ] + then + + fireqos_exec_dir="$(realdir ${fireqos})" + + if [ ! -z "${fireqos_exec_dir}" -a "${fireqos_exec_dir}" != "." -a -f "${fireqos_exec_dir}/install.config" ] + then + + LOCALSTATEDIR= + source "${fireqos_exec_dir}/install.config" + + if [ -d "${LOCALSTATEDIR}/run/fireqos" ] + then + fireqos_run_dir="${LOCALSTATEDIR}/run/fireqos" + fi + fi + fi +fi + +# ----------------------------------------------------------------------------- +# logging functions PROGRAM_FILE="$0" PROGRAM_NAME="$(basename $0)" PROGRAM_NAME="${PROGRAM_NAME/.plugin}" +logdate() { + date "+%Y-%m-%d %H:%M:%S" +} + +log() { + local status="${1}" + shift + + echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}" + +} + +warning() { + log WARNING "${@}" +} + +error() { + log ERROR "${@}" +} + +info() { + log INFO "${@}" +} + +fatal() { + log FATAL "${@}" + exit 1 +} + +debug=0 +debug() { + [ $debug -eq 1 ] && log DEBUG "${@}" +} + + +# ----------------------------------------------------------------------------- + plugins_dir="${NETDATA_PLUGINS_DIR}" [ -z "$plugins_dir" ] && plugins_dir="$( dirname $PROGRAM_FILE )" config_dir=${NETDATA_CONFIG_DIR-/etc/netdata} -tc="$(which tc 2>/dev/null)" -fireqos_run_dir="/var/run/fireqos" +tc="$(which tc 2>/dev/null || command -v tc 2>/dev/null)" + + +# ----------------------------------------------------------------------------- +# user configuration + +# time in seconds to refresh QoS class/qdisc names qos_get_class_names_every=120 + +# time in seconds to exit - netdata will restart the script qos_exit_every=3600 +# what to use? classes or qdiscs? +tc_show="qdisc" # can also be "class" + + +# ----------------------------------------------------------------------------- # check if we have a valid number for interval + t=${1} update_every=$((t)) [ $((update_every)) -lt 1 ] && update_every=${NETDATA_UPDATE_EVERY} [ $((update_every)) -lt 1 ] && update_every=1 + +# ----------------------------------------------------------------------------- # allow the user to override our defaults + if [ -f "${config_dir}/tc-qos-helper.conf" ] then source "${config_dir}/tc-qos-helper.conf" fi -# default time function -now_ms= -current_time_ms() { - now_ms="$(date +'%s')000" -} +case "${tc_show}" in + qdisc|class) + ;; + + *) + error "tc_show variable can be either 'qdisc' or 'class' but is set to '${tc_show}'. Assuming it is 'qdisc'." + tc_show="qdisc" + ;; +esac + +# ----------------------------------------------------------------------------- # default sleep function + LOOPSLEEPMS_LASTWORK=0 loopsleepms() { - [ "$1" = "tellwork" ] && shift sleep $1 } @@ -44,27 +161,51 @@ loopsleepms() { # with a high resolution timer function for precise looping. . "${plugins_dir}/loopsleepms.sh.inc" + +# ----------------------------------------------------------------------------- +# final checks we can run + if [ -z "${tc}" -o ! -x "${tc}" ] then - echo >&2 "${PROGRAM_NAME}: Cannot find command 'tc' in this system." - exit 1 + fatal "cannot find command 'tc' in this system." fi -devices= +tc_devices= fix_names= +# ----------------------------------------------------------------------------- + setclassname() { - echo "SETCLASSNAME $3 $2" + if [ "${tc_show}" = "qdisc" ] + then + echo "SETCLASSNAME $4 $2" + else + echo "SETCLASSNAME $3 $2" + fi } -show_tc() { - local x="${1}" interface_dev interface_classes interface_classes_monitor +show_tc_cls() { + [ "${tc_show}" = "qdisc" ] && return 1 - echo "BEGIN ${x}" - ${tc} -s class show dev ${x} + local x="${1}" - # check FireQOS names for classes - if [ ! -z "${fix_names}" -a -f "${fireqos_run_dir}/ifaces/${x}" ] + if [ -f /etc/iproute2/tc_cls ] + then + local classid name rest + while read classid name rest + do + [ -z "${classid}" -o -z "${name}" -o "${classid}" = "#" -o "${name}" = "#" -o "${classid:0:1}" = "#" -o "${name:0:1}" = "#" ] && continue + setclassname "" "${name}" "${classid}" + done