diff --git a/plugins/router/mikrotik_system b/plugins/router/mikrotik_system new file mode 100644 index 00000000..ef412ade --- /dev/null +++ b/plugins/router/mikrotik_system @@ -0,0 +1,486 @@ +#!/bin/bash +#%# family=auto + +: << EOF +=head1 NAME +mikrotik_system - This plugin fetches multiple Values from a mikrotik device. + +=head1 CONFIGURATION +tested with a RB750GR3, RB5009 and CRS309. +Dependencies: +- sshpass + +A User is needed for this plugin to work: +/user add name=munin group=read password=hallowelt address= + +plugin config: +[mt_system_] +user root +env.ssh_user munin +env.ssh_password hallowelt +env.ssh_host 192.168.2.1 + +=head1 AUTHOR +=over 4 +=item * Michael Grote +=back + +=head1 LICENSE +GPLv3 or later + +SPDX-License-Identifier: GPL-3.0-or-later + +=head1 MAGIC MARKERS +=begin comment +These magic markers are used by munin-node-configure when installing +munin-node. +=end comment + #%# family=auto +=cut +EOF + +# setze Variablen mit default-Werten +ssh_user=${ssh_user:-user} +ssh_password=${ssh_password:-password} +ssh_host=${ssh_host:-192.168.2.1} +c=0 # zähler; wird für verschiedene Schleifen benötigt + +# Funktionen +function get_name { + while read -r line; do + if echo "$line" | grep -q 'name:'; then + name=$(echo "$line" | grep name: | awk '{ print $2 }') + fi + done <<< "$data" +} +function get_ros_version { + while read -r line; do + if echo "$line" | grep -q 'version:'; then + if echo "$line" | cut -f2 -d" " | grep --quiet "^7\."; then + ros_version="7" + else + ros_version="6" + 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 { + # hole daten per ssh + data=$(sshpass -p "$ssh_password" ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$ssh_user"@"$ssh_host" -q ':delay 6s; /system health print; /system resource print; /system resource cpu print; /system identity print') +} +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 # für jede zeile in... ; siehe "done" + # gebe die zeile aus + # suche mit awk nach "voltage:" + # wenn gefunden: + # gebe jede zeile per print text aus + # externe/bash-variablen mit "'""'" + 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 { + while read -r line; do + # funktion wie bei den "label"-funktionen + # gib überschrift aus wenn dirtyconfig nicht gesetzt ist + # weil aufruf dann nicht in "config" erfolgt + # wenn dirtyconfig nicht gesetzt ist oder =0, gebe überschrift aus + if [ "$MUNIN_CAP_DIRTYCONFIG" = "0" ] || [ -z "$MUNIN_CAP_DIRTYCONFIG" ]; then + echo "$line" | awk '/voltage:/{ + print "multigraph voltage_graph_""'"$name"'"; + }' + fi + # entferne mit gsub das zeichen % in wert $2 + # gebe $2 aus + echo "$line" | awk '/voltage:/{ + gsub(/V/,"",$2); + print "voltage.value " $2 + }' + 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 100"; + print "bad_blocks.label bad_blocks"; + print "bad_blocks.warning 50"; + print "bad_blocks.critical 90"; + 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 '/cpu-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 '/free-memory:/{ + print "multigraph memory_graph_""'"$name"'"; + print "graph_title memory " "'"$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); + print "used_memory.critical " $2*0.9; + print "used_memory.warning " $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_"$name" + fi + while read -r line; do + echo "$line" | awk '/total-memory:/{ + gsub(/MiB/,"",$2); + print "total_memory.value " $2 + }' + done <<< "$data" + while read -r line; do + echo "$line" | awk '/free-memory:/{ + gsub(/MiB/,"",$2); + print "free_memory.value " $2 + }' + done <<< "$data" + # berechne used-memory + # gesamt + frei = benutzt + echo used_memory.value "$(echo $mem_total $mem_free | awk '{print ($1 - $2)}')" +} + +function get_disk_label { + while read -r line; do + echo "$line" | awk '/free-hdd-space:/{ + print "multigraph disk_graph_""'"$name"'"; + print "graph_title disk " "'"$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_"$name" + fi + while read -r line; do + echo "$line" | grep KiB | awk '/free-hdd-space:/ { + gsub(/KiB/,"",$2) + print "free_disk.value " $2*1024 }' + echo "$line" | grep MiB | awk '/free-hdd-space:/ { + gsub(/MiB/,"",$2) + print "free_disk.value " $2*1048576}' + echo "$line" | grep KiB | awk '/total-hdd-space:/ { + gsub(/KiB/,"",$2) + print "total_disk.value " $2*1024 }' + echo "$line" | grep MiB | awk '/total-hdd-space:/ { + gsub(/MiB/,"",$2) + print "total_disk.value " $2*1048576 }' + done <<< "$data" +} + +# rufe funktionen auf, reihenfolge ist wichtig +get_data +get_name +get_cpu_count +# munin-Logik +# wenn $1 = X; dann +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 + # gebe label aus + # wenn dirtyconfig gesetzt rufe value funktion auf + 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 +# wird nie aufgerufen wenn dirtyconfig gesetzt ist +# dann wird nur config aufgerufen und dabei werden zusätzlich die values ausgegeben +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 + +# Beispieloutput 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 + +# Beispieloutput 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 +#