diff options
author | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2016-09-12 23:47:25 +0300 |
---|---|---|
committer | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2016-09-12 23:47:25 +0300 |
commit | 4bd921279f0e2b9fe30de07529af87787bf5cd65 (patch) | |
tree | 47b435db08213390366a87b63388ba79dca52dd6 | |
parent | 76e257a0d03d34c507c51e46604eca2f0a54ee36 (diff) |
charts.d.plugin and tc-qos-helper.sh optimization to avoid frequent forks due to date and sleep
-rwxr-xr-x | charts.d/example.chart.sh | 4 | ||||
-rwxr-xr-x | plugins.d/charts.d.plugin | 99 | ||||
-rw-r--r-- | plugins.d/loopsleepms.sh.inc | 98 | ||||
-rwxr-xr-x | plugins.d/tc-qos-helper.sh | 7 |
4 files changed, 129 insertions, 79 deletions
diff --git a/charts.d/example.chart.sh b/charts.d/example.chart.sh index 1f020dee27..93f1cf4fdd 100755 --- a/charts.d/example.chart.sh +++ b/charts.d/example.chart.sh @@ -48,8 +48,8 @@ example_get() { else example_count=$((1 + (RANDOM * 5 / 32767) )) - [ $example_last -gt 16383 -a $example_value4 -gt 16383 ] && example_value4=$((value4 - 16383)) - [ $example_last -le 16383 -a $example_value4 -lt 16383 ] && example_value4=$((value4 + 16383)) + [ $example_last -gt 16383 -a $example_value4 -gt 16383 ] && example_value4=$((example_value4 - 16383)) + [ $example_last -le 16383 -a $example_value4 -lt 16383 ] && example_value4=$((example_value4 + 16383)) fi example_last=$example_value4 diff --git a/plugins.d/charts.d.plugin b/plugins.d/charts.d.plugin index 9aaadc1685..df9998ecec 100755 --- a/plugins.d/charts.d.plugin +++ b/plugins.d/charts.d.plugin @@ -48,10 +48,6 @@ require_cmd awk || exit 1 # insternal defaults # netdata exposes a few environment variables for us -pause_method="sleep" # use either "suspend" or "sleep" - # DO NOT USE SUSPEND - LINUX WILL SUSPEND NETDATA TOO - # THE WHOLE PROCESS GROUP - NOT JUST THE SHELL - pluginsd="${NETDATA_PLUGINS_DIR}" [ -z "$pluginsd" ] && pluginsd="$( dirname $PROGRAM_FILE )" @@ -154,6 +150,24 @@ done # ----------------------------------------------------------------------------- +# loop control + +# default sleep function +LOOPSLEEPMS_HIGHRES=0 +now_ms= +current_time_ms_default() { + now_ms="$(date +'%s')000" +} +current_time_ms="current_time_ms_default" +current_time_ms_accuracy=1 +mysleep="sleep" + +# if found and included, this file overwrites loopsleepms() +# and current_time_ms() with a high resolution timer function +# for precise looping. +. "$pluginsd/loopsleepms.sh.inc" + +# ----------------------------------------------------------------------------- # load my configuration if [ -f "$myconfig" ] @@ -172,13 +186,6 @@ else echo >&2 "$PROGRAM_NAME: configuration file '$myconfig' not found. Using defaults." fi -if [ "$pause_method" = "suspend" ] -then - # enable bash job control - # this is required for suspend to work - set -m -fi - # we check for the timeout command, after we load our # configuration, so that the user may overwrite the # timeout command we use, providing a function that @@ -205,27 +212,6 @@ fi # ----------------------------------------------------------------------------- -# loop control - -# default sleep function -LOOPSLEEPMS_HIGHRES=0 -loopsleepms() { - [ "$1" = "tellwork" ] && shift - sleep $1 -} - -now_ms= -current_time_ms() { - now_ms="$(date +'%s')000" -} - -# if found and included, this file overwrites loopsleepms() -# and current_time_ms() with a high resolution timer function -# for precise looping. -. "$pluginsd/loopsleepms.sh.inc" - - -# ----------------------------------------------------------------------------- # library functions fixid() { @@ -537,7 +523,7 @@ global_update() { next_ms x seconds millis # return the current time in ms in $now_ms - current_time_ms + ${current_time_ms} exit_at=$(( now_ms + (restart_timeout * 1000) )) @@ -562,16 +548,16 @@ global_update() { next_charts=() # return the current time in ms in $now_ms - current_time_ms + ${current_time_ms} for chart in "${now_charts[@]}" do - # echo >&2 "DEBUG: chart: $chart last: ${charts_last_update[$chart]}, next: ${charts_next_update[$chart]}, now: ${now_ms}" + #echo >&2 " DEBUG: chart: $chart last: ${charts_last_update[$chart]}, next: ${charts_next_update[$chart]}, now: ${now_ms}" if [ ${now_ms} -ge ${charts_next_update[$chart]} ] then last_ms=${charts_last_update[$chart]} dt=$(( (now_ms - last_ms) )) - # echo >&2 "DEBUG: chart: $chart last: ${charts_last_update[$chart]}, next: ${charts_next_update[$chart]}, now: ${now_ms}, dt: ${dt}" + #echo >&2 " DEBUG: chart: $chart last: ${charts_last_update[$chart]}, next: ${charts_next_update[$chart]}, now: ${now_ms}, dt: ${dt}" charts_last_update[$chart]=${now_ms} @@ -590,11 +576,12 @@ global_update() { fi exec_start_ms=$now_ms + #echo >&2 " EXEC: $chart$charts_update $dt" $chart$charts_update $dt ret=$? # return the current time in ms in $now_ms - current_time_ms; exec_end_ms=$now_ms + ${current_time_ms}; exec_end_ms=$now_ms echo "BEGIN netdata.plugin_chartsd_$chart $dt" echo "SET run_time = $(( exec_end_ms - exec_start_ms ))" @@ -620,27 +607,29 @@ global_update() { fi done - if [ "$pause_method" = "suspend" ] - then - echo "STOPPING_WAKE_ME_UP_PLEASE" - suspend || ( echo >&2 "$PROGRAM_NAME: suspend returned error $?, falling back to sleep."; loopsleepms $debug_time $update_every $time_divisor) - else - # wait the time you are required to - next_ms=$((now_ms + (update_every * 1000 * 100) )) - for x in "${charts_next_update[@]}"; do [ ${x} -lt ${next_ms} ] && next_ms=${x}; done - next_ms=$((next_ms - now_ms)) + # wait the time you are required to + next_ms=$((now_ms + (update_every * 1000 * 100) )) + for x in "${charts_next_update[@]}"; do [ ${x} -lt ${next_ms} ] && next_ms=${x}; done + next_ms=$((next_ms - now_ms)) - if [ ${LOOPSLEEPMS_HIGHRES} -eq 1 -a ${next_ms} -gt 0 ] + if [ ${LOOPSLEEPMS_HIGHRES} -eq 1 -a ${next_ms} -gt 0 ] + then + next_ms=$(( next_ms + current_time_ms_accuracy )) + seconds=$(( next_ms / 1000 )) + millis=$(( next_ms % 1000 )) + if [ ${millis} -lt 10 ] then - seconds=$(( next_ms / 1000 )) - millis=$(( next_ms % 1000 )) - [ ${millis} -lt 10 ] && millis="0${millis}" - [ ${millis} -lt 100 ] && millis="0${millis}" - [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: sleeping for ${seconds}.${millis} seconds." - sleep ${seconds}.${millis} - else - sleep $update_every + millis="00${millis}" + elif [ ${millis} -lt 100 ] + then + millis="0${millis}" fi + + [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: sleeping for ${seconds}.${millis} seconds." + ${mysleep} ${seconds}.${millis} + else + [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: sleeping for ${update_every} seconds." + ${mysleep} $update_every fi test ${now_ms} -ge ${exit_at} && exit 0 diff --git a/plugins.d/loopsleepms.sh.inc b/plugins.d/loopsleepms.sh.inc index 02ab694d26..2a81152ea8 100644 --- a/plugins.d/loopsleepms.sh.inc +++ b/plugins.d/loopsleepms.sh.inc @@ -1,10 +1,5 @@ # no need for shebang - this file is included from other scripts -# this function is used to sleep a fraction of a second -# it calculates the difference between every time is called -# and tries to align the sleep time to give you exactly the -# loop you need. - LOOPSLEEP_DATE="$(which date)" if [ -z "$LOOPSLEEP_DATE" ] then @@ -12,17 +7,13 @@ if [ -z "$LOOPSLEEP_DATE" ] exit 1 fi -LOOPSLEEPMS_LASTRUN=0 -LOOPSLEEPMS_LASTSLEEP=0 -LOOPSLEEPMS_LASTWORK=0 +# ----------------------------------------------------------------------------- +# use the date command as a high resolution timer +now_ms= LOOPSLEEPMS_HIGHRES=1 test "$($LOOPSLEEP_DATE +%N)" = "%N" && LOOPSLEEPMS_HIGHRES=0 - -now_ms= -current_time_ms() { - # if high resolution is not supported - # just sleep the time requested, in seconds +current_time_ms_from_date() { if [ $LOOPSLEEPMS_HIGHRES -eq 0 ] then now_ms="$($LOOPSLEEP_DATE +'%s')000" @@ -31,6 +22,83 @@ current_time_ms() { fi } +# ----------------------------------------------------------------------------- +# use /proc/uptime as a high resolution timer + +current_time_ms_from_date +current_time_ms_from_uptime_started="${now_ms}" +current_time_ms_from_uptime_first=0 +current_time_ms_from_uptime() { + local up rest arr n + + read up rest </proc/uptime + arr=(${up//./ }) + + if [ ${#arr[1]} -lt 1 ] + then + n="${arr[0]}000" + elif [ ${#arr[1]} -lt 2 ] + then + n="${arr[0]}${arr[1]}00" + elif [ ${#arr[1]} -lt 3 ] + then + n="${arr[0]}${arr[1]}0" + else + n="${arr[0]}${arr[1]}" + fi + + now_ms=$((current_time_ms_from_uptime_started - current_time_ms_from_uptime_first + n)) + + if [ "${now_ms}" -lt "${current_time_ms_from_uptime_started}" ] + then + echo >&2 "$0: Cannot use current_time_ms_from_uptime() - falling back to current_time_ms_from_date()." + current_time_ms="current_time_ms_from_date" + current_time_ms_from_date + current_time_ms_accuracy=1 + fi +} +current_time_ms_from_uptime +current_time_ms_from_uptime_first="$((now_ms - current_time_ms_from_uptime_started))" +current_time_ms="current_time_ms_from_uptime" +current_time_ms_accuracy=10 +if [ "${current_time_ms_from_uptime_first}" -eq 0 ] + then + echo >&2 "$0: Invalid setup for current_time_ms_from_uptime() - falling back to current_time_ms_from_date()." + current_time_ms="current_time_ms_from_date" + current_time_ms_accuracy=1 +fi + +# ----------------------------------------------------------------------------- +# use read with timeout for sleep + +mysleep="mysleep_read" + +mysleep_fifo="${NETDATA_CACHE_DIR-/tmp}/.netdata_bash_sleep_timer_fifo" +[ -e "${mysleep_fifo}" ] && rm "${mysleep_fifo}" +mkfifo "${mysleep_fifo}" || mysleep="sleep" + +mysleep_read() { + read -t "${1}" <>"${mysleep_fifo}" + ret=$? + if [ $ret -le 128 ] + then + echo >&2 "$0: Cannot use read for sleeping (return code ${ret})." + mysleep="sleep" + ${mysleep} "${1}" + fi +} + + +# ----------------------------------------------------------------------------- +# this function is used to sleep a fraction of a second +# it calculates the difference between every time is called +# and tries to align the sleep time to give you exactly the +# loop you need. + +LOOPSLEEPMS_LASTRUN=0 +LOOPSLEEPMS_LASTSLEEP=0 +LOOPSLEEPMS_LASTWORK=0 + loopsleepms() { local tellwork=0 t="$1" div s m now mstosleep @@ -68,7 +136,7 @@ loopsleepms() { # echo "# last loop's work took $LOOPSLEEPMS_LASTWORK ms" # calculate ms to sleep - mstosleep=$(( t - LOOPSLEEPMS_LASTWORK )) + mstosleep=$(( t - LOOPSLEEPMS_LASTWORK + current_time_ms_accuracy )) # echo "# mstosleep is $mstosleep ms" # if we are too slow, sleep some time @@ -81,7 +149,7 @@ loopsleepms() { # echo "# sleeping $s.$m" # echo - sleep $s.$m + ${mysleep} $s.$m # keep the values we need # for our next run diff --git a/plugins.d/tc-qos-helper.sh b/plugins.d/tc-qos-helper.sh index bff5217d28..9caef85f72 100755 --- a/plugins.d/tc-qos-helper.sh +++ b/plugins.d/tc-qos-helper.sh @@ -27,16 +27,9 @@ if [ -f "${config_dir}/tc-qos-helper.conf" ] source "${config_dir}/tc-qos-helper.conf" fi -# default time function -now_ms= -current_time_ms() { - now_ms="$(date +'%s')000" -} - # default sleep function LOOPSLEEPMS_LASTWORK=0 loopsleepms() { - [ "$1" = "tellwork" ] && shift sleep $1 } |