X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netdata.git;a=blobdiff_plain;f=plugins.d%2Ftc-qos-helper.sh;h=074fece9a5e3d571618a69a0c3942ac7b11cd0ea;hp=7b4739815481d2097bb1573500b8f92e8757a338;hb=HEAD;hpb=3252f884c69f04ae97aaa7d8f7e17c18eefcbfa6 diff --git a/plugins.d/tc-qos-helper.sh b/plugins.d/tc-qos-helper.sh index 7b473981..074fece9 100755 --- a/plugins.d/tc-qos-helper.sh +++ b/plugins.d/tc-qos-helper.sh @@ -1,107 +1,302 @@ -#!/bin/bash +#!/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") -# default time function -now_ms= -current_time_ms() { - now_ms="$(date +'%s')000" + 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 || 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 + +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 + sleep $1 } # if found and included, this file overwrites loopsleepms() # with a high resolution timer function for precise looping. -. "$NETDATA_PLUGINS_DIR/loopsleepms.sh.inc" +. "${plugins_dir}/loopsleepms.sh.inc" -# check if we have a valid number for interval -t=$1 -sleep_time=$((t)) -[ $((sleep_time)) -lt 1 ] && $NETDATA_UPDATE_EVERY -[ $((sleep_time)) -lt 1 ] && sleep_time=1 - -tc_cmd="$(which tc)" -if [ -z "$tc_cmd" ] - then - echo >&2 "tc: Cannot find a 'tc' command in this system." - exit 1 + +# ----------------------------------------------------------------------------- +# final checks we can run + +if [ -z "${tc}" -o ! -x "${tc}" ] + then + 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_cls() { + [ "${tc_show}" = "qdisc" ] && return 1 + + local x="${1}" + + 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