declare -A ap_devs=()
-export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
-
# _check is called once, to find out if this chart should be enabled or not
ap_check() {
require_cmd iw || return 1
- local ev=$(iw dev | awk '
+ local ev=$(run iw dev | awk '
BEGIN {
i = "";
ssid = "";
# - 1 to disable the chart
[ ${#ap_devs[@]} -gt 0 ] && return 0
+ error "no devices found in AP mode, with 'iw dev'"
return 1
}
# we will not check of the Conns*
# keys, since these are apache 2.4 specific
- [ -z "${apache_key_accesses}" ] && echo >&2 "apache: missing 'Total Accesses' from apache server: ${*}" && return 1
- [ -z "${apache_key_kbytes}" ] && echo >&2 "apache: missing 'Total kBytes' from apache server: ${*}" && return 1
- [ -z "${apache_key_reqpersec}" ] && echo >&2 "apache: missing 'ReqPerSec' from apache server: ${*}" && return 1
- [ -z "${apache_key_bytespersec}" ] && echo >&2 "apache: missing 'BytesPerSec' from apache server: ${*}" && return 1
- [ -z "${apache_key_bytesperreq}" ] && echo >&2 "apache: missing 'BytesPerReq' from apache server: ${*}" && return 1
- [ -z "${apache_key_busyworkers}" ] && echo >&2 "apache: missing 'BusyWorkers' from apache server: ${*}" && return 1
- [ -z "${apache_key_idleworkers}" ] && echo >&2 "apache: missing 'IdleWorkers' from apache server: ${*}" && return 1
- [ -z "${apache_key_scoreboard}" ] && echo >&2 "apache: missing 'Scoreboard' from apache server: ${*}" && return 1
+ [ -z "${apache_key_accesses}" ] && error "missing 'Total Accesses' from apache server: ${*}" && return 1
+ [ -z "${apache_key_kbytes}" ] && error "missing 'Total kBytes' from apache server: ${*}" && return 1
+ [ -z "${apache_key_reqpersec}" ] && error "missing 'ReqPerSec' from apache server: ${*}" && return 1
+ [ -z "${apache_key_bytespersec}" ] && error "missing 'BytesPerSec' from apache server: ${*}" && return 1
+ [ -z "${apache_key_bytesperreq}" ] && error "missing 'BytesPerReq' from apache server: ${*}" && return 1
+ [ -z "${apache_key_busyworkers}" ] && error "missing 'BusyWorkers' from apache server: ${*}" && return 1
+ [ -z "${apache_key_idleworkers}" ] && error "missing 'IdleWorkers' from apache server: ${*}" && return 1
+ [ -z "${apache_key_scoreboard}" ] && error "missing 'Scoreboard' from apache server: ${*}" && return 1
if [ ! -z "${apache_key_connstotal}" \
-a ! -z "${apache_key_connsasyncwriting}" \
apache_get() {
local oIFS="${IFS}" ret
- IFS=$':\n' apache_response=($(curl -Ss ${apache_curl_opts} "${apache_url}"))
+ IFS=$':\n' apache_response=($(run curl -Ss ${apache_curl_opts} "${apache_url}"))
ret=$?
IFS="${oIFS}"
-o -z "${apache_idleworkers}" \
]
then
- echo >&2 "apache: empty values got from apache server: ${apache_response[*]}"
+ error "empty values got from apache server: ${apache_response[*]}"
return 1
fi
apache_get
if [ $? -ne 0 ]
then
- echo >&2 "apache: cannot find stub_status on URL '${apache_url}'. Please set apache_url='http://apache.server:80/server-status?auto' in $confd/apache.conf"
+ error "cannot find stub_status on URL '${apache_url}'. Please set apache_url='http://apache.server:80/server-status?auto' in $confd/apache.conf"
return 1
fi
apcupsd_priority=90000
apcupsd_get() {
- timeout $apcupsd_timeout apcaccess status "$1:$2"
+ run -t $apcupsd_timeout apcaccess status "$1:$2"
}
apcupsd_check() {
require_cmd apcaccess || return 1
- apcupsd_get $apcupsd_ip $apcupsd_port >/dev/null
+ run apcupsd_get $apcupsd_ip $apcupsd_port >/dev/null
if [ $? -ne 0 ]
then
- echo >&2 "apcupsd: ERROR: Cannot get information for apcupsd server."
+ error "cannot get information for apcupsd server."
return 1
elif [ $(apcupsd_get $apcupsd_ip $apcupsd_port | awk '/^STATUS.*/{ print $3 }') != "ONLINE" ]
then
- echo >&2 "apcupsd: ERROR: UPS not online."
+ error "APC UPS not online."
return 1
fi
print \"SET time = \" time;
print \"END\"
}"
- [ $? -ne 0 ] && echo >&2 "apcupsd: failed to get values" && return 1
+ [ $? -ne 0 ] && error "failed to get values" && return 1
return 0
}
if [ -z "$cpu_apps_apps" ]
then
- echo >&2 "$PROGRAM_NAME: cpu_apps: Please set cpu_apps_apps='command1 command2 ...' in $confd/cpu_apps_apps.conf"
+ error "manual configuration required: please set cpu_apps_apps='command1 command2 ...' in $confd/cpu_apps_apps.conf"
return 1
fi
return 0
id="$( fixid "cpu$cpu" )"
- echo >&2 "charts.d: cpufreq: on file='$file', dir='$dir', cpu='$cpu', id='$id'"
+ debug "file='$file', dir='$dir', cpu='$cpu', id='$id'"
echo "DIMENSION $id '$id' absolute 1 1000"
echo >>$TMP_DIR/cpufreq.sh "echo \"SET $id = \"\$(< $file )"
echo >>$TMP_DIR/cpufreq.sh "echo END"
[ $cpufreq_source_update -eq 1 ] && echo >>$TMP_DIR/cpufreq.sh "}"
- # cat >&2 $TMP_DIR/cpufreq.sh
# ok, load the function cpufreq_update() we created
[ $cpufreq_source_update -eq 1 ] && . $TMP_DIR/cpufreq.sh
# - 1 to disable the chart
# check something
- [ "${example_magic_number}" != "12345" ] && echo >&2 "example: you have to set example_magic_number=$example_magic_number in example.conf to start example chart." && return 1
+ [ "${example_magic_number}" != "12345" ] && error "manual configuration required: you have to set example_magic_number=$example_magic_number in example.conf to start example chart." && return 1
# check that we can collect data
example_get || return 1
SET random = $example_value4
END
VALUESEOF
- # echo >&2 "example_count = $example_count value = $value4"
return 0
}
# no need for shebang - this file is loaded from charts.d.plugin
+# the exim command to run
exim_command=
# how frequently to collect queue size
exim_priority=60000
exim_check() {
- if [ -z "$exim_command" -o ! -x "$exim_command" ]
- then
- local d=
- for d in /sbin /usr/sbin /usr/local/sbin
- do
- if [ -x "$d/exim" ]
- then
- exim_command="$d/exim"
- break
- fi
- done
- fi
-
- if [ -z "$exim_command" -o ! -x "$exim_command" ]
- then
- echo >&2 "$PROGRAM_NAME: exim: cannot find exim executable. Please set 'exim_command=/path/to/exim' in $confd/exim.conf"
- return 1
- fi
+ if [ -z "${exim_command}" ]
+ then
+ require_cmd exim || return 1
+ exim_command="${EXIM_CMD}"
+ fi
- if [ `$exim_command -bpc 2>&1 | grep -c denied` -ne 0 ]
+ if [ $(${exim_command} -bpc 2>&1 | grep -c denied) -ne 0 ]
then
- echo >&2 "$PROGRAM_NAME: exim: permission denied. Please set 'queue_list_requires_admin = false' in your exim options file"
+ error "permission denied - please set 'queue_list_requires_admin = false' in your exim options file"
return 1
fi
}
exim_create() {
-cat <<EOF
+ cat <<EOF
CHART exim_local.qemails '' "Exim Queue Emails" "emails" queue exim.queued.emails line $((exim_priority + 1)) $exim_update_every
DIMENSION emails '' absolute 1 1
EOF
-return 0
+ return 0
}
exim_update() {
-echo "BEGIN exim_local.qemails $1"
-echo "SET emails = " `$exim_command -bpc`
-echo "END"
-return 0
+ echo "BEGIN exim_local.qemails $1"
+ echo "SET emails = " $(run ${exim_command} -bpc)
+ echo "END"
+ return 0
}
# _check is called once, to find out if this chart should be enabled or not
hddtemp_check() {
- nc $hddtemp_host $hddtemp_port &>/dev/null && return 0 || return 1
+ require_cmd nc || return 1
+ run nc $hddtemp_host $hddtemp_port && return 0 || return 1
}
# _create is called once, to create the charts
if [ -z "$mem_apps_apps" ]
then
- echo >&2 "$PROGRAM_NAME: mem_apps: not configured. Please set mem_apps_apps='command1 command2 ...' in $confd/mem_apps_apps.conf"
+ error "manual configuration required: please set mem_apps_apps='command1 command2 ...' in $confd/mem_apps_apps.conf"
return 1
fi
return 0
local oIFS="${IFS}"
mysql_data=()
IFS=$'\t'$'\n'
- #arr=($("${@}" -e "SHOW GLOBAL STATUS WHERE value REGEXP '^[0-9]';" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)" ))
- #arr=($("${@}" -N -e "SHOW GLOBAL STATUS;" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)[^ ]+\s[0-9]" ))
- arr=($("${@}" -N -e "SHOW GLOBAL STATUS;" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)[^[:space:]]+[[:space:]]+[0-9]+" ))
+ #arr=($(run "${@}" -e "SHOW GLOBAL STATUS WHERE value REGEXP '^[0-9]';" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)" ))
+ #arr=($(run "${@}" -N -e "SHOW GLOBAL STATUS;" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)[^ ]+\s[0-9]" ))
+ arr=($(run "${@}" -N -e "SHOW GLOBAL STATUS;" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)[^[:space:]]+[[:space:]]+[0-9]+" ))
IFS="${oIFS}"
[ "${#arr[@]}" -lt 3 ] && return 1
[ -z "${mysql_cmds[$m]}" ] && mysql_cmds[$m]="$mysql_cmd"
if [ -z "${mysql_cmds[$m]}" ]
then
- echo >&2 "$PROGRAM_NAME: mysql: cannot get mysql command for '$m'. Please set mysql_cmds[$m]='/path/to/mysql', in $confd/mysql.conf"
+ error "cannot get mysql command for '$m'. Please set mysql_cmds[$m]='/path/to/mysql', in $confd/mysql.conf"
fi
mysql_get "${mysql_cmds[$m]}" ${mysql_opts[$m]}
if [ ! $? -eq 0 ]
then
- echo >&2 "$PROGRAM_NAME: mysql: cannot get global status for '$m'. Please set mysql_opts[$m]='options' to whatever needed to get connected to the mysql server, in $confd/mysql.conf"
+ error "cannot get global status for '$m'. Please set mysql_opts[$m]='options' to whatever needed to get connected to the mysql server, in $confd/mysql.conf"
unset mysql_cmds[$m]
unset mysql_opts[$m]
unset mysql_ids[$m]
mysql_check tryroot "${@}"
return $?
else
- echo >&2 "$PROGRAM_NAME: mysql: no mysql servers found. Please set mysql_opts[name]='options' to whatever needed to get connected to the mysql server, in $confd/mysql.conf"
+ error "no mysql servers found. Please set mysql_opts[name]='options' to whatever needed to get connected to the mysql server, in $confd/mysql.conf"
return 1
fi
fi
unset mysql_ids[$m]
unset mysql_opts[$m]
unset mysql_cmds[$m]
- echo >&2 "$PROGRAM_NAME: mysql: failed to get values for '$m', disabling it."
+ error "failed to get values for '$m', disabling it."
continue
fi
fi
done
- [ ${#mysql_ids[@]} -eq 0 ] && echo >&2 "$PROGRAM_NAME: mysql: no mysql servers left active." && return 1
+ [ ${#mysql_ids[@]} -eq 0 ] && error "no mysql servers left active." && return 1
return 0
}
nginx_writing=0
nginx_waiting=0
nginx_get() {
- nginx_response=($(curl -Ss ${nginx_curl_opts} "${nginx_url}"))
+ nginx_response=($(run curl -Ss ${nginx_curl_opts} "${nginx_url}"))
[ $? -ne 0 -o "${#nginx_response[@]}" -eq 0 ] && return 1
if [ "${nginx_response[0]}" != "Active" \
-o "${nginx_response[14]}" != "Waiting:" \
]
then
- echo >&2 "nginx: Invalid response from nginx server: ${nginx_response[*]}"
+ error "Invalid response from nginx server: ${nginx_response[*]}"
return 1
fi
-o -z "${nginx_waiting}" \
]
then
- echo >&2 "nginx: empty values got from nginx server: ${nginx_response[*]}"
+ error "empty values got from nginx server: ${nginx_response[*]}"
return 1
fi
nginx_get
if [ $? -ne 0 ]
then
- echo >&2 "nginx: cannot find stub_status on URL '${nginx_url}'. Please set nginx_url='http://nginx.server/stub_status' in $confd/nginx.conf"
+ error "cannot find stub_status on URL '${nginx_url}'. Please set nginx_url='http://nginx.server/stub_status' in $confd/nginx.conf"
return 1
fi
declare -A nut_ids=()
nut_get_all() {
- timeout $nut_timeout upsc -l
+ run -t $nut_timeout upsc -l
}
nut_get() {
- timeout $nut_timeout upsc "$1"
+ run -t $nut_timeout upsc "$1"
}
nut_check() {
nut_ids[$x]="$( fixid "$x" )"
continue
fi
- echo >&2 "nut: ERROR: Cannot get information for NUT UPS '$x'."
+ error "cannot get information for NUT UPS '$x'."
done
if [ ${#nut_ids[@]} -eq 0 ]
then
- echo >&2 "nut: Please set nut_ups='ups_name' in $confd/nut.conf"
+ error "Cannot find UPSes - please set nut_ups='ups_name' in $confd/nut.conf"
return 1
fi
print \"SET temp = \" temp;
print \"END\"
}"
- [ $? -ne 0 ] && unset nut_ids[$i] && echo >&2 "nut: failed to get values for '$i', disabling it."
+ [ $? -ne 0 ] && unset nut_ids[$i] && error "failed to get values for '$i', disabling it."
done
- [ ${#nut_ids[@]} -eq 0 ] && echo >&2 "nut: no UPSes left active." && return 1
+ [ ${#nut_ids[@]} -eq 0 ] && error "no UPSes left active." && return 1
return 0
}
opensips_priority=80000
opensips_get_stats() {
- timeout $opensips_timeout "$opensips_cmd" $opensips_opts |\
+ run -t $opensips_timeout "$opensips_cmd" $opensips_opts |\
grep "^\(core\|dialog\|net\|registrar\|shmem\|siptrace\|sl\|tm\|uri\|usrloc\):[a-zA-Z0-9_-]\+[[:space:]]*[=:]\+[[:space:]]*[0-9]\+[[:space:]]*$" |\
sed \
-e "s|[[:space:]]*[=:]\+[[:space:]]*\([0-9]\+\)[[:space:]]*$|=\1|g" \
local x="$(opensips_get_stats | grep "^opensips_core_")"
if [ ! $? -eq 0 -o -z "$x" ]
then
- echo >&2 "$PROGRAM_NAME: opensips: cannot get global status. Please set opensips_opts='options' whatever needed to get connected to opensips server, in $confd/opensips.conf"
+ error "cannot get global status. Please set opensips_opts='options' whatever needed to get connected to opensips server, in $confd/opensips.conf"
return 1
fi
eval "local $(opensips_get_stats)"
[ $? -ne 0 ] && return 1
- [ $opensips_command_failed -eq 1 ] && echo >&2 "$PROGRAM_NAME: opensips: failed to get values, disabling." && return 1
+ [ $opensips_command_failed -eq 1 ] && error "failed to get values, disabling." && return 1
# write the result of the work.
cat <<VALUESEOF
phpfpm_get() {
local opts="${1}" url="${2}"
- phpfpm_response=($(curl -Ss ${opts} "${url}"))
+ phpfpm_response=($(run curl -Ss ${opts} "${url}"))
[ $? -ne 0 -o "${#phpfpm_response[@]}" -eq 0 ] && return 1
if [[ "${phpfpm_response[0]}" != "pool:" \
|| "${phpfpm_response[32]}" != "total" \
]]
then
- echo >&2 "phpfpm: invalid response from phpfpm status server: ${phpfpm_response[*]}"
+ error "invalid response from phpfpm status server: ${phpfpm_response[*]}"
return 1
fi
|| -z "${phpfpm_max_children_reached}" \
]]
then
- echo >&2 "phpfpm: empty values got from phpfpm status server: ${phpfpm_response[*]}"
+ error "empty values got from phpfpm status server: ${phpfpm_response[*]}"
return 1
fi
do
phpfpm_get "${phpfpm_curl_opts[$m]}" "${phpfpm_urls[$m]}"
if [ $? -ne 0 ]; then
- echo >&2 "phpfpm: cannot find status on URL '${phpfpm_url[$m]}'. Please set phpfpm_urls[$m]='http://localhost/status' in $confd/phpfpm.conf"
+ error "cannot find status on URL '${phpfpm_url[$m]}'. Please set phpfpm_urls[$m]='http://localhost/status' in $confd/phpfpm.conf"
unset phpfpm_urls[$m]
continue
fi
done
if [ ${#phpfpm_urls[@]} -eq 0 ]; then
- echo >&2 "phpfpm: no phpfpm servers found. Please set phpfpm_urls[name]='url' to whatever needed to get status to the phpfpm server, in $confd/phpfpm.conf"
+ error "no phpfpm servers found. Please set phpfpm_urls[name]='url' to whatever needed to get status to the phpfpm server, in $confd/phpfpm.conf"
return 1
fi
if [ -z "$postfix_postqueue" -o ! -x "$postfix_postqueue" ]
then
postfix_postqueue="`which postqueue 2>/dev/null`"
- if [ -z "$postfix_postqueue" -o ! -x "$postfix_postqueue" ]
- then
- local d=
- for d in /sbin /usr/sbin /usr/local/sbin
- do
- if [ -x "$d/postqueue" ]
- then
- postfix_postqueue="$d/postqueue"
- break
- fi
- done
- fi
fi
if [ -z "$postfix_postqueue" -o ! -x "$postfix_postqueue" ]
then
- echo >&2 "$PROGRAM_NAME: postfix: cannot find postqueue. Please set 'postfix_postqueue=/path/to/postqueue' in $confd/postfix.conf"
+ error "cannot find postqueue. Please set 'postfix_postqueue=/path/to/postqueue' in $confd/postfix.conf"
return 1
fi
postfix_q_emails=0
postfix_q_size=0
- eval "`$postfix_postqueue -p |\
+ eval "$(run $postfix_postqueue -p |\
grep "^--" |\
sed -e "s/-- \([0-9]\+\) Kbytes in \([0-9]\+\) Requests.$/local postfix_q_size=\1\nlocal postfix_q_emails=\2/g" |\
- egrep "^local postfix_q_(emails|size)=[0-9]+$"`"
+ egrep "^local postfix_q_(emails|size)=[0-9]+$")"
# write the result of the work.
cat <<VALUESEOF
# - 0 to enable the chart
# - 1 to disable the chart
- [ -z "$( sensors_find_all_files $sensors_sys_dir )" ] && echo >&2 "$PROGRAM_NAME: sensors: no sensors found in '$sensors_sys_dir'." && return 1
+ [ -z "$( sensors_find_all_files $sensors_sys_dir )" ] && error "no sensors found in '$sensors_sys_dir'." && return 1
return 0
}
[ $v -ne 0 ] && echo "$f" && continue
excluded=
- echo >&2 "$PROGRAM_NAME: sensors: $f gives zero values"
+ error "$f gives zero values"
done
}
v=$(( v + 1 - 1 ))
[ $v -ne 0 ] && echo "$f" && continue
- echo >&2 "$PROGRAM_NAME: sensors: $f is disabled"
+ error "$f is disabled"
done
}
id="$( fixid "$device.$subsystem.$dir" )"
- echo >&2 "charts.d: sensors: on path='$path', dir='$dir', device='$device', subsystem='$subsystem', id='$id', name='$name'"
+ debug "path='$path', dir='$dir', device='$device', subsystem='$subsystem', id='$id', name='$name'"
for mode in temperature voltage fans power current energy humidity
do
done
[ $sensors_source_update -eq 1 ] && echo >>$TMP_DIR/sensors.sh "}"
- # cat >&2 $TMP_DIR/sensors.sh
# ok, load the function sensors_update() we created
[ $sensors_source_update -eq 1 ] && . $TMP_DIR/sensors.sh
squid_get_stats_internal() {
local host="$1" port="$2" url="$3"
- squidclient -h $host -p $port $url
+ run squidclient -h $host -p $port $url
}
squid_get_stats() {
squid_host="$host"
squid_port="$port"
squid_url="$url"
- echo >&2 "squid: found squid at '$host:$port' with url '$url'"
+ debug "found squid at '$host:$port' with url '$url'"
return 0
fi
done
done
- echo >&2 "squid: cannot find squid running in localhost. Please set squid_url='url' and squid_host='IP' and squid_port='PORT' in $confd/squid.conf"
+ error "cannot find squid running in localhost. Please set squid_url='url' and squid_host='IP' and squid_port='PORT' in $confd/squid.conf"
return 1
}
local x="$(squid_get_stats | grep client_http.requests)"
if [ ! $? -eq 0 -o -z "$x" ]
then
- echo >&2 "squid: cannot fetch URL '$squid_url' by connecting to $squid_host:$squid_port. Please set squid_url='url' and squid_host='host' and squid_port='port' in $confd/squid.conf"
+ error "cannot fetch URL '$squid_url' by connecting to $squid_host:$squid_port. Please set squid_url='url' and squid_host='host' and squid_port='port' in $confd/squid.conf"
return 1
fi
# check if url, username, passwords are set
if [ -z "${tomcat_url}" ]; then
- echo >&2 "tomcat url is unset or set to the empty string"
+ error "tomcat url is unset or set to the empty string"
return 1
fi
if [ -z "${tomcat_user}" ]; then
# check backwards compatibility
if [ -z "${tomcatUser}" ]; then
- echo >&2 "tomcat user is unset or set to the empty string"
+ error "tomcat user is unset or set to the empty string"
return 1
else
tomcat_user="${tomcatUser}"
if [ -z "${tomcat_password}" ]; then
# check backwards compatibility
if [ -z "${tomcatPassword}" ]; then
- echo >&2 "tomcat password is unset or set to the empty string"
+ error "tomcat password is unset or set to the empty string"
return 1
else
tomcat_password="${tomcatPassword}"
tomcat_get
if [ $? -ne 0 ]
then
- echo >&2 "tomcat: couldn't get to status page on URL '${tomcat_url}'."\
- "Please make sure tomcat url, username and password are correct."
+ error "cannot get to status page on URL '${tomcat_url}'. Please make sure tomcat url, username and password are correct."
return 1
fi
tomcat_get() {
# collect tomcat values
tomcat_port="$(IFS=/ read -ra a <<< "$tomcat_url"; hostport=${a[2]}; echo "${hostport#*:}")"
- mapfile -t lines < <(curl -u "$tomcat_user":"$tomcat_password" -Ss ${tomcat_curl_opts} "$tomcat_url" |\
- xmlstarlet sel \
+ mapfile -t lines < <(run curl -u "$tomcat_user":"$tomcat_password" -Ss ${tomcat_curl_opts} "$tomcat_url" |\
+ run xmlstarlet sel \
-t -m "/status/jvm/memory" -v @free \
-n -m "/status/connector[@name='\"http-bio-$tomcat_port\"']/threadInfo" -v @currentThreadCount \
-n -v @currentThreadsBusy \
#!/usr/bin/env bash
+export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
+
PROGRAM_FILE="$0"
PROGRAM_NAME="$(basename $0)"
PROGRAM_NAME="${PROGRAM_NAME/.plugin}"
+MODULE_NAME="main"
# if you need to run parallel charts.d processes
# just link this files with a different name
# netdata will start multiple of them
# each will have a different config file
-echo >&2 "$PROGRAM_NAME: started from '$PROGRAM_FILE' with options: $*"
+# -----------------------------------------------------------------------------
+# create temp dir
+
+debug=0
+TMP_DIR=
+chartsd_cleanup() {
+ if [ ! -z "$TMP_DIR" -a -d "$TMP_DIR" ]
+ then
+ [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: cleaning up temporary directory $TMP_DIR ..."
+ rm -rf "$TMP_DIR"
+ fi
+ exit 0
+}
+trap chartsd_cleanup EXIT
+trap chartsd_cleanup SIGHUP
+trap chartsd_cleanup INT
-if [ $(( ${BASH_VERSINFO[0]} )) -lt 4 ]
+if [ $UID = "0" ]
then
- echo >&2
- echo >&2 "$PROGRAM_NAME: ERROR"
- echo >&2 "BASH version 4 or later is required."
- echo >&2 "You are running version: ${BASH_VERSION}"
- echo >&2 "Please upgrade."
- echo >&2
- exit 1
+ TMP_DIR="$( mktemp -d /var/run/netdata-${PROGRAM_NAME}-XXXXXXXXXX )"
+else
+ TMP_DIR="$( mktemp -d /tmp/.netdata-${PROGRAM_NAME}-XXXXXXXXXX )"
fi
+logdate() {
+ date "+%Y-%m-%d %H:%M:%S"
+}
+
+log() {
+ local status="${1}"
+ shift
+
+ echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${MODULE_NAME}: ${*}"
+
+}
+
+warning() {
+ log WARNING "${@}"
+}
+
+error() {
+ log ERROR "${@}"
+}
+
+info() {
+ log INFO "${@}"
+}
+
+fatal() {
+ log FATAL "${@}"
+ echo "DISABLE"
+ exit 1
+}
+
+debug() {
+ [ $debug -eq 1 ] && log DEBUG "${@}"
+}
+
+# -----------------------------------------------------------------------------
# check a few commands
+
require_cmd() {
- which "$1" >/dev/null
- if [ $? -ne 0 ]
+ local x=$(which "${1}" 2>/dev/null || command -v "${1}" 2>/dev/null)
+ if [ -z "${x}" -o ! -x "${x}" ]
then
- echo >&2 "$PROGRAM_NAME: ERROR: Command '$1' is not found in the system path."
+ warning "command '${1}' is not found in ${PATH}."
+ eval "${1^^}_CMD=\"\""
return 1
fi
+
+ eval "${1^^}_CMD=\"${x}\""
return 0
}
require_cmd egrep || exit 1
require_cmd mktemp || exit 1
require_cmd awk || exit 1
+require_cmd timeout || exit 1
+require_cmd curl || exit 1
+
+# -----------------------------------------------------------------------------
+
+[ $(( ${BASH_VERSINFO[0]} )) -lt 4 ] && fatal "BASH version 4 or later is required, but found version: ${BASH_VERSION}. Please upgrade."
+
+info "started from '$PROGRAM_FILE' with options: $*"
# -----------------------------------------------------------------------------
-# insternal defaults
+# internal defaults
# netdata exposes a few environment variables for us
pluginsd="${NETDATA_PLUGINS_DIR}"
# -----------------------------------------------------------------------------
# parse parameters
-debug=0
check=0
chart_only=
while [ ! -z "$1" ]
continue
fi
- echo >&2 "Cannot understand parameter $1. Aborting."
- echo "DISABLE"
- exit 1
+ fatal "Cannot understand parameter $1. Aborting."
done
if [ -f "$myconfig" ]
then
. "$myconfig"
- if [ $? -ne 0 ]
- then
- echo >&2 "$PROGRAM_NAME: cannot load $myconfig"
- echo "DISABLE"
- exit 1
- fi
+ [ $? -ne 0 ] && fatal "cannot load $myconfig"
+
time_divisor=$((time_divisor))
[ $time_divisor -lt 10 ] && time_divisor=10
[ $time_divisor -gt 100 ] && time_divisor=100
else
- echo >&2 "$PROGRAM_NAME: configuration file '$myconfig' not found. Using defaults."
+ info "configuration file '$myconfig' not found. Using defaults."
fi
# we check for the timeout command, after we load our
test $update_every -eq 0 && update_every=1 # if it is zero, make it 1
# check the charts.d directory
-if [ ! -d "$chartsd" ]
- then
- echo >&2 "$PROGRAM_NAME: cannot find charts directory '$chartsd'"
- echo "DISABLE"
-fi
-
+[ ! -d "$chartsd" ] && fatal "cannot find charts directory '$chartsd'"
# -----------------------------------------------------------------------------
# library functions
tr "[A-Z]" "[a-z]"
}
+run() {
+ local ret pid="${BASHPID}" t
+
+ if [ "z${1}" = "z-t" -a "${2}" != "0" ]
+ then
+ t="${2}"
+ shift 2
+ timeout ${t} "${@}" 2>"${TMP_DIR}/run.${pid}"
+ ret=$?
+ else
+ "${@}" 2>"${TMP_DIR}/run.${pid}"
+ ret=$?
+ fi
+
+ if [ ${ret} -ne 0 ]
+ then
+ {
+ printf "$(logdate): ${PROGRAM_NAME}: ${status}: ${MODULE_NAME}: command '"
+ printf "%q " "${@}"
+ printf "' failed:\n --- BEGIN TRACE ---\n"
+ cat "${TMP_DIR}/run.${pid}"
+ printf " --- END TRACE ---\n"
+ } >&2
+ fi
+ rm "${TMP_DIR}/run.${pid}"
+
+ return ${ret}
+}
+
# convert any floating point number
# to integer, give a multiplier
# the result is stored in ${FLOAT2INT_RESULT}
local f m="$2" a b l v=($1)
f=${v[0]}
- # echo >&2 "value='${1}' f='${f}', m='${m}'"
-
# the length of the multiplier - 1
l=$(( ${#m} - 1 ))
# store the result
FLOAT2INT_RESULT=$(( (a * m) + b ))
- #echo >&2 "FLOAT2INT_RESULT='${FLOAT2INT_RESULT}'"
}
all_charts() {
cd "$chartsd"
- [ $? -ne 0 ] && echo >&2 "$PROGRAM_NAME: Cannot cd to $chartsd" && return 1
+ [ $? -ne 0 ] && error "cannot cd to $chartsd" && return 1
ls *.chart.sh | sed "s/\.chart\.sh$//g"
}
for chart in $( all_charts )
do
+ MODULE_NAME="${chart}"
+
eval "enabled=\$$chart"
if [ -z "${enabled}" ]
then
if [ ! "${enabled}" = "${required}" ]
then
- echo >&2 "$PROGRAM_NAME: '$chart' is NOT enabled. Add a line with $chart=$required in $myconfig to enable it (or remove the line that disables it)."
+ info "is disabled. Add a line with $chart=$required in $myconfig to enable it (or remove the line that disables it)."
else
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: '$chart' is enabled."
+ debug "is enabled for auto-detection."
local charts="$charts $chart"
fi
done
+ MODULE_NAME="main"
local charts2=
for chart in $charts
do
+ MODULE_NAME="${chart}"
+
# check the enabled charts
local check="$( cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_check()" )"
if [ -z "$check" ]
then
- echo >&2 "$PROGRAM_NAME: chart '$chart' does not seem to have a $chart$charts_check() function. Disabling it."
+ error "module '$chart' does not seem to have a $chart$charts_check() function. Disabling it."
continue
fi
local create="$( cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_create()" )"
if [ -z "$create" ]
then
- echo >&2 "$PROGRAM_NAME: chart '$chart' does not seem to have a $chart$charts_create() function. Disabling it."
+ error "module '$chart' does not seem to have a $chart$charts_create() function. Disabling it."
continue
fi
local update="$( cat "$chartsd/$chart.chart.sh" | sed "s/^ \+//g" | grep "^$chart$charts_update()" )"
if [ -z "$update" ]
then
- echo >&2 "$PROGRAM_NAME: chart '$chart' does not seem to have a $chart$charts_update() function. Disabling it."
+ error "module '$chart' does not seem to have a $chart$charts_update() function. Disabling it."
continue
fi
#then
# if [ ! -z "$( cat "$confd/$chart.conf" | sed "s/^ \+//g" | grep -v "^$" | grep -v "^#" | grep -v "^$chart$charts_undescore" )" ]
# then
- # echo >&2 "$PROGRAM_NAME: chart's $chart config $confd/$chart.conf should only have lines starting with $chart$charts_undescore . Disabling it."
+ # error "module's $chart config $confd/$chart.conf should only have lines starting with $chart$charts_undescore . Disabling it."
# continue
# fi
#fi
# "$pluginsd/charts.d.dryrun-helper.sh" "$chart" "$chartsd/$chart.chart.sh" "$confd/$chart.conf" >/dev/null
# if [ $? -ne 0 ]
# then
- # echo >&2 "$PROGRAM_NAME: chart's $chart did not pass the dry run check. This means it uses global variables not starting with $chart. Disabling it."
+ # error "module's $chart did not pass the dry run check. This means it uses global variables not starting with $chart. Disabling it."
# continue
# fi
#fi
local charts2="$charts2 $chart"
done
+ MODULE_NAME="main"
echo $charts2
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: enabled charts: $charts2"
+ debug "enabled charts: $charts2"
}
-
# -----------------------------------------------------------------------------
# load the charts
active_charts=
for chart in $( all_enabled_charts )
do
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: loading chart: '$chartsd/$chart.chart.sh'"
+ MODULE_NAME="${chart}"
+
+ debug "loading module: '$chartsd/$chart.chart.sh'"
+
. "$chartsd/$chart.chart.sh"
if [ -f "$confd/$PROGRAM_NAME/$chart.conf" ]
then
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: loading chart options: '$confd/$PROGRAM_NAME/$chart.conf'"
+ debug "loading module configuration: '$confd/$PROGRAM_NAME/$chart.conf'"
. "$confd/$PROGRAM_NAME/$chart.conf"
elif [ -f "$confd/$chart.conf" ]
then
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: loading chart options: '$confd/$chart.conf'"
+ debug "loading module configuration: '$confd/$chart.conf'"
. "$confd/$chart.conf"
else
- echo >&2 "$PROGRAM_NAME: $chart: configuration file '$confd/$PROGRAM_NAME/$chart.conf' not found. Using defaults."
+ warning "configuration file '$confd/$PROGRAM_NAME/$chart.conf' not found. Using defaults."
fi
eval "dt=\$$chart$suffix_update_every"
$chart$charts_check
if [ $? -eq 0 ]
then
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: '$chart' activated"
+ debug "module '$chart' activated"
active_charts="$active_charts $chart"
else
- echo >&2 "$PROGRAM_NAME: chart '$chart' check() function reports failure."
+ error "module's '$chart' check() function reports failure."
fi
done
-[ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: activated charts: $active_charts"
+MODULE_NAME="main"
+debug "activated modules: $active_charts"
# -----------------------------------------------------------------------------
# if we only need a specific chart, remove all the others
if [ ! -z "${chart_only}" ]
then
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: requested to run only for: '${chart_only}'"
+ debug "requested to run only for: '${chart_only}'"
check_charts=
for chart in $active_charts
do
done
active_charts="$check_charts"
fi
-[ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: activated charts: $active_charts"
+debug "activated charts: $active_charts"
# stop if we just need a pre-check
if [ $check -eq 1 ]
then
- echo >&2 "CHECK RESULT"
- echo >&2 "Will run the charts: $active_charts"
+ info "CHECK RESULT"
+ info "Will run the charts: $active_charts"
exit 0
fi
# -----------------------------------------------------------------------------
-# create temp dir
-
-TMP_DIR=
-chartsd_cleanup() {
- cd /tmp
- if [ ! -z "$TMP_DIR" -a -d "$TMP_DIR" ]
- then
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: cleaning up temporary directory $TMP_DIR ..."
- rm -rf "$TMP_DIR"
- fi
- exit 0
-}
-trap chartsd_cleanup EXIT
-trap chartsd_cleanup SIGHUP
-trap chartsd_cleanup INT
-if [ $UID = "0" ]
-then
- TMP_DIR="$( mktemp -d /var/run/netdata-${PROGRAM_NAME}-XXXXXXXXXX )"
-else
- TMP_DIR="$( mktemp -d /tmp/.netdata-${PROGRAM_NAME}-XXXXXXXXXX )"
-fi
-
-cd "$TMP_DIR" || exit 1
+cd "${TMP_DIR}" || exit 1
# -----------------------------------------------------------------------------
# create charts
run_charts=
for chart in $active_charts
do
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: Calling '$chart$charts_create()'..."
+ MODULE_NAME="${chart}"
+
+ debug "calling '$chart$charts_create()'..."
$chart$charts_create
if [ $? -eq 0 ]
then
run_charts="$run_charts $chart"
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: '$chart' has initialized."
+ debug "'$chart' initialized."
else
- echo >&2 "$PROGRAM_NAME: chart '$chart' function '$chart$charts_create()' reports failure."
+ error "module's '$chart' function '$chart$charts_create()' reports failure."
fi
done
-[ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: run_charts='$run_charts'"
+MODULE_NAME="main"
+debug "run_charts='$run_charts'"
# -----------------------------------------------------------------------------
# update dimensions
-if [ -z "$run_charts" ]
- then
- echo >&2 "$PROGRAM_NAME: No charts to collect data from."
- echo "DISABLE"
- exit 1
-fi
+[ -z "$run_charts" ] && fatal "No charts to collect data from."
declare -A charts_last_update=() charts_update_every=() charts_next_update=() charts_run_counter=() charts_serial_failures=()
global_update() {
for chart in "${now_charts[@]}"
do
- #echo >&2 " DEBUG: chart: $chart last: ${charts_last_update[$chart]}, next: ${charts_next_update[$chart]}, now: ${now_ms}"
+ MODULE_NAME="${chart}"
+
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}"
charts_last_update[$chart]=${now_ms}
fi
exec_start_ms=$now_ms
- #echo >&2 " EXEC: $chart$charts_update $dt"
$chart$charts_update $dt
ret=$?
if [ ${charts_serial_failures[$chart]} -gt 10 ]
then
- echo >&2 "$PROGRAM_NAME: chart '$chart' update() function reported failure ${charts_serial_failures[$chart]} times. Disabling it."
+ error "module's '$chart' update() function reported failure ${charts_serial_failures[$chart]} times. Disabling it."
else
- echo >&2 "$PROGRAM_NAME: chart '$chart' update() function reports failure. Will keep trying for a while."
+ error "module's '$chart' update() function reports failure. Will keep trying for a while."
next_charts+=($chart)
fi
fi
next_charts+=($chart)
fi
done
+ MODULE_NAME="${chart}"
# wait the time you are required to
next_ms=$((now_ms + (update_every * 1000 * 100) ))
millis="0${millis}"
fi
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: sleeping for ${seconds}.${millis} seconds."
+ debug "sleeping for ${seconds}.${millis} seconds."
${mysleep} ${seconds}.${millis}
else
- [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: sleeping for ${update_every} seconds."
+ debug "sleeping for ${update_every} seconds."
${mysleep} $update_every
fi
test ${now_ms} -ge ${exit_at} && exit 0
done
- echo >&2 "$PROGRAM_NAME: Nothing left to do. Disabling charts.d.plugin."
- echo "DISABLE"
+ fatal "nothing left to do, exiting..."
}
global_update