#!/bin/sh # # Simple Bourne Shell script that implements Munin protocol and # some common Linux plugins. # # For latest version, see http://muninlite.sf.net/ # # Copyright (c) 2007-2011 Rune Nordbøe Skillingstad # # Licensed under GPLv2 (see LICENSE file for full License) # VERSION="@@VERSION@@" set -eu @@CONF@@ # Name of runtime configuration file CONFIG_FILE=/etc/munin/muninlite.conf # if plugindir_ is present in $PLUGINS, executables (scripts, binaries) in the specified path # and matching the pattern will be scanned and operated as plugins PLUGIN_DIRECTORY=/etc/munin/plugins PLUGINPATTERN="*" # Remove unwanted plugins from this list PLUGINS="@@PLUGINS@@" # ===== LIB FUNCTIONS ===== clean_fieldname() { echo "$@" | sed -e 's/^[^A-Za-z_]/_/' -e 's/[^A-Za-z0-9_]/_/g' } # ===== PLUGINS CODE ===== @@PLSTR@@ # ===== NODE CODE ===== do_list() { echo "$PLUGINS" } do_nodes() { echo "$HOSTNAME" echo "." } do_config() { if echo "$PLUGINS" | grep -qwF "$1"; then "config_$1" else echo "# Unknown service" fi echo "." } do_fetch() { if echo "$PLUGINS" | grep -qwF "$1"; then "fetch_$1" else echo "# Unknown service" fi echo "." } do_version() { echo "munins node on $HOSTNAME version: $VERSION (muninlite)" } do_quit() { exit 0 } # ===== Runtime config ===== # shellcheck source=/dev/null [ -f ${CONFIG_FILE} ] && . ${CONFIG_FILE} RES="" for PLUG in $PLUGINS; do case "$PLUG" in if_|if_err_) interface_names=$(sed 's/^ *//; s/:.*$//; / /d; /^lo$/d' /proc/net/dev) for INTER in $interface_names; do INTERRES=$(echo "$INTER" | sed -e 's/\./VLAN/' -e 's/\-/_/g') RES="$RES ${PLUG}${INTERRES}" eval "fetch_${PLUG}${INTERRES}() { 'fetch_${PLUG%_}' '$INTER'; }" eval "config_${PLUG}${INTERRES}() { 'config_${PLUG%_}' '$INTER'; }" done ;; netstat) if netstat -s >/dev/null 2>&1; then RES="$RES netstat" fi ;; wireless) if iwinfo >/dev/null 2>&1; then RES="${RES} ${PLUG}" fi ;; plugindir_) for MYPLUGIN in $(if [ -d "$PLUGIN_DIRECTORY" ]; then find -L "$PLUGIN_DIRECTORY" -type f -name "$PLUGINPATTERN"; fi); do if [ -f "$MYPLUGIN" ] && [ -x "$MYPLUGIN" ]; then # generate a name suitable for shell function names MYPLUGINNAME=$(basename "$MYPLUGIN" | sed 's/[^0-9a-zA-Z_]/_/g') # detect and avoid name collision if echo "$RES" | grep -qwF "$MYPLUGINNAME"; then MYPLUGINNAME="plugindir_$MYPLUGINNAME" fi RES="$RES $MYPLUGINNAME" eval "fetch_${MYPLUGINNAME}() { '$MYPLUGIN'; }" eval "config_${MYPLUGINNAME}() { '$MYPLUGIN' config; }" fi done ;; *) RES="$RES $PLUG" ;; esac done # sort plugin names and remove surrounding whitespace PLUGINS=$(echo "$RES" | xargs -r -n 1 echo | sort | xargs echo) # ===== MAIN LOOP ===== FUNCTIONS="list nodes config fetch version quit" HOSTNAME=$( { hostname -f || hostname || cat /proc/sys/kernel/hostname || echo "unknown"; } 2>/dev/null ) echo "# munin node at $HOSTNAME" while read -r arg0 arg1 do arg0=$(printf '%s\n' "$arg0" | xargs) arg1=$(printf '%s\n' "$arg1" | xargs) if ! echo "$FUNCTIONS" | grep -qwF -- "$arg0"; then echo "# Unknown command. Try $(echo "$FUNCTIONS" | sed -e 's/\( [[:alpha:]]\{1,\}\)/,\1/g' -e 's/,\( [[:alpha:]]\{1,\}\)$/ or\1/')" elif [ -n "$arg0" ]; then "do_$arg0" "$arg1" fi done