summaryrefslogtreecommitdiffstats
path: root/charts.d
diff options
context:
space:
mode:
Diffstat (limited to 'charts.d')
-rw-r--r--charts.d/Makefile.am1
-rw-r--r--charts.d/Makefile.in1
-rw-r--r--charts.d/README.md293
-rw-r--r--charts.d/apcupsd.chart.sh104
-rw-r--r--charts.d/libreswan.chart.sh173
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
+}