2020-04-04 11:57:16 +02:00
|
|
|
#!/usr/bin/env bash
|
2017-07-18 23:06:11 +02:00
|
|
|
#
|
2017-07-20 15:10:15 +02:00
|
|
|
# MOTDs32 powered by Erreur32
|
|
|
|
# Original Author: Krigler Pavol
|
|
|
|
# Version 0.0.5
|
2017-07-18 23:06:11 +02:00
|
|
|
#
|
|
|
|
# MOTDs32 is dynamicaly refreshing the /etc/motd file with current informations
|
2020-04-04 11:57:16 +02:00
|
|
|
# about system status and usage.
|
2017-07-18 23:06:11 +02:00
|
|
|
#
|
|
|
|
# Copyright 2013 Pavol Krigler <pavol.krigler@gelogic.net>
|
|
|
|
#
|
2017-07-20 15:10:15 +02:00
|
|
|
|
2017-07-31 18:49:01 +02:00
|
|
|
if [[ $EUID -ne 0 ]]; then
|
2017-07-31 21:03:36 +02:00
|
|
|
echo " Need to be ROOT to executing this file" 1>&2
|
2017-07-31 18:49:01 +02:00
|
|
|
else
|
|
|
|
/bin/bash /etc/motds32/Stats32 > /etc/motds32/Stats32.txt
|
2017-07-31 21:03:36 +02:00
|
|
|
# echo -e "\n Generating Stats file" 1>&2
|
2017-07-31 18:49:01 +02:00
|
|
|
fi
|
2017-07-31 16:27:03 +02:00
|
|
|
|
2017-07-18 23:06:11 +02:00
|
|
|
# Path to the configuration file
|
|
|
|
CONFIGFILE="/etc/motds32/motds32.conf"
|
|
|
|
|
|
|
|
# Message of the day file
|
|
|
|
MOTD='/etc/motd'
|
|
|
|
MOTD32="/etc/motds32/Stats32"
|
|
|
|
PRG32="/etc/motds32"
|
2020-04-04 11:57:16 +02:00
|
|
|
# List of network services which MUST be running
|
2017-07-18 23:06:11 +02:00
|
|
|
NETSERVICE_LIST="/etc/motds32/netservice"
|
|
|
|
|
|
|
|
# List of processes which MUST be running
|
|
|
|
PROCESS_LIST="/etc/motds32/process"
|
|
|
|
|
|
|
|
# List of partitions and usage limits
|
|
|
|
PARTITION_TABLE="/etc/motds32/fstab_limits"
|
|
|
|
|
|
|
|
# List of processes which could be autodiscovered during installation
|
|
|
|
AUTO_PROCESS_DISCOVERY="sshd apache dhcpd named ntpd nscd postfix slapd smbd atd crond smartd dovecot master mysqld"
|
|
|
|
|
|
|
|
# List of network ports which could be autodiscovered during installation
|
2017-07-21 13:19:26 +02:00
|
|
|
AUTO_NETSERVICE_DISCOVERY="21 22 25 80 443 123 8080"
|
2017-07-18 23:06:11 +02:00
|
|
|
|
|
|
|
#
|
|
|
|
# Do not modify lines below
|
|
|
|
#
|
2017-07-21 13:19:26 +02:00
|
|
|
VERSION="0.1"
|
2017-07-18 23:06:11 +02:00
|
|
|
LINES=0
|
|
|
|
|
|
|
|
TMPDIR="/tmp"
|
|
|
|
STATS_DIR="/var/cache/motds32"
|
|
|
|
COLL_MEM="$TMPDIR/.motds32_mem_$$"
|
|
|
|
COLL_DISK="$TMPDIR/.motds32_disk_$$"
|
|
|
|
COLL_PROC="$TMPDIR/.motds32_proc_$$"
|
2017-07-21 13:19:26 +02:00
|
|
|
COLL_WALL="$TMPDIR/.motdstat_wall_$$"
|
2017-07-18 23:06:11 +02:00
|
|
|
COLL_EMPTY="$TMPDIR/.motds32_empty_$$"
|
|
|
|
|
2020-04-04 11:57:16 +02:00
|
|
|
# Set default VARIABLES
|
2017-07-18 23:06:11 +02:00
|
|
|
function set_default_values() {
|
|
|
|
DISK_USAGE_WARNING=80
|
|
|
|
DISK_USAGE_CRITICAL=90
|
|
|
|
SWAP_USAGE_WARNING=10
|
|
|
|
SWAP_USAGE_CRITICAL=30
|
|
|
|
CPU_WARNING=90
|
|
|
|
CPU_CRITICAL=100
|
|
|
|
MAX_ROWS_LIMIT=15
|
|
|
|
MAILQ_WARNING=0
|
|
|
|
CHECK_NTP="NO"
|
|
|
|
ENABLE_SYSLOG="NO"
|
|
|
|
NTP_PROBLEM_EXEC=""
|
|
|
|
LOAD_TRESHOLD_EXEC=""
|
|
|
|
SWAP_TRESHOLD_EXEC=""
|
|
|
|
DISK_TRESHOLD_EXEC=""
|
|
|
|
}
|
|
|
|
|
|
|
|
# Clean temporary files
|
|
|
|
test -e $COLL_EMPTY && rm -f $COLL_EMPTY
|
|
|
|
|
|
|
|
# Make a copy of original MOTD file if exits
|
|
|
|
if [ ! -e "${MOTD}.orig" ]; then
|
|
|
|
test -e ${MOTD} && cp $MOTD ${MOTD}.orig || touch ${MOTD}.orig
|
|
|
|
fi
|
|
|
|
|
|
|
|
#
|
|
|
|
# Generate stats data
|
|
|
|
#
|
2017-07-21 13:19:26 +02:00
|
|
|
## not use yet
|
2017-07-18 23:06:11 +02:00
|
|
|
function stats_data() {
|
|
|
|
#make stats file in the good directory
|
|
|
|
$MOTD32 > $PRG32/Stats32.txt
|
|
|
|
}
|
|
|
|
#$stats_data
|
|
|
|
#$MOTD32 > $PRG32/Stats32.txt
|
2017-07-21 13:19:26 +02:00
|
|
|
|
|
|
|
|
2017-07-18 23:06:11 +02:00
|
|
|
#
|
|
|
|
# Append message to the report (and to syslog if enabled)
|
|
|
|
#
|
|
|
|
function report() {
|
|
|
|
REPORT=$REPORT"${1}\n"
|
2020-04-04 11:57:16 +02:00
|
|
|
test $ENABLE_SYSLOG = "YES" && logger -t motds32 -- "${1}"
|
2017-07-18 23:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Colored text
|
|
|
|
#
|
|
|
|
function red () {
|
|
|
|
echo -e "\e[1;31m$1\e[0;39m"
|
|
|
|
}
|
|
|
|
|
|
|
|
function green () {
|
|
|
|
echo -e "\e[1;32m$1\e[0;39m"
|
|
|
|
}
|
|
|
|
|
|
|
|
function yellow () {
|
|
|
|
echo -e "\e[1;33m$1\e[0;39m"
|
|
|
|
}
|
|
|
|
|
|
|
|
function bold () {
|
|
|
|
echo -e "\033[1m$1\033[0m"
|
|
|
|
}
|
|
|
|
|
2017-07-21 13:19:26 +02:00
|
|
|
# Trim the line to 24 , (32 is better) characters
|
2017-07-18 23:06:11 +02:00
|
|
|
function normalize() {
|
|
|
|
LENGTH=$(echo $PART | wc -c)
|
|
|
|
|
2017-07-21 13:19:26 +02:00
|
|
|
if [ $LENGTH -gt 32 ]; then
|
2017-07-18 23:06:11 +02:00
|
|
|
CUT=$(echo $PART | sed -e 's/^\(.......\).*\(.............\)/\1...\2/')
|
|
|
|
PART=$CUT
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Generate list of the most used processess
|
|
|
|
#
|
|
|
|
function gen_process_list() {
|
|
|
|
local PROCESS
|
|
|
|
local PGREP
|
|
|
|
|
|
|
|
echo "Generating \"process\" configuration file to ${PROCESS_LIST} from autodiscovery"
|
|
|
|
|
|
|
|
# Generate process file header
|
|
|
|
echo "#" > ${PROCESS_LIST}
|
|
|
|
echo "# List of processes that MUST be running" >> ${PROCESS_LIST}
|
|
|
|
echo "#" >> ${PROCESS_LIST}
|
|
|
|
echo "# (The following processes where found through autodiscovery)" >> ${PROCESS_LIST}
|
|
|
|
|
|
|
|
test $(which pgrep 2>/dev/null >/dev/null && echo OK || echo NOK) != "OK" && return
|
|
|
|
|
|
|
|
for PROCESS in ${AUTO_PROCESS_DISCOVERY}; do
|
|
|
|
pgrep -x ${PROCESS} > /dev/null
|
|
|
|
PGREP=$?
|
|
|
|
test ${PGREP} -eq 0 && echo ${PROCESS} >> ${PROCESS_LIST}
|
2020-04-04 11:57:16 +02:00
|
|
|
done
|
2017-07-18 23:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Generate netservice list
|
|
|
|
#
|
|
|
|
function gen_netservice_list() {
|
|
|
|
local NETSTAT
|
|
|
|
local ENTRY
|
|
|
|
local RESULT
|
|
|
|
|
|
|
|
echo "Generating \"netservice\" configuration file to ${NETSERVICE_LIST} from autodiscovery"
|
|
|
|
|
|
|
|
# Generate process file header
|
|
|
|
echo "#" > ${NETSERVICE_LIST}
|
|
|
|
echo "# List of local network services that MUST be running" >> ${NETSERVICE_LIST}
|
|
|
|
echo "#" >> ${NETSERVICE_LIST}
|
|
|
|
echo "# (The following processes where found through autodiscovery)" >> ${NETSERVICE_LIST}
|
|
|
|
echo "# PROTOCOL IP_ADDRESS:PORT PROCESS NAME" >> ${NETSERVICE_LIST}
|
|
|
|
|
|
|
|
test $(which netstat 2>/dev/null >/dev/null && echo OK || echo NOK) != "OK" && return
|
|
|
|
|
|
|
|
NETSTAT=$(netstat -nlp | egrep "^tcp *|^udp *" | sed -e 's/[0-9]*\///' | sed -e 's/LISTEN//' | sed -e 's/: .*$//' | awk '{printf "%-13s%-30s %s\n", $1, $4, $6}')
|
|
|
|
|
|
|
|
for ENTRY in ${AUTO_NETSERVICE_DISCOVERY}; do
|
|
|
|
RESULT=$(echo "${NETSTAT}" | egrep ":${ENTRY} *")
|
|
|
|
test -n "${RESULT}" && echo "${RESULT}" >> ${NETSERVICE_LIST}
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# Process status
|
|
|
|
function checkprocess {
|
|
|
|
test ! -f ${PROCESS_LIST} && gen_process_list
|
|
|
|
|
|
|
|
if [ -s ${PROCESS_LIST} ]; then
|
|
|
|
for PROC in $(egrep -v "^#|^$" ${PROCESS_LIST}); do
|
|
|
|
PROCES=$(ps ax | grep "$PROC" | grep -v "grep" | grep -vc "checkclient")
|
|
|
|
if [ $PROCES -gt 0 ]; then
|
|
|
|
if [ $PROCES -eq 1 ]; then
|
|
|
|
green "$PROC" >> $COLL_PROC
|
|
|
|
else
|
2017-07-21 13:19:26 +02:00
|
|
|
#green "$PROC ($PROCES)" | awk '{printf("%-26s %4s\n", $1, $2)}' >> $COLL_PROC
|
|
|
|
green "$PROC ($PROCES)" | awk '{printf("%-27s %4s\n", $1, $2)}' >> $COLL_PROC
|
2017-07-18 23:06:11 +02:00
|
|
|
fi
|
|
|
|
else
|
2017-07-21 13:19:26 +02:00
|
|
|
report "CRITICAL: Process \"${PROC}\" is not running"
|
|
|
|
#red "$PROC is not running" >> $COLL_PROC
|
|
|
|
red "$(printf "%-9.9s is not running" $PROC)" >> $COLL_PROC
|
2017-07-18 23:06:11 +02:00
|
|
|
NOT_RUNNING=1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
cp $COLL_PROC ${COLL_PROC}.tmp
|
|
|
|
|
|
|
|
test -n "$NOT_RUNNING" && red " Service status " > $COLL_PROC || green " Service status " > $COLL_PROC
|
|
|
|
|
|
|
|
cat ${COLL_PROC}.tmp >> $COLL_PROC
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Memory status
|
|
|
|
function memory() {
|
|
|
|
bold "Memory used kB [%]" > $COLL_MEM
|
|
|
|
MEMTOTAL=$(grep "MemTotal" /proc/meminfo | awk '{print $2}')
|
|
|
|
MEMFREE=$(grep "MemFree" /proc/meminfo | awk '{print $2}')
|
|
|
|
SWAPTOTAL=$(grep "SwapTotal" /proc/meminfo | awk '{print $2}')
|
|
|
|
SWAPFREE=$(grep "SwapFree" /proc/meminfo | awk '{print $2}')
|
|
|
|
|
|
|
|
PERCENTOM=$(echo $MEMFREE $MEMTOTAL | awk '{printf("%d", ($2-$1)/$2*100)}')
|
|
|
|
test $SWAPTOTAL -eq 0 && PERCENTOS=0 || PERCENTOS=$(echo $SWAPFREE $SWAPTOTAL | awk '{printf("%d", ($2-$1)/$2*100)}')
|
|
|
|
|
|
|
|
SWAP=$(printf "Swap: %13d %3d%%\n" $(($SWAPTOTAL-$SWAPFREE)) $PERCENTOS)
|
|
|
|
|
|
|
|
# MEMORY USAGE
|
|
|
|
printf "Memory: %11d %3d%%\n" $(($MEMTOTAL-$MEMFREE)) $PERCENTOM >> $COLL_MEM
|
|
|
|
|
|
|
|
if [ $PERCENTOS -ge $SWAP_USAGE_CRITICAL ] || [ $SWAPTOTAL -eq 0 ]; then
|
|
|
|
red "$SWAP" >> $COLL_MEM
|
|
|
|
CR_MEM=1
|
|
|
|
report "WARNING: usage of the SWAP space is more than ${SWAP_USAGE_CRITICAL}%"
|
|
|
|
|
|
|
|
# Execute custom command
|
|
|
|
if [ -n "${SWAP_TRESHOLD_EXEC}" ]; then
|
|
|
|
report "WARNING: executing command: \"$SWAP_TRESHOLD_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$(eval ${SWAP_TRESHOLD_EXEC} 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
|
|
|
|
if [ $PERCENTOS -ge $SWAP_USAGE_WARNING ] && [ $PERCENTOS -lt $SWAP_USAGE_CRITICAL ]; then
|
|
|
|
yellow "$SWAP" >> $COLL_MEM
|
|
|
|
WR_MEM=1
|
|
|
|
report "CRITICAL: usage of the SWAP space is more than ${SWAP_USAGE_WARNING}%"
|
|
|
|
# Execute custom command
|
|
|
|
if [ -n "${SWAP_TRESHOLD_EXEC}" ]; then
|
|
|
|
report "CRITICAL: executing command: \"$SWAP_TRESHOLD_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$(eval ${SWAP_TRESHOLD_EXEC} 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "$SWAP" >> $COLL_MEM
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
grep Buffer /proc/meminfo | awk '{printf("%-10s %8s \n",$1,$2)}' >> $COLL_MEM
|
|
|
|
grep "^Cached" /proc/meminfo | awk '{printf("%-10s %8s \n",$1,$2)}' >> $COLL_MEM
|
|
|
|
|
|
|
|
cp $COLL_MEM ${COLL_MEM}.tmp
|
|
|
|
|
|
|
|
green " Memory status " > $COLL_MEM
|
|
|
|
test -n "$CR_MEM" && red " Memory status " > $COLL_MEM
|
|
|
|
test -n "$WR_MEM" && yellow " Memory status " > $COLL_MEM
|
|
|
|
|
|
|
|
cat ${COLL_MEM}.tmp >> $COLL_MEM
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Disk status
|
|
|
|
function disk() {
|
|
|
|
|
|
|
|
STATUS_DISK=$(egrep -v "^#|^ *#" /etc/motds32/fstab_limits)
|
|
|
|
|
|
|
|
IFS=$'\n'
|
|
|
|
|
|
|
|
for DEVICE in $STATUS_DISK
|
|
|
|
do
|
|
|
|
# Read Mount Point path and limits
|
|
|
|
MP=$(echo "${DEVICE}" | awk {'print $1'})
|
|
|
|
MP_USAGE_WARNING=$(echo "${DEVICE}" | awk {'print $2'})
|
|
|
|
MP_USAGE_CRITICAL=$(echo "${DEVICE}" | awk {'print $3'})
|
|
|
|
|
|
|
|
# If Warning and Critical limit are not set to GLOBAL defaults
|
|
|
|
test -z ${MP_USAGE_WARNING} && MP_USAGE_WARNING=$DISK_USAGE_WARNING
|
|
|
|
test -z ${MP_USAGE_CRITICAL} && MP_USAGE_CRITICAL=$DISK_USAGE_CRITICAL
|
|
|
|
|
|
|
|
|
|
|
|
# Fixed problems with long device names and new line
|
|
|
|
PART_RESULT=$(df -h "${MP}" 2>/dev/null)
|
|
|
|
DF_RESULT=$?
|
|
|
|
|
|
|
|
# Check if the partition exists
|
|
|
|
if [ ${DF_RESULT} -eq 0 ]; then
|
|
|
|
|
|
|
|
PART=$(echo "${PART_RESULT}" | grep '\/' | tr -d '\n' | awk '{printf("%-13s %5s %4s\n",$6,$4,$5)}' | tr -d '%')
|
|
|
|
|
|
|
|
normalize
|
|
|
|
|
|
|
|
USAGE=$(echo $PART | awk '{print $3}')
|
|
|
|
PARTITION=$(echo $PART | awk '{print $1}')
|
|
|
|
|
|
|
|
if [ $USAGE -ge $MP_USAGE_WARNING ] && [ $USAGE -lt $MP_USAGE_CRITICAL ]; then
|
|
|
|
yellow "${PART}%" >> $COLL_DISK && WR_NOTICE=1
|
|
|
|
report "WARNING: usage of $PARTITION partition is ${USAGE}% and limit is ${MP_USAGE_WARNING}%"
|
|
|
|
|
|
|
|
# Execute custom command
|
|
|
|
if [ -n "${DISK_TRESHOLD_EXEC}" ]; then
|
|
|
|
report "WARNING: executing command: \"$DISK_TRESHOLD_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$(eval ${DISK_TRESHOLD_EXEC} 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $USAGE -ge $MP_USAGE_CRITICAL ]; then
|
|
|
|
red "${PART}%" >> $COLL_DISK && CR_NOTICE=1
|
|
|
|
report "CRITICAL: usage of $PARTITION partition is ${USAGE}% and limit is ${MP_USAGE_CRITICAL}%"
|
|
|
|
|
|
|
|
# Execute custom command
|
|
|
|
if [ -n "${DISK_TRESHOLD_EXEC}" ]; then
|
|
|
|
report "CRITICAL: executing command: \"$DISK_TRESHOLD_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$(eval ${DISK_TRESHOLD_EXEC} 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
test $USAGE -lt $MP_USAGE_WARNING && echo "${PART}%" >> $COLL_DISK
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
red "$(printf "%-13.13s NotMounted" ${MP})" >> $COLL_DISK && CR_NOTICE=1
|
|
|
|
report "CRITICAL: mount point $MP is not mounted"
|
|
|
|
fi
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
unset IFS
|
|
|
|
|
|
|
|
cat $COLL_DISK | sort -k 3 -nr > ${COLL_DISK}.tmp
|
|
|
|
|
|
|
|
green " Disk status " > $COLL_DISK
|
|
|
|
test -n "$CR_NOTICE" && red " Disk status " > $COLL_DISK
|
|
|
|
test -n "$WR_NOTICE" && yellow " Disk status " > $COLL_DISK
|
|
|
|
|
|
|
|
|
|
|
|
bold "partition free usg" >> $COLL_DISK
|
|
|
|
cat ${COLL_DISK}.tmp >> $COLL_DISK
|
|
|
|
}
|
|
|
|
|
|
|
|
function getmaxrow () {
|
|
|
|
DISK_NUM=$(wc -l $COLL_DISK | awk '{print $1}')
|
|
|
|
test $DISK_NUM -gt $LINES && LINES=$DISK_NUM
|
|
|
|
MEM_NUM=$(wc -l $COLL_MEM | awk '{print $1}')
|
|
|
|
test $MEM_NUM -gt $LINES && LINES=$MEM_NUM
|
|
|
|
PROC_NUM=$(wc -l $COLL_PROC | awk '{print $1}')
|
|
|
|
test $PROC_NUM -gt $LINES && LINES=$PROC_NUM
|
|
|
|
}
|
|
|
|
|
|
|
|
# Join 3 cols together
|
|
|
|
function join () {
|
|
|
|
getmaxrow
|
|
|
|
MEM_NUM=$(($MEM_NUM + 1))
|
|
|
|
DISK_NUM=$(($DISK_NUM + 1))
|
|
|
|
|
|
|
|
test -e $COLL_EMPTY && rm -f $COLL_EMPTY
|
|
|
|
for I in $(seq $DISK_NUM $LINES); do echo " " >> $COLL_DISK; done
|
|
|
|
for I in $(seq $MEM_NUM $LINES); do echo " " >> $COLL_MEM; done
|
|
|
|
|
|
|
|
for I in $(seq $LINES); do echo ' | ' >> $COLL_EMPTY; done
|
2017-07-21 13:19:26 +02:00
|
|
|
for I in $(seq $LINES); do echo '|' >> $COLL_WALL; done
|
2017-07-18 23:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Center text
|
|
|
|
function echo_center {
|
|
|
|
LENGTH=${#1}
|
|
|
|
printf "%$(((80 - $LENGTH) / 2))s" ; echo "$1"
|
|
|
|
}
|
2017-07-21 13:19:26 +02:00
|
|
|
|
|
|
|
function echo_center2 {
|
|
|
|
LENGTH=${#1}
|
|
|
|
INDENT=`seq 1 $(((78 - $LENGTH) / 2)) | sed 's/.*/ /' | tr -d '\n'`
|
|
|
|
printf "|%-78s|\n" "${INDENT}${1}"
|
|
|
|
}
|
|
|
|
|
2017-07-18 23:06:11 +02:00
|
|
|
function cat_center {
|
|
|
|
LENGTH=${#1}
|
|
|
|
printf "%$(((80 - $LENGTH) / 2))s" ; cat $1
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Check listen services IP:Port
|
|
|
|
#
|
|
|
|
function checkservices {
|
|
|
|
test ! -f ${NETSERVICE_LIST} && gen_netservice_list
|
|
|
|
|
|
|
|
bold "service(s) (count)" > $COLL_PROC
|
|
|
|
|
|
|
|
NETSTAT=$(netstat -nlp 2>/dev/null)
|
|
|
|
|
|
|
|
if [ -e ${NETSERVICE_LIST} ]; then
|
|
|
|
IFS=$'\n'
|
|
|
|
|
|
|
|
LINE=$(grep -v "^#" ${NETSERVICE_LIST})
|
|
|
|
for SERVICE in $LINE; do
|
|
|
|
PROTO=$(echo $SERVICE | awk '{print $1}')
|
|
|
|
SOCKET=$(echo $SERVICE | awk '{print $2}')
|
|
|
|
PROCES=$(echo $SERVICE | awk '{print $3}')
|
|
|
|
|
|
|
|
RESULT=$(echo "$NETSTAT" | egrep "^${PROTO}.*${SOCKET}")
|
|
|
|
|
|
|
|
# First checking
|
|
|
|
if [ -z "$RESULT" ]; then
|
|
|
|
# DEBUG
|
|
|
|
# echo $NETSTAT >> /tmp/.motds32_netstat_$$.tmp
|
|
|
|
sleep 1
|
|
|
|
|
|
|
|
NETSTAT=$(netstat -nlp 2>/dev/null)
|
|
|
|
# Double checking for fake panic
|
|
|
|
RESULT=$(echo "$NETSTAT" | egrep "^${PROTO}.*${SOCKET}")
|
|
|
|
|
|
|
|
if [ -z "$RESULT" ]; then
|
2017-07-21 13:19:26 +02:00
|
|
|
# red "${PROTO}/${SOCKET}" >> $COLL_PROC
|
|
|
|
red "$(printf "%-24.24s" ${PROTO}/${SOCKET})" >> $COLL_PROC
|
2017-07-18 23:06:11 +02:00
|
|
|
NOT_RUNNING=1
|
|
|
|
report "CRITICAL: Service \"$PROCES\" not running at socket ${PROTO}/${SOCKET}"
|
|
|
|
else
|
2017-07-21 13:19:26 +02:00
|
|
|
green "$(printf "%-24.24s" ${PROTO}/${SOCKET})" >> $COLL_PROC
|
|
|
|
#green "${PROTO}/${SOCKET}" >> $COLL_PROC
|
2017-07-18 23:06:11 +02:00
|
|
|
fi
|
|
|
|
else
|
2017-07-21 13:19:26 +02:00
|
|
|
#green "${PROTO}/${SOCKET}" >> $COLL_PROC
|
|
|
|
green "$(printf "%-24.24s" ${PROTO}/${SOCKET})" >> $COLL_PROC
|
2017-07-18 23:06:11 +02:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
unset IFS
|
|
|
|
fi
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function load {
|
|
|
|
NUM_OF_CPU=$(grep -i processor /proc/cpuinfo | wc -l)
|
|
|
|
LOAD_5MIN=$(awk '{printf $2}' < /proc/loadavg)
|
|
|
|
LOAD_PERCENT=$(echo $LOAD_5MIN $NUM_OF_CPU |awk '{printf "%2.f", $1*100/$2}')
|
|
|
|
|
|
|
|
LOAD_REPORT="5min load is $LOAD_5MIN on $NUM_OF_CPU cpu(s)"
|
|
|
|
|
|
|
|
if [ $LOAD_PERCENT -gt $CPU_WARNING ] && [ $LOAD_PERCENT -lt $CPU_CRITICAL ]; then
|
|
|
|
report "WARNING: System load ${LOAD_5MIN} on $NUM_OF_CPU cpu(s)"
|
|
|
|
|
|
|
|
# Execute custom command
|
|
|
|
if [ -n "${LOAD_TRESHOLD_EXEC}" ]; then
|
|
|
|
report "WARNING: executing command: \"$LOAD_TRESHOLD_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$(eval ${LOAD_TRESHOLD_EXEC} 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
if [ $LOAD_PERCENT -gt $CPU_CRITICAL ]; then
|
|
|
|
report "CRITICAL: system load ${LOAD_5MIN} on $NUM_OF_CPU cpu(s)"
|
|
|
|
|
|
|
|
# Execute custom command
|
|
|
|
if [ -n "${LOAD_TRESHOLD_EXEC}" ]; then
|
|
|
|
report "CRITICAL: executing command: \"$LOAD_TRESHOLD_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$(eval ${LOAD_TRESHOLD_EXEC} 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Notify when too much e-mails in mailq
|
|
|
|
# if MAILQ_WARNING=0 skip this test
|
|
|
|
#
|
|
|
|
function check_mailq {
|
|
|
|
|
|
|
|
test $MAILQ_WARNING -eq 0 && return
|
|
|
|
|
|
|
|
# Check if mail command is present in $PATH
|
|
|
|
if [ $(which mailq 2>/dev/null >/dev/null && echo OK || echo NOK) != "OK" ]; then
|
|
|
|
echo "WARNING: unable to find mailq command in \$PATH"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
MAILQ=$(mailq | tail -n 1 | grep -i requests | awk '{print $5}')
|
|
|
|
|
|
|
|
if [ -n "$MAILQ" ]; then
|
|
|
|
if [ $MAILQ -gt $MAILQ_WARNING ]; then
|
|
|
|
# REPORT=$REPORT"WARNING: mail queue size warning $MAILQ > $MAILQ_WARNING\n"
|
|
|
|
report "WARNING: mail queue size warning $MAILQ > $MAILQ_WARNING"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Check NTP status
|
|
|
|
function check_ntp() {
|
|
|
|
test $CHECK_NTP != "YES" && NTPSTATUS=" " && return
|
|
|
|
|
|
|
|
if [ $(which ntpq 2>/dev/null >/dev/null && echo OK || echo NOK) != "OK" ]; then
|
|
|
|
echo "WARNING: unable to find ntpq command in \$PATH"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
NTP=$(ntpq -p 2>/dev/null | egrep -v '===|remote|^ ' | sed -e 's/^\(.\).*/\1/' | tr -d '\n')
|
|
|
|
if [ $(echo "$NTP" | grep -c '\*') -eq 0 ]; then
|
|
|
|
test -z "$NTP" && NTPSTATUS=$(red "x") || NTPSTATUS=$(red "$NTP")
|
|
|
|
report "WARNING: NTP synchronization lost"
|
|
|
|
if [ -n "${NTP_PROBLEM_EXEC}" ]; then
|
|
|
|
report "WARNING: executing command: \"$NTP_PROBLEM_EXEC\""
|
|
|
|
report "--->%---"
|
|
|
|
report "$($NTP_PROBLEM_EXEC 2>&1)"
|
|
|
|
report "--->%---"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
NTPSTATUS=$(green "$NTP")
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Generate mount point table usage limits from /etc/fstab file
|
|
|
|
# If Warning or Critical mimits are not set user GLOBAL settings
|
|
|
|
#
|
|
|
|
function gen_mount_point_table() {
|
|
|
|
|
|
|
|
if [ ! -e ${PARTITION_TABLE} ]; then
|
|
|
|
|
|
|
|
# Exclude list : '#' comments and blacklisted filesystems
|
|
|
|
FSTAB=$(egrep -v '^#|^ .*#|[[:space:]]proc[[:space:]]|[[:space:]]debugfs[[:space:]]|[[:space:]]swap[[:space:]]|[[:space:]]devpts[[:space:]]|[[:space:]]sysfs[[:space:]]|[[:space:]]tmpfs[[:space:]]' < /etc/fstab | awk '{print($2)}')
|
|
|
|
# Generate header
|
|
|
|
echo "# Mount point usage limit Warn [%] Critical [%]" > ${PARTITION_TABLE}
|
|
|
|
|
|
|
|
for PARTITION in $FSTAB; do
|
|
|
|
printf "%-28s %s %s\n" ${PARTITION} ${DISK_USAGE_WARNING} ${DISK_USAGE_CRITICAL} >> ${PARTITION_TABLE}
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Main program
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
|
# Read the configuration file
|
|
|
|
if [ -e $CONFIGFILE ]; then
|
|
|
|
set_default_values
|
|
|
|
. $CONFIGFILE
|
|
|
|
else
|
|
|
|
echo "Error: configuration file $CONFIGFILE not found"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2017-07-20 15:10:15 +02:00
|
|
|
# display usage
|
|
|
|
function usage {
|
|
|
|
echo "Usage: motds32 OPTIONS"
|
|
|
|
|
|
|
|
echo " -g, --generate Check system status and generate it to $MOTD file"
|
|
|
|
echo " -s, --status Show limited content of MOTD file"
|
|
|
|
echo " -v, --version Display information about motds32 version and author"
|
|
|
|
echo " -m, --MOTDs32 See MOTD file now!"
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2017-07-18 23:06:11 +02:00
|
|
|
case $1 in
|
|
|
|
-g|--generate)
|
|
|
|
;;
|
|
|
|
-s|--status)
|
|
|
|
test -e $MOTD && cat $MOTD
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
-v|--version)
|
2017-07-31 21:03:36 +02:00
|
|
|
echo "motds32 Version: $VERSION"
|
|
|
|
echo "Original project: Krigler Pavol, modstat"
|
|
|
|
echo "MOTDs32: by Erreur32"
|
2017-07-18 23:06:11 +02:00
|
|
|
exit 0
|
|
|
|
;;
|
2017-07-20 11:17:27 +02:00
|
|
|
-m|--MOTDs32)
|
2017-07-20 15:10:15 +02:00
|
|
|
echo "Read motds32 file"
|
2017-07-18 23:06:11 +02:00
|
|
|
cat /etc/motd
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
usage
|
2017-07-31 21:03:36 +02:00
|
|
|
;;
|
2017-07-18 23:06:11 +02:00
|
|
|
esac
|
|
|
|
|
|
|
|
# Generate mount point table usage limits from /etc/fstab file
|
|
|
|
gen_mount_point_table
|
|
|
|
|
|
|
|
# Create e-mail REPORT header
|
2017-08-12 10:48:31 +02:00
|
|
|
REPORT="MOTDs32 System report\n==================\nHost: ${HOSTNAME}\nDate: $(date)\n(to set this report alarm in /etc/motds32/motds32.conf)\n"
|
2017-07-18 23:06:11 +02:00
|
|
|
|
|
|
|
# Get disk statistics
|
|
|
|
disk
|
|
|
|
|
|
|
|
# Get memorty statistics
|
|
|
|
memory
|
|
|
|
|
|
|
|
# Check local network service
|
|
|
|
checkservices
|
|
|
|
|
|
|
|
# Check local running processes
|
|
|
|
checkprocess
|
|
|
|
|
|
|
|
# Join all output to multiple columns
|
|
|
|
join
|
|
|
|
|
|
|
|
# Check the mailq
|
|
|
|
check_mailq
|
|
|
|
|
|
|
|
# Check NTP status
|
|
|
|
check_ntp
|
|
|
|
|
|
|
|
# Create MOTD system status header
|
|
|
|
load
|
|
|
|
|
2017-08-12 10:48:31 +02:00
|
|
|
|
|
|
|
|
2017-07-22 22:41:46 +02:00
|
|
|
# clean terminal when load MOTDs32
|
|
|
|
echo -en "\ec" > $MOTD
|
|
|
|
|
|
|
|
echo_center "${HOSTNAME}${NTPSTATUS} > status at $(date +"%R") > ${LOAD_REPORT}" bold >> $MOTD
|
2017-07-18 23:06:11 +02:00
|
|
|
|
|
|
|
echo >> $MOTD
|
|
|
|
|
|
|
|
paste -d "" $COLL_DISK $COLL_EMPTY $COLL_MEM $COLL_EMPTY $COLL_PROC | head -n $MAX_ROWS_LIMIT >> $MOTD
|
2017-07-21 13:19:26 +02:00
|
|
|
#paste -d "" $COLL_DISK $COLL_EMPTY $COLL_MEM $COLL_EMPTY $COLL_PROC >> $MOTD
|
2017-08-16 10:47:29 +02:00
|
|
|
if [[ $EUID -ne 0 ]]; then
|
|
|
|
echo "MOTD available only with root" 1>&2
|
|
|
|
else
|
2017-07-18 23:06:11 +02:00
|
|
|
cat /etc/motds32/Stats32.txt >> $MOTD
|
2017-08-16 10:47:29 +02:00
|
|
|
# /bin/bash /etc/motds32/Stats32 > /etc/motds32/Stats32.txt
|
|
|
|
# echo -e "\n Generating Stats file" 1>&2
|
|
|
|
fi
|
2017-07-18 23:06:11 +02:00
|
|
|
|
|
|
|
# Full report
|
2017-07-21 13:19:26 +02:00
|
|
|
#paste -d "" $COLL_DISK $COLL_EMPTY $COLL_MEM $COLL_EMPTY $COLL_PROC > $MOTD.full
|
2017-07-18 23:06:11 +02:00
|
|
|
|
|
|
|
echo >> $MOTD
|
|
|
|
|
|
|
|
# Append original MOTD from /etc/motd.orig file if exists
|
|
|
|
if [ -s ${MOTD}.orig ]; then
|
2017-07-20 15:10:15 +02:00
|
|
|
# echo_center "--- Message Of The Day --- (from /etc/motd.orig file) ---" >> $MOTD
|
|
|
|
# echo >> $MOTD
|
2017-07-18 23:06:11 +02:00
|
|
|
cat ${MOTD}.orig >> $MOTD
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Create statistics directory
|
|
|
|
test ! -e $STATS_DIR && mkdir -p $STATS_DIR
|
|
|
|
|
|
|
|
# Check if server has rebooted (current uptime < stored uptime
|
|
|
|
if [ -s $STATS_DIR/uptime ]; then
|
|
|
|
if [ $(cut -d '.' -f 1 < /proc/uptime) -lt $(cat $STATS_DIR/uptime) ]; then
|
|
|
|
report "CRITICAL: System has rebooted."
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Update uptime statistics
|
|
|
|
test -e /proc/uptime && cut -d '.' -f 1 < /proc/uptime > $STATS_DIR/uptime
|
|
|
|
|
|
|
|
|
2017-08-08 18:30:38 +02:00
|
|
|
|
2017-07-18 23:06:11 +02:00
|
|
|
# Removing temporary files
|
|
|
|
rm -f ${COLL_PROC} ${COLL_PROC}.tmp
|
|
|
|
rm -f ${COLL_MEM} ${COLL_MEM}.tmp
|
|
|
|
rm -f ${COLL_DISK} ${COLL_DISK}.tmp
|
|
|
|
rm -f ${COLL_EMPTY}
|
2017-07-21 13:19:26 +02:00
|
|
|
rm -f ${COLL_WALL}
|
2017-07-18 23:06:11 +02:00
|
|
|
|
|
|
|
if [ ! -z "$EMAIL" ]; then
|
|
|
|
|
|
|
|
# Check if mail command is present in $PATH
|
|
|
|
if [ $(which mail 2>/dev/null >/dev/null && echo OK || echo NOK) != "OK" ]; then
|
|
|
|
echo "WARNING: unable to find mail command in \$PATH"
|
|
|
|
else
|
|
|
|
if [ ! -z "$(echo -e "$REPORT" | egrep -i "warning:|critical:")" ]; then
|
|
|
|
echo -e "$REPORT" | mail "$EMAIL" -s "MOTDs32 alert"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|