diff options
Diffstat (limited to 'charts.d')
-rw-r--r-- | charts.d/Makefile.am | 1 | ||||
-rw-r--r-- | charts.d/Makefile.in | 1 | ||||
-rw-r--r-- | charts.d/README.md | 293 | ||||
-rw-r--r-- | charts.d/apcupsd.chart.sh | 104 | ||||
-rw-r--r-- | charts.d/libreswan.chart.sh | 173 |
5 files changed, 415 insertions, 157 deletions
diff --git a/charts.d/Makefile.am b/charts.d/Makefile.am index 85bcef3cf..104ba86af 100644 --- a/charts.d/Makefile.am +++ b/charts.d/Makefile.am @@ -16,6 +16,7 @@ dist_charts_DATA = \ example.chart.sh \ exim.chart.sh \ hddtemp.chart.sh \ + libreswan.chart.sh \ load_average.chart.sh \ mem_apps.chart.sh \ mysql.chart.sh \ diff --git a/charts.d/Makefile.in b/charts.d/Makefile.in index 5d17f4d2a..ebd1af2be 100644 --- a/charts.d/Makefile.in +++ b/charts.d/Makefile.in @@ -310,6 +310,7 @@ dist_charts_DATA = \ example.chart.sh \ exim.chart.sh \ hddtemp.chart.sh \ + libreswan.chart.sh \ load_average.chart.sh \ mem_apps.chart.sh \ mysql.chart.sh \ diff --git a/charts.d/README.md b/charts.d/README.md index 37c9d22ec..748af08a1 100644 --- a/charts.d/README.md +++ b/charts.d/README.md @@ -1,5 +1,76 @@ The following charts.d plugins are supported: +--- + +# hddtemp + +The plugin will collect temperatures from disks + +It will create one chart with all active disks + +1. **temperature in Celsius** + +### configuration + +hddtemp needs to be running in daemonized mode + +```sh +# host with daemonized hddtemp +hddtemp_host="localhost" + +# port on which hddtemp is showing data +hddtemp_port="7634" + +# array of included disks +# the default is to include all +hddtemp_disks=() +``` + +--- + +# libreswan + +The plugin will collects bytes-in, bytes-out and uptime for all established libreswan IPSEC tunnels. + +The following charts are created, **per tunnel**: + +1. **Uptime** + + * the uptime of the tunnel + +2. **Traffic** + + * bytes in + * bytes out + +### configuration + +Its config file is `/etc/netdata/charts.d/libreswan.conf`. + +The plugin executes 2 commands to collect all the information it needs: + +```sh +ipsec whack --status +ipsec whack --trafficstatus +``` + +The first command is used to extract the currently established tunnels, their IDs and their names. +The second command is used to extract the current uptime and traffic. + +Most probably user `netdata` will not be able to query libreswan, so the `ipsec` commands will be denied. +The plugin attempts to run `ipsec` as `sudo ipsec ...`, to get access to libreswan statistics. + +To allow user `netdata` execute `sudo ipsec ...`, create the file `/etc/sudoers.d/netdata` with this content: + +``` +netdata ALL = (root) NOPASSWD: /sbin/ipsec whack --status +netdata ALL = (root) NOPASSWD: /sbin/ipsec whack --trafficstatus +``` + +Make sure the path `/sbin/ipsec` matches your setup (execute `which ipsec` to find the right path). + +--- + # mysql The plugin will monitor one or more mysql servers @@ -76,67 +147,89 @@ The above sets the mysql command only for server2. server1 will use the system d If no configuration is given, the plugin will attempt to connect to mysql server at localhost. + --- -# squid +# nut -The plugin will monitor a squid server. +The plugin will collect UPS data for all UPSes configured in the system. -It will produce 4 charts: +The following charts will be created: -1. **Squid Client Bandwidth** in kbps +1. **UPS Charge** - * in - * out - * hits + * percentage changed -2. **Squid Client Requests** in requests/sec +2. **UPS Battery Voltage** - * requests - * hits - * errors + * current voltage + * high voltage + * low voltage + * nominal voltage -3. **Squid Server Bandwidth** in kbps +3. **UPS Input Voltage** - * in - * out + * current voltage + * fault voltage + * nominal voltage -4. **Squid Server Requests** in requests/sec +4. **UPS Input Current** - * requests - * errors + * nominal current -### autoconfig +5. **UPS Input Frequency** -The plugin will by itself detect squid servers running on -localhost, on ports 3128 or 8080. + * current frequency + * nominal frequency -It will attempt to download URLs in the form: +6. **UPS Output Voltage** -- `cache_object://HOST:PORT/counters` -- `/squid-internal-mgr/counters` + * current voltage + +7. **UPS Load** + + * current load + +8. **UPS Temperature** + + * current temperature -If any succeeds, it will use this. ### configuration -If you need to configure it by hand, create the file -`/etc/netdata/squid.conf` with the following variables: +This is the internal default for `/etc/netdata/nut.conf` -- `squid_host=IP` the IP of the squid host -- `squid_port=PORT` the port the squid is listening -- `squid_url="URL"` the URL with the statistics to be fetched from squid -- `squid_timeout=SECONDS` how much time we should wait for squid to respond -- `squid_update_every=SECONDS` the frequency of the data collection +```sh +# a space separated list of UPS names +# if empty, the list returned by 'upsc -l' will be used +nut_ups= -Example `/etc/netdata/squid.conf`: +# how frequently to collect UPS data +nut_update_every=2 +``` + +--- + +# postfix + +The plugin will collect the postfix queue size. + +It will create two charts: + +1. **queue size in emails** +2. **queue size in KB** + +### configuration + +This is the internal default for `/etc/netdata/postfix.conf` ```sh -squid_host=127.0.0.1 -squid_port=3128 -squid_url="cache_object://127.0.0.1:3128/counters" -squid_timeout=2 -squid_update_every=5 +# the postqueue command +# if empty, it will use the one found in the system path +postfix_postqueue= + +# how frequently to collect queue size +postfix_update_every=15 ``` --- @@ -189,113 +282,63 @@ sensors_excluded=() --- -# hddtemp - -The plugin will collect temperatures from disks - -It will create one chart with all active disks - -1. **temperature in Celsius** - -### configuration - -hddtemp needs to be running in daemonized mode - -```sh -# host with daemonized hddtemp -hddtemp_host="localhost" - -# port on which hddtemp is showing data -hddtemp_port="7634" - -# array of included disks -# the default is to include all -hddtemp_disks=() -``` - ---- - -# postfix - -The plugin will collect the postfix queue size. - -It will create two charts: - -1. **queue size in emails** -2. **queue size in KB** - -### configuration - -This is the internal default for `/etc/netdata/postfix.conf` - -```sh -# the postqueue command -# if empty, it will use the one found in the system path -postfix_postqueue= - -# how frequently to collect queue size -postfix_update_every=15 -``` - ---- - -# nut - -The plugin will collect UPS data for all UPSes configured in the system. - -The following charts will be created: +# squid -1. **UPS Charge** +The plugin will monitor a squid server. - * percentage changed +It will produce 4 charts: -2. **UPS Battery Voltage** +1. **Squid Client Bandwidth** in kbps - * current voltage - * high voltage - * low voltage - * nominal voltage + * in + * out + * hits -3. **UPS Input Voltage** +2. **Squid Client Requests** in requests/sec - * current voltage - * fault voltage - * nominal voltage + * requests + * hits + * errors -4. **UPS Input Current** +3. **Squid Server Bandwidth** in kbps - * nominal current + * in + * out -5. **UPS Input Frequency** +4. **Squid Server Requests** in requests/sec - * current frequency - * nominal frequency + * requests + * errors -6. **UPS Output Voltage** +### autoconfig - * current voltage +The plugin will by itself detect squid servers running on +localhost, on ports 3128 or 8080. -7. **UPS Load** +It will attempt to download URLs in the form: - * current load +- `cache_object://HOST:PORT/counters` +- `/squid-internal-mgr/counters` -8. **UPS Temperature** +If any succeeds, it will use this. - * current temperature +### configuration +If you need to configure it by hand, create the file +`/etc/netdata/squid.conf` with the following variables: -### configuration +- `squid_host=IP` the IP of the squid host +- `squid_port=PORT` the port the squid is listening +- `squid_url="URL"` the URL with the statistics to be fetched from squid +- `squid_timeout=SECONDS` how much time we should wait for squid to respond +- `squid_update_every=SECONDS` the frequency of the data collection -This is the internal default for `/etc/netdata/nut.conf` +Example `/etc/netdata/squid.conf`: ```sh -# a space separated list of UPS names -# if empty, the list returned by 'upsc -l' will be used -nut_ups= - -# how frequently to collect UPS data -nut_update_every=2 +squid_host=127.0.0.1 +squid_port=3128 +squid_url="cache_object://127.0.0.1:3128/counters" +squid_timeout=2 +squid_update_every=5 ``` - ---- - diff --git a/charts.d/apcupsd.chart.sh b/charts.d/apcupsd.chart.sh index 46a86101c..9878fd36c 100644 --- a/charts.d/apcupsd.chart.sh +++ b/charts.d/apcupsd.chart.sh @@ -6,8 +6,12 @@ # GPL v3+ # -apcupsd_ip=127.0.0.1 -apcupsd_port=3551 +apcupsd_ip= +apcupsd_port= + +declare -A apcupsd_sources=( + ["local"]="127.0.0.1:3551" +) # how frequently to collect UPS data apcupsd_update_every=10 @@ -18,7 +22,7 @@ apcupsd_timeout=3 apcupsd_priority=90000 apcupsd_get() { - run -t $apcupsd_timeout apcaccess status "$1:$2" + run -t $apcupsd_timeout apcaccess status "$1" } apcupsd_check() { @@ -29,52 +33,76 @@ apcupsd_check() { require_cmd apcaccess || return 1 - run apcupsd_get $apcupsd_ip $apcupsd_port >/dev/null - if [ $? -ne 0 ] - then - error "cannot get information for apcupsd server." - return 1 - elif [ $(apcupsd_get $apcupsd_ip $apcupsd_port | awk '/^STATUS.*/{ print $3 }') != "ONLINE" ] - then - error "APC UPS not online." - return 1 + # backwards compatibility + if [ "${apcupsd_ip}:${apcupsd_port}" != ":" ] + then + apcupsd_sources["local"]="${apcupsd_ip}:${apcupsd_port}" fi + local host working=0 failed=0 + for host in "${!apcupsd_sources[@]}" + do + run apcupsd_get "${apcupsd_sources[${host}]}" >/dev/null + if [ $? -ne 0 ] + then + error "cannot get information for apcupsd server ${host} on ${apcupsd_sources[${host}]}." + failed=$((failed + 1)) + elif [ $(apcupsd_get "${apcupsd_sources[${host}]}" | awk '/^STATUS.*/{ print $3 }') != "ONLINE" ] + then + error "APC UPS ${host} on ${apcupsd_sources[${host}]} is not online." + failed=$((failed + 1)) + else + working=$((working + 1)) + fi + done + + if [ ${working} -eq 0 ] + then + error "No APC UPSes found available." + return 1 + fi + return 0 } apcupsd_create() { - # create the charts - cat <<EOF -CHART apcupsd.charge '' "UPS Charge" "percentage" ups apcupsd.charge area $((apcupsd_priority + 1)) $apcupsd_update_every + local host src + for host in "${!apcupsd_sources[@]}" + do + src=${apcupsd_sources[${host}]} + + # create the charts + cat <<EOF +CHART apcupsd_${host}.charge '' "UPS Charge for ${host} on ${src}" "percentage" ups apcupsd.charge area $((apcupsd_priority + 1)) $apcupsd_update_every DIMENSION battery_charge charge absolute 1 100 -CHART apcupsd.battery_voltage '' "UPS Battery Voltage" "Volts" ups apcupsd.battery.voltage line $((apcupsd_priority + 3)) $apcupsd_update_every +CHART apcupsd_${host}.battery_voltage '' "UPS Battery Voltage for ${host} on ${src}" "Volts" ups apcupsd.battery.voltage line $((apcupsd_priority + 3)) $apcupsd_update_every DIMENSION battery_voltage voltage absolute 1 100 DIMENSION battery_voltage_nominal nominal absolute 1 100 -CHART apcupsd.input_voltage '' "UPS Input Voltage" "Volts" input apcupsd.input.voltage line $((apcupsd_priority + 4)) $apcupsd_update_every +CHART apcupsd_${host}.input_voltage '' "UPS Input Voltage for ${host} on ${src}" "Volts" input apcupsd.input.voltage line $((apcupsd_priority + 4)) $apcupsd_update_every DIMENSION input_voltage voltage absolute 1 100 DIMENSION input_voltage_min min absolute 1 100 DIMENSION input_voltage_max max absolute 1 100 -CHART apcupsd.input_frequency '' "UPS Input Frequency" "Hz" input apcupsd.input.frequency line $((apcupsd_priority + 5)) $apcupsd_update_every +CHART apcupsd_${host}.input_frequency '' "UPS Input Frequency for ${host} on ${src}" "Hz" input apcupsd.input.frequency line $((apcupsd_priority + 5)) $apcupsd_update_every DIMENSION input_frequency frequency absolute 1 100 -CHART apcupsd.output_voltage '' "UPS Output Voltage" "Volts" output apcupsd.output.voltage line $((apcupsd_priority + 6)) $apcupsd_update_every +CHART apcupsd_${host}.output_voltage '' "UPS Output Voltage for ${host} on ${src}" "Volts" output apcupsd.output.voltage line $((apcupsd_priority + 6)) $apcupsd_update_every DIMENSION output_voltage voltage absolute 1 100 DIMENSION output_voltage_nominal nominal absolute 1 100 -CHART apcupsd.load '' "UPS Load" "percentage" ups apcupsd.load area $((apcupsd_priority)) $apcupsd_update_every +CHART apcupsd_${host}.load '' "UPS Load for ${host} on ${src}" "percentage" ups apcupsd.load area $((apcupsd_priority)) $apcupsd_update_every DIMENSION load load absolute 1 100 -CHART apcupsd.temp '' "UPS Temperature" "Celsius" ups apcupsd.temperature line $((apcupsd_priority + 7)) $apcupsd_update_every +CHART apcupsd_${host}.temp '' "UPS Temperature for ${host} on ${src}" "Celsius" ups apcupsd.temperature line $((apcupsd_priority + 7)) $apcupsd_update_every DIMENSION temp temp absolute 1 100 -CHART apcupsd.time '' "UPS Time Remaining" "Minutes" ups apcupsd.time area $((apcupsd_priority + 2)) $apcupsd_update_every +CHART apcupsd_${host}.time '' "UPS Time Remaining for ${host} on ${src}" "Minutes" ups apcupsd.time area $((apcupsd_priority + 2)) $apcupsd_update_every DIMENSION time time absolute 1 100 EOF + done return 0 } @@ -87,7 +115,10 @@ apcupsd_update() { # for each dimension # remember: KEEP IT SIMPLE AND SHORT - apcupsd_get $apcupsd_ip $apcupsd_port | awk " + local host working=0 failed=0 + for host in "${!apcupsd_sources[@]}" + do + apcupsd_get "${apcupsd_sources[${host}]}" | awk " BEGIN { battery_charge = 0; @@ -116,43 +147,52 @@ BEGIN { /^ITEMP.*/ { temp = \$3 * 100 }; /^TIMELEFT.*/ { time = \$3 * 100 }; END { - print \"BEGIN apcupsd.charge $1\"; + print \"BEGIN apcupsd_${host}.charge $1\"; print \"SET battery_charge = \" battery_charge; print \"END\" - print \"BEGIN apcupsd.battery_voltage $1\"; + print \"BEGIN apcupsd_${host}.battery_voltage $1\"; print \"SET battery_voltage = \" battery_voltage; print \"SET battery_voltage_nominal = \" battery_voltage_nominal; print \"END\" - print \"BEGIN apcupsd.input_voltage $1\"; + print \"BEGIN apcupsd_${host}.input_voltage $1\"; print \"SET input_voltage = \" input_voltage; print \"SET input_voltage_min = \" input_voltage_min; print \"SET input_voltage_max = \" input_voltage_max; print \"END\" - print \"BEGIN apcupsd.input_frequency $1\"; + print \"BEGIN apcupsd_${host}.input_frequency $1\"; print \"SET input_frequency = \" input_frequency; print \"END\" - print \"BEGIN apcupsd.output_voltage $1\"; + print \"BEGIN apcupsd_${host}.output_voltage $1\"; print \"SET output_voltage = \" output_voltage; print \"SET output_voltage_nominal = \" output_voltage_nominal; print \"END\" - print \"BEGIN apcupsd.load $1\"; + print \"BEGIN apcupsd_${host}.load $1\"; print \"SET load = \" load; print \"END\" - print \"BEGIN apcupsd.temp $1\"; + print \"BEGIN apcupsd_${host}.temp $1\"; print \"SET temp = \" temp; print \"END\" - print \"BEGIN apcupsd.time $1\"; + print \"BEGIN apcupsd_${host}.time $1\"; print \"SET time = \" time; print \"END\" }" - [ $? -ne 0 ] && error "failed to get values" && return 1 + if [ $? -ne 0 ] + then + failed=$((failed + 1)) + error "failed to get values for APC UPS ${host} on ${apcupsd_sources[${host}]}" && return 1 + else + working=$((working + 1)) + fi + done + + [ $working -eq 0 ] && error "failed to get values from all APC UPSes" && return 1 return 0 } diff --git a/charts.d/libreswan.chart.sh b/charts.d/libreswan.chart.sh new file mode 100644 index 000000000..30632e9ce --- /dev/null +++ b/charts.d/libreswan.chart.sh @@ -0,0 +1,173 @@ +# no need for shebang - this file is loaded from charts.d.plugin + +# netdata +# real-time performance and health monitoring, done right! +# (C) 2018 Costa Tsaousis <costa@tsaousis.gr> +# GPL v3+ +# + +# _update_every is a special variable - it holds the number of seconds +# between the calls of the _update() function +libreswan_update_every=1 + +# the priority is used to sort the charts on the dashboard +# 1 = the first chart +libreswan_priority=90000 + +# set to 1, to run ipsec with sudo +libreswan_sudo=1 + +# global variables to store our collected data + +# [TUNNELID] = TUNNELNAME +# here we track the *latest* established tunnels +# as detected by: ipsec whack --status +declare -A libreswan_connected_tunnels=() + +# [TUNNELID] = VALUE +# here we track values of all established tunnels (not only the latest) +# as detected by: ipsec whack --trafficstatus +declare -A libreswan_traffic_in=() +declare -A libreswan_traffic_out=() +declare -A libreswan_established_add_time=() + +# [TUNNELNAME] = CHARTID +# here we remember CHARTIDs of all tunnels +# we need this to avoid converting tunnel names to chart IDs on every iteration +declare -A libreswan_tunnel_charts=() + +# run the ipsec command +libreswan_ipsec() { + if [ ${libreswan_sudo} -ne 0 ] + then + sudo -n "${IPSEC_CMD}" "${@}" + return $? + else + "${IPSEC_CMD}" "${@}" + return $? + fi +} + +# fetch latest values - fill the arrays +libreswan_get() { + # do all the work to collect / calculate the values + # for each dimension + + # empty the variables + libreswan_traffic_in=() + libreswan_traffic_out=() + libreswan_established_add_time=() + libreswan_connected_tunnels=() + + # convert the ipsec command output to a shell script + # and source it to get the values + source <( + { + libreswan_ipsec whack --status; + libreswan_ipsec whack --trafficstatus; + } | sed -n \ + -e "s|[0-9]\+ #\([0-9]\+\): \"\(.*\)\".*IPsec SA established.*newest IPSEC.*|libreswan_connected_tunnels[\"\1\"]=\"\2\"|p" \ + -e "s|[0-9]\+ #\([0-9]\+\): \"\(.*\)\",.* add_time=\([0-9]\+\),.* inBytes=\([0-9]\+\),.* outBytes=\([0-9]\+\).*|libreswan_traffic_in[\"\1\"]=\"\4\"; libreswan_traffic_out[\"\1\"]=\"\5\"; libreswan_established_add_time[\"\1\"]=\"\3\";|p" + ) || return 1 + + # check we got some data + [ ${#libreswan_connected_tunnels[@]} -eq 0 ] && return 1 + + return 0 +} + +# _check is called once, to find out if this chart should be enabled or not +libreswan_check() { + # this should return: + # - 0 to enable the chart + # - 1 to disable the chart + + require_cmd ipsec || return 1 + + # make sure it is libreswan + if [ -z "$(ipsec --version | grep -i libreswan)" ] + then + error "ipsec command is not Libreswan. Disabling Libreswan plugin." + return 1 + fi + + # check that we can collect data + libreswan_get || return 1 + + return 0 +} + +# create the charts for an ipsec tunnel +libreswan_create_one() { + local n="${1}" name + + name="${libreswan_connected_tunnels[${n}]}" + + [ ! -z "${libreswan_tunnel_charts[${name}]}" ] && return 0 + + libreswan_tunnel_charts[${name}]="$(fixid "${name}")" + + cat <<EOF +CHART libreswan.${libreswan_tunnel_charts[${name}]}_net '${name}_net' "LibreSWAN Tunnel ${name} Traffic" "kilobits/s" "${name}" libreswan.net area $((libreswan_priority)) $libreswan_update_every +DIMENSION in '' incremental 8 1000 +DIMENSION out '' incremental -8 1000 +CHART libreswan.${libreswan_tunnel_charts[${name}]}_uptime '${name}_uptime' "LibreSWAN Tunnel ${name} Uptime" "seconds" "${name}" libreswan.uptime line $((libreswan_priority + 1)) $libreswan_update_every +DIMENSION uptime '' absolute 1 1 +EOF + + return 0 + +} + +# _create is called once, to create the charts +libreswan_create() { + local n + for n in "${!libreswan_connected_tunnels[@]}" + do + libreswan_create_one "${n}" + done + return 0 +} + +libreswan_now=$(date +%s) + +# send the values to netdata for an ipsec tunnel +libreswan_update_one() { + local n="${1}" microseconds="${2}" name id uptime + + name="${libreswan_connected_tunnels[${n}]}" + id="${libreswan_tunnel_charts[${name}]}" + + [ -z "${id}" ] && libreswan_create_one "${name}" + + uptime=$(( ${libreswan_now} - ${libreswan_established_add_time[${n}]} )) + [ ${uptime} -lt 0 ] && uptime=0 + + # write the result of the work. + cat <<VALUESEOF +BEGIN libreswan.${id}_net ${microseconds} +SET in = ${libreswan_traffic_in[${n}]} +SET out = ${libreswan_traffic_out[${n}]} +END +BEGIN libreswan.${id}_uptime ${microseconds} +SET uptime = ${uptime} +END +VALUESEOF +} + +# _update is called continiously, to collect the values +libreswan_update() { + # the first argument to this function is the microseconds since last update + # pass this parameter to the BEGIN statement (see bellow). + + libreswan_get || return 1 + libreswan_now=$(date +%s) + + local n + for n in "${!libreswan_connected_tunnels[@]}" + do + libreswan_update_one "${n}" "${@}" + done + + return 0 +} |