#!/bin/bash #%# family=auto : << EOF =head1 NAME mikrotik_system - This plugin fetches multiple Values from a mikrotik device. =head1 CONFIGURATION tested with a RB493G, 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 #