526 lines
15 KiB
Bash
Executable File
526 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
|
#%# family=auto
|
|
|
|
: << EOF
|
|
=head1 NAME
|
|
|
|
mikrotik_system - This plugin fetches multiple values from a mikrotik device.
|
|
|
|
=head1 NOTES
|
|
|
|
Tested with a RB493G, RB750GR3, RB5009, CRS305 and CRS309 on Router OS >6.49.* and >7.0.4. sshpass is a dependency for this Plugin.
|
|
|
|
=head1 CONFIGURATION
|
|
|
|
|
|
A User on the Target-Device is needed for this plugin to work:
|
|
|
|
/user add name=munin group=read password=hallowelt address=<munin-server-ip>
|
|
|
|
plugin config:
|
|
[mt_system_<name>]
|
|
user root
|
|
env.ssh_user munin
|
|
env.ssh_password hallowelt
|
|
env.ssh_host 192.168.2.1
|
|
|
|
=head1 AUTHOR
|
|
|
|
Michael Grote - git.mgrote.net
|
|
|
|
=head1 LICENSE
|
|
|
|
GPLv3 or later
|
|
|
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
=head1 MAGIC MARKERS
|
|
|
|
#%# family=auto
|
|
#%# capabilities=autoconf
|
|
|
|
EOF
|
|
|
|
# set variables with default values
|
|
ssh_user=${ssh_user:-user}
|
|
ssh_password=${ssh_password:-password}
|
|
ssh_host=${ssh_host:-192.168.2.1}
|
|
c=0 # counter, it is used in a few loops
|
|
|
|
# Function to get stderr from command
|
|
# USAGE: catch STDOUT STDERR cmd args..
|
|
# Source: https://stackoverflow.com/a/41069638
|
|
catch()
|
|
{
|
|
eval "$({
|
|
__2="$(
|
|
{ __1="$("${@:3}")"; } 2>&1;
|
|
ret=$?;
|
|
printf '%q=%q\n' "$1" "$__1" >&2;
|
|
exit $ret
|
|
)";
|
|
ret="$?";
|
|
printf '%s=%q\n' "$2" "$__2" >&2;
|
|
printf '( exit %q )' "$ret" >&2;
|
|
} 2>&1 )";
|
|
}
|
|
|
|
# functions
|
|
function get_name {
|
|
local fname
|
|
IFS=$'\n'; for line in $data; do
|
|
if echo "$line" | grep -q 'name:'; then
|
|
fname="$(echo "$line" | cut -d: -f2 | xargs | sed 's/[\s\n\r]*$//g' | sed 's/[^A-Za-z0-9]/_/g')"
|
|
if [ -n "$fname" ]; then
|
|
name="$fname"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
function get_ros_version {
|
|
while read -r line; do
|
|
if echo "$line" | grep -q 'version: '; then
|
|
if echo "$line" | awk '/version:/{print $2}' | grep -q "^[0-6]\."; then
|
|
ros_version="6"
|
|
else
|
|
ros_version="7"
|
|
fi
|
|
fi
|
|
done <<< "$data"
|
|
}
|
|
function get_cpu_count {
|
|
while read -r line; do
|
|
if echo "$line" | grep -q 'cpu-count'; then
|
|
anzahl_cpu=$(echo "$line" | grep cpu-count: | sed -r 's/(cpu-count: )([0-9]+)/\2/g' | tr -dc '0-9')
|
|
fi
|
|
done <<< "$data"
|
|
}
|
|
function get_data {
|
|
# fetch data per ssh
|
|
catch data stderr sshpass -p "$ssh_password" ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_user"@"$ssh_host" ':delay 6s; /system health print; /system resource print; /system resource cpu print; /system identity print'
|
|
data_ret=$?
|
|
}
|
|
function validate_data {
|
|
if [ $data_ret -ne 0 ]; then
|
|
echo "SSH returned errorcode = $data_ret:"
|
|
echo "$stderr"
|
|
exit $data_ret
|
|
fi
|
|
}
|
|
function get_mem_total {
|
|
mem_total=$(
|
|
while read -r line; do
|
|
echo "$line" | awk '/total-memory:/{ gsub(/MiB/,"",$2); print $2 }' | tr -dc '0-9.'
|
|
done <<< "$data")
|
|
}
|
|
function get_mem_free {
|
|
mem_free=$(
|
|
while read -r line; do
|
|
echo "$line" | awk '/free-memory:/{ gsub(/MiB/,"",$2); print $2 }' | tr -dc '0-9.'
|
|
done <<< "$data")
|
|
}
|
|
|
|
function get_voltage_label {
|
|
while read -r line; do # for every line
|
|
# output line
|
|
# search with awk for "voltage:"
|
|
# if found
|
|
# print line
|
|
# external/bash-variables with "'"<var>"'"
|
|
echo "$line" | awk '/voltage/{
|
|
print "multigraph voltage_graph_""'"$name"'";
|
|
print "graph_title voltage " "'"$name"'";
|
|
print "graph_vlabel volt";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0";
|
|
print "voltage.label voltage";
|
|
print "graph_info Input Voltage."
|
|
}'
|
|
done <<< "$data" # der variable data
|
|
}
|
|
function get_voltage_value {
|
|
get_ros_version
|
|
while read -r line; do
|
|
# like the label functions
|
|
# print title if dirtyconfig is not set
|
|
# because the call does not come in "config"
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo "$line" | awk '/voltage/{
|
|
print "multigraph voltage_graph_""'"$name"'";
|
|
}'
|
|
fi
|
|
if [ "$ros_version" == "6" ]; then
|
|
# remove with gsub the char % in argument $2
|
|
# print $2
|
|
echo "$line" | awk '/voltage/{
|
|
gsub(/V/,"",$2);
|
|
print "voltage.value " $2
|
|
}'
|
|
fi
|
|
if [ "$ros_version" == "7" ]; then
|
|
echo "$line" | awk '/voltage/{
|
|
print "voltage.value " $3
|
|
}'
|
|
fi
|
|
done <<< "$data"
|
|
}
|
|
|
|
function get_bad_blocks_label {
|
|
while read -r line; do
|
|
echo "$line" | awk '/bad-blocks:/{
|
|
print "multigraph bad_blocks_graph_""'"$name"'";
|
|
print "graph_title bad blocks " "'"$name"'";
|
|
print "graph_vlabel %";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0 --upper-limit 5";
|
|
print "bad_blocks.label bad_blocks";
|
|
print "bad_blocks.warning 3";
|
|
print "bad_blocks.critical 4";
|
|
print "graph_info Percentage of Bad Blocks."
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
function get_bad_blocks_value {
|
|
while read -r line; do
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo "$line" | awk '/bad-blocks:/{
|
|
print "multigraph bad_blocks_graph_""'"$name"'";
|
|
}'
|
|
fi
|
|
echo "$line" | awk '/bad-blocks:/{
|
|
gsub(/%/,"",$2);
|
|
print "bad_blocks.value " $2
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
|
|
function get_write_sect_total_label {
|
|
while read -r line; do
|
|
echo "$line" | awk '/write-sect-total:/{
|
|
print "multigraph write_sect_total_graph_""'"$name"'";
|
|
print "graph_title Total sector writes " "'"$name"'";
|
|
print "graph_vlabel count";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0";
|
|
print "write_sect_total.label write_sect_total";
|
|
print "graph_info Total sector writes."
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
function get_write_sect_total_value {
|
|
while read -r line; do
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo "$line" | awk '/write-sect-total:/{
|
|
print "multigraph write_sect_total_graph_'"$name"'";
|
|
}'
|
|
fi
|
|
echo "$line" | awk '/write-sect-total:/{
|
|
print "write_sect_total.value " $2
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
|
|
function get_write_sect_since_reboot_label {
|
|
while read -r line; do
|
|
echo "$line" | awk '/write-sect-since-reboot:/{
|
|
print "multigraph write_sect_since_reboot_graph_'"$name"'";
|
|
print "graph_title Sector writes since reboot " "'"$name"'";
|
|
print "graph_vlabel count";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0";
|
|
print "write_sect_since_reboot.label write_sect_since_reboot";
|
|
print "graph_info Total Sector writes since last reboot."
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
function get_write_sect_since_reboot_value {
|
|
while read -r line; do
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo "$line" | awk '/write-sect-since-reboot:/{
|
|
print "multigraph write_sect_since_reboot_graph_""'"$name"'";
|
|
}'
|
|
fi
|
|
echo "$line" | awk '/write-sect-since-reboot:/{
|
|
print "write_sect_since_reboot.value " $2
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
|
|
function get_temperature_label {
|
|
while read -r line; do
|
|
echo "$line" | awk '/temperature/{
|
|
print "multigraph temperature_graph_""'"$name"'";
|
|
print "graph_title temperature " "'"$name"'";
|
|
print "graph_vlabel °C";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0";
|
|
print "temperature.label cpu temperature";
|
|
print "temperature.warning 75";
|
|
print "temperature.critical 90"
|
|
}'
|
|
done <<< "$data"
|
|
}
|
|
function get_temperature_value {
|
|
get_ros_version
|
|
while read -r line; do
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo "$line" | awk '/temperature/{
|
|
print "multigraph temperature_graph_""'"$name"'";
|
|
}'
|
|
fi
|
|
if [ "$ros_version" == "6" ]; then
|
|
echo "$line" | awk '/temperature:/{
|
|
gsub(/C/,"",$2);
|
|
print "temperature.value " $2
|
|
}'
|
|
fi
|
|
if [ "$ros_version" == "7" ]; then
|
|
echo "$line" | awk '/temperature/{
|
|
print "temperature.value " $3
|
|
}'
|
|
fi
|
|
done <<< "$data"
|
|
}
|
|
|
|
function get_cpu_label {
|
|
echo multigraph cpu_load_graph_"$name"
|
|
echo graph_title cpu load "$name"
|
|
echo graph_vlabel %
|
|
echo graph_category mikrotik
|
|
echo graph_args -l 0 --upper-limit 100
|
|
echo cpu_total.label total load
|
|
echo cpu_total.warning 75
|
|
echo cpu_total.critical 90
|
|
echo graph_info Total CPU Load and Load, IRQ and Disk per Core.
|
|
|
|
while [ "$c" -lt "$anzahl_cpu" ]; do
|
|
while read -r line; do
|
|
echo "$line" | grep cpu$c | awk '{
|
|
print "cpu"'"$c"'"_load.label " "cpu" "'"$c"'" " load"
|
|
print "cpu"'"$c"'"_irq.label " "cpu" "'"$c"'" " irq"
|
|
print "cpu"'"$c"'"_disk.label " "cpu" "'"$c"'" " disk"
|
|
}'
|
|
done <<< "$data"
|
|
c=$(( c + 1 ))
|
|
done
|
|
}
|
|
function get_cpu_value {
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo multigraph cpu_load_graph_"$name"
|
|
fi
|
|
while read -r line; do
|
|
echo "$line" | awk '/cpu-load:/{
|
|
gsub(/%/,"",$2);
|
|
print "cpu_total.value " $2
|
|
}'
|
|
done <<< "$data"
|
|
c=0
|
|
while [ "$c" -lt "$anzahl_cpu" ]; do
|
|
while read -r line; do
|
|
echo "$line" | grep cpu$c | awk '{
|
|
gsub(/%/,"",$3);
|
|
gsub(/%/,"",$4);
|
|
gsub(/%/,"",$5);
|
|
print "cpu"'"$c"'"_load.value " $3
|
|
print "cpu"'"$c"'"_irq.value " $4
|
|
print "cpu"'"$c"'"_disk.value " $5
|
|
}'
|
|
done <<< "$data"
|
|
c=$(( c + 1 ))
|
|
done
|
|
}
|
|
|
|
function get_memory_label {
|
|
get_mem_total
|
|
get_mem_free
|
|
while read -r line; do
|
|
echo "$line" | awk -v name=$name '/free-memory:/{
|
|
printf "multigraph memory_graph_%s\n", name;
|
|
printf "graph_title memory %s\n", name;
|
|
print "graph_vlabel MiB";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0";
|
|
print "total_memory.label total memory";
|
|
print "used_memory.label used memory";
|
|
print "free_memory.label free memory";
|
|
print "graph_info Total, Used & free RAM.";
|
|
gsub(/MiB/,"",$2);
|
|
printf "used_memory.critical %.0f\n", $2*0.9;
|
|
printf "used_memory.warning %.0f\n", $2*0.7 }'
|
|
done <<< "$data"
|
|
}
|
|
function get_memory_value {
|
|
get_mem_total
|
|
get_mem_free
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo multigraph memory_graph_"$name"
|
|
fi
|
|
while read -r line; do
|
|
echo "$line" | awk '/total-memory:/{
|
|
gsub(/MiB/,"",$2);
|
|
printf "total_memory.value %.0f\n", $2
|
|
}'
|
|
done <<< "$data"
|
|
while read -r line; do
|
|
echo "$line" | awk '/free-memory:/{
|
|
gsub(/MiB/,"",$2);
|
|
printf "free_memory.value %.0f\n", $2
|
|
}'
|
|
done <<< "$data"
|
|
# calculate used-memory
|
|
# total - free = used
|
|
printf "used_memory.value %.0f\n" "$(echo $mem_total $mem_free | awk '{print ($1 - $2)}')"
|
|
}
|
|
|
|
function get_disk_label {
|
|
while read -r line; do
|
|
echo "$line" | awk -v name=$name '/free-hdd-space:/{
|
|
printf "multigraph disk_graph_%s\n", name;
|
|
printf "graph_title disk %s\n", name;
|
|
print "graph_vlabel Bytes";
|
|
print "graph_category mikrotik";
|
|
print "graph_args -l 0";
|
|
print "total_disk.label total disk space";
|
|
print "free_disk.label free disk space";
|
|
print "graph_info Total & free disk space."}'
|
|
done <<< "$data"
|
|
}
|
|
function get_disk_value {
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then
|
|
echo multigraph disk_graph_"$name"
|
|
fi
|
|
while read -r line; do
|
|
echo "$line" | grep KiB | awk '/free-hdd-space:/ {
|
|
gsub(/KiB/,"",$2)
|
|
printf "free_disk.value %d\n", $2*1024 }'
|
|
echo "$line" | grep MiB | awk '/free-hdd-space:/ {
|
|
gsub(/MiB/,"",$2)
|
|
printf "free_disk.value %d\n", $2*1048576}'
|
|
echo "$line" | grep KiB | awk '/total-hdd-space:/ {
|
|
gsub(/KiB/,"",$2)
|
|
printf "total_disk.value %d\n", $2*1024 }'
|
|
echo "$line" | grep MiB | awk '/total-hdd-space:/ {
|
|
gsub(/MiB/,"",$2)
|
|
printf "total_disk.value %d\n", $2*1048576 }'
|
|
done <<< "$data"
|
|
}
|
|
|
|
# call functions, the order is important
|
|
get_data
|
|
validate_data
|
|
get_name
|
|
get_cpu_count
|
|
# munin-Logic
|
|
# id $1 = X; then
|
|
if [ "$1" = "autoconf" ]; then
|
|
if ! command -v sshpass &> /dev/null; then
|
|
echo "[ERROR] sshpass could not be found!"
|
|
else
|
|
echo "yes"
|
|
fi
|
|
exit 0
|
|
fi
|
|
if [ "$1" = "config" ]; then
|
|
# print label
|
|
# if dirtyconfig is set print the value
|
|
get_voltage_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_voltage_value
|
|
fi
|
|
get_bad_blocks_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_bad_blocks_value
|
|
fi
|
|
get_write_sect_total_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_write_sect_total_value
|
|
fi
|
|
get_write_sect_since_reboot_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_write_sect_since_reboot_value
|
|
fi
|
|
get_temperature_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_temperature_value
|
|
fi
|
|
get_cpu_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_cpu_value
|
|
fi
|
|
get_memory_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_memory_value
|
|
fi
|
|
get_disk_label
|
|
if [ "$MUNIN_CAP_DIRTYCONFIG" = "1" ]; then
|
|
get_disk_value
|
|
fi
|
|
exit 0
|
|
fi
|
|
# does not get called if dirtyconfig is set
|
|
get_voltage_value
|
|
get_bad_blocks_value
|
|
get_write_sect_total_value
|
|
get_write_sect_since_reboot_value
|
|
get_temperature_value
|
|
get_cpu_value
|
|
get_memory_value
|
|
get_disk_value
|
|
exit 0
|
|
|
|
# Example Output ROS 6.4*
|
|
# voltage: 24.5V
|
|
# cpu-temperature: 31C
|
|
# uptime: 4w3d21h28m58s
|
|
# version: 6.48.4 (stable)
|
|
# build-time: Aug/18/2021 06:43:27
|
|
# factory-software: 6.44.6
|
|
# free-memory: 475.8MiB
|
|
# total-memory: 512.0MiB
|
|
# cpu: ARMv7
|
|
# cpu-count: 2
|
|
# cpu-frequency: 800MHz
|
|
# cpu-load: 9%
|
|
# free-hdd-space: 2124.0KiB
|
|
# total-hdd-space: 15.9MiB
|
|
# write-sect-since-reboot: 339810
|
|
# write-sect-total: 350544
|
|
# bad-blocks: 0%
|
|
# architecture-name: arm
|
|
# board-name: CRS309-1G-8S+
|
|
# platform: MikroTik
|
|
# # CPU LOAD IRQ DISK
|
|
# 0 cpu0 0% 0% 0%
|
|
# 1 cpu1 19% 0% 0%
|
|
# name: crs309
|
|
|
|
# Example Output ROS 7*
|
|
# Columns: NAME, VALUE, TYPE
|
|
# # NAME VA T
|
|
# 0 cpu-temperature 44 C
|
|
# uptime: 3d1h30m
|
|
# version: 7.0.5 (stable)
|
|
# build-time: Aug/06/2021 11:33:39
|
|
# factory-software: 7.0.4
|
|
# free-memory: 818.8MiB
|
|
# total-memory: 1024.0MiB
|
|
# cpu-count: 4
|
|
# cpu-frequency: 1400MHz
|
|
# cpu-load: 0%
|
|
# free-hdd-space: 993.8MiB
|
|
# total-hdd-space: 1025.0MiB
|
|
# write-sect-since-reboot: 4802
|
|
# write-sect-total: 4802
|
|
# bad-blocks: 0%
|
|
# architecture-name: arm64
|
|
# board-name: RB5009UG+S+
|
|
# platform: MikroTik
|
|
# Columns: CPU, LOAD, IRQ, DISK
|
|
# # CPU LO IR DI
|
|
# 0 cpu0 0% 0% 0%
|
|
# 1 cpu1 0% 0% 0%
|
|
# 2 cpu2 0% 0% 0%
|
|
# 3 cpu3 0% 0% 0%
|
|
# name: rb5009
|
|
#
|