contrib-munin/plugins/network/netatalk3

145 lines
4.3 KiB
Bash
Executable File

#!/bin/bash -
#
#### Abstract ################################################################
#
# Munin contributed plugin to measure open, locked and files being hold by
# Netatalk version 3.*;
#
#### Author ##################################################################
#
# Otavio Fernandes <otaviof@gmail.com>
# Wednesday, 01/01/2014
#
#### Functions ###############################################################
#
function afpd_full_path () {
echo $(which afpd |head -n 1)
}
function afp_related_file_exists () {
local afp_file_path=$1
if [ -z "$afp_file_path" -o ! -f "$afp_file_path" ]; then
echo "ERROR: AFP related file not found: \"${afpd_bin_path}\";" >&2
exit 1
fi
}
function is_netatalk_version_3 () {
local afpd_bin_path=$1
version_string="$(${afpd_bin_path} -version |head -n1 |grep '^afpd' |cut -d' ' -f2)"
if [[ $version_string != 3\.* ]]; then
cat <<EOM >&2
ERROR: Netatalk is not version 3.
Binary: ${afpd_bin_path};
Version: ${version_string};
EOM
exit 1
fi
}
function count_running_procs () {
local afpd_bin_path=$1
echo $(ps ax --no-headers -o command |grep "^${afpd_bin_path}" |wc -l)
}
function count_connected_users () {
local afpd_bin_path=$1
afpd_procs=$(ps anx --no-headers -o uid,command |grep -E "\w+\d+*\s${afpd_bin_path}" |wc -l)
# one of those processes will be always from root user, so it's not being
# used to externaly connect volumes, therefor being disconsider.
echo $(echo "${afpd_procs} - 1" |bc)
}
function base_lsof () {
local afpd_bin_path=$1
process_name="$(basename ${afpd_bin_path})"
excluded_fds="^DEL,^err,^jld,^ltx,^Mxx,^m86,^mem,^mmap,^pd,^rtd,^tr,^txt,^v86"
echo "lsof -a -c ${process_name} -d ${excluded_fds}"
}
function count_locked_files () {
local afpd_bin_path=$1
cmd_suffix="$(base_lsof "${afpd_bin_path}")"
echo "$(${cmd_suffix} -F -l |grep '^l[rRwWu]' |wc -l)"
}
function probe_afp_conf_file () {
local afpd_bin_path=$1
echo "$(${afpd_bin_path} -version 2>&1 |grep -E '^\s+afp.conf\:' |awk '{print $2}')"
}
function count_open_shares () {
local afpd_bin_path=$1
local afp_conf_path=$2
mounted=0
declare -a shares=($(grep '^path.*\=' ${afp_conf_path} |awk -F '=' '{print $2}' |sed -E 's/^\s+//g'))
if [ ! -z "$shares" ]; then
# narrowing lsof results to only list configured mount directories
cmd_lookup_prefix=$(echo ${shares[@]} |tr " " "|")
cmd_suffix="$(base_lsof "${afpd_bin_path}")"
mounted=$(${cmd_suffix} -F n |grep '^n' |egrep "(${cmd_lookup_prefix})" |wc -l)
fi
echo $mounted
}
#### Main ####################################################################
# For all routines, holds the entry points dealing with the informed parameter
# or lack of it, meaning just print out collected data.
#
case "$1" in
config)
# printing configuration for this plugin's produced data
cat <<EOM
graph_title Netatalk v3 Status
graph_title Netatalk status
graph_args --logarithmic --lower-limit 0.1
graph_vlabel Number
graph_category fs
proc.label Running processes
proc.info Running AFPd processes
proc.min 0
user.label Connected users
user.info Connected users
user.min 0
lock.label Locked files
lock.info AFPd locked files
lock.min 0
share.label Open shares
share.info Netatalk open shares
share.min 0
EOM
exit 0
;;
*)
#### Boilerplates ####################################################
# Locating AFP related files:
# * Binary: Using the first result of "which" command;
# * Config: Using "afpd" with parameters to pring configuration file
# location;
#
AFPD_PATH="$(afpd_full_path)"
afp_related_file_exists "${AFPD_PATH}"
is_netatalk_version_3 "${AFPD_PATH}"
AFP_CONF_PATH="$(probe_afp_conf_file "${AFPD_PATH}")"
afp_related_file_exists "${AFP_CONF_PATH}"
#### Collecting Metrics ##############################################
#
echo "proc.value" $(count_running_procs "${AFPD_PATH}")
echo "user.value" $(count_connected_users "${AFPD_PATH}")
echo "lock.value" $(count_locked_files "${AFPD_PATH}")
echo "share.value" $(count_open_shares "${AFPD_PATH}" "${AFP_CONF_PATH}")
exit 0
;;
esac
# EOF