#!/bin/bash
#
#	logdigest.sh: Log file digests
#	written by Peter Poeml <poeml@suse.de>
#	(based on the logcheck package by Craig Rowland <crowland@psionic.com>)
#
#	This file needs the program logtail.c to run
#

# source site local configuration from /etc/logdigest/config
test -r /etc/logdigest/config && . /etc/logdigest/config 

# find the fully qualified domain name here
#test -r /etc/sysconfig/network/config && . /etc/sysconfig/network/config 

# CONFIGURATION SECTION

PATH=/sbin:/bin:/usr/sbin:/usr/bin

# Person to send log activity to.
: ${SYSADMIN:=root}

# Full path to logtail program.
# This program is required to run this script and comes with the package.
: ${LOGTAIL:=/usr/bin/logtail}

# Full path to non public writable /tmp directory.
: ${TMPDIR:=/var/lib/logdigest}

# The 'grep' command. This command MUST support the '-i' '-v' and '-f' flags.
# The GNU grep does this by default.  The Sun grep supposedely does not support
# these switches, but the 'egrep' command does.
GREP=egrep

# The 'mail' command. Most systems this should be OK to leave as is.
# If your default mail command does not support the '-s' (subject) command
# line switch you will need to change this command one one that does.
MAIL=mail

# file containing "alarm"ing regular expressions
: ${KEYWORDS_ALARMING:=/etc/logdigest/alarming}

# This is the name of a file that contains patterns that we should
# ignore if found in a log file. If you have repeated false alarms
# or want specific errors ignored, you should put them in here.
# Once again, be as specific as possible, and go easy on the wildcards

: ${KEYWORDS_IGNORE:=/etc/logdigest/ignore}

# add .local conf files if they are not there
for i in $KEYWORDS_ALARMING $KEYWORDS_IGNORE; do
	test -e $i.local || { touch $i.local; chmod 600 $i.local; }
done

# Make sure we really did clean up from the last run.
# Also this ensures that people aren't trying to trick us into
# overwriting files that we aren't supposed to. This is still a race
# condition, but if you are in a temp directory that does not have
# generic luser access it is not a problem. Do not allow this program
# to write to a generic /tmp directory where others can watch and/or
# create files!!

# Shouldn't need to touch these...
HOSTNAME=`hostname -f`
DATE=`date +%Y-%m-%d\ %H:%M`

function print_login_stats() {
	TMPFILE=$TMPDIR/last 
	last >| $TMPFILE 
	for i in `grep -v wtmp $TMPFILE | cut -b 0-9 | sort | uniq`; do 
		printf "%-10s" $i
		grep -c "^$i\>" $TMPFILE
	done 
	rm $TMPFILE
}

function prune_whitespace() {
	$GREP -v "^[[:space:]]*$" $1
}

umask 077
rm -f $TMPDIR/checkoutput.$$ $TMPDIR/mail.$$

if [ -f $TMPDIR/check.$$ -o -f $TMPDIR/checkoutput.$$ -o -f $TMPDIR/mail.$$ ]; then
	echo "Log files exist in $TMPDIR directory that cannot be removed. This 
may be an attempt to spoof the log checker." \
	| $MAIL -s "[$HOSTNAME] logdigest Logfile problem!" $SYSADMIN
	exit 1
fi


# Logfiles to grep through
: ${LOGFILES:=/var/log/messages /var/log/mail}

j=0; for i in $LOGFILES; do 
	((j++)) 
	LOGFILE[$j]=$i 
	log_file_name[$j]=${i//\//_} # normalized name
	#echo ${log_file_name[$j]}
done; 

# that's n logfiles
n=${#log_file_name[@]}

# Set the flag variables
FOUND=0
ALARM=0

cat > $TMPDIR/mail.$$ <<-EOF 

	Edit /etc/logdigest/ignore.local with regular expressions
	for messages that should be ignored in the future.
	Please consider submitting new regexps to upstream!

EOF

# for each logfile 
for (( i=1; i<=n; i++)); do 

	> $TMPDIR/${log_file_name[$i]}.1.$$
	$LOGTAIL ${LOGFILE[$i]} $TMPDIR/${log_file_name[$i]}.offset \
	  | $GREP -v -f <(prune_whitespace $KEYWORDS_IGNORE) -f <(prune_whitespace $KEYWORDS_IGNORE.local) \
	  > $TMPDIR/${log_file_name[$i]}.1.$$

	# skip non-existant log files
	test -e ${LOGFILE[$i]} || continue

	# Check for "alarming" keywords
	$GREP    -i -f <(prune_whitespace $KEYWORDS_ALARMING) -f <(prune_whitespace $KEYWORDS_ALARMING.local) $TMPDIR/${log_file_name[$i]}.1.$$ \
		> $TMPDIR/${log_file_name[$i]}.alarm.$$
	# Collect all the rest
	$GREP -v -i -f <(prune_whitespace $KEYWORDS_ALARMING) -f <(prune_whitespace $KEYWORDS_ALARMING.local) $TMPDIR/${log_file_name[$i]}.1.$$ \
		> $TMPDIR/${log_file_name[$i]}.rest.$$


	# found anything to report?
	if test -s $TMPDIR/${log_file_name[$i]}.alarm.$$ -o -s $TMPDIR/${log_file_name[$i]}.rest.$$; then
		cat >> $TMPDIR/mail.$$ <<-EOF


			
			${LOGFILE[$i]}:
			________________________________________________________________________________
		EOF
	fi

	if test -s $TMPDIR/${log_file_name[$i]}.alarm.$$; then
		cat >> $TMPDIR/mail.$$ <<-EOF
			
			Messages matching keywords in the "alarming" list:
			=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
			(`wc -l $TMPDIR/${log_file_name[$i]}.alarm.$$ | awk '{print $1}'` lines)
			`cat $TMPDIR/${log_file_name[$i]}.alarm.$$`
			
		EOF
		FOUND=1
	fi

	if test -s $TMPDIR/${log_file_name[$i]}.rest.$$; then
		cat >> $TMPDIR/mail.$$ <<-EOF
			
			All lines that are not in the "ignore" list:
			=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
			(`wc -l $TMPDIR/${log_file_name[$i]}.rest.$$ | awk '{print $1}'` lines)
			`cat $TMPDIR/${log_file_name[$i]}.rest.$$`
			
		EOF
		FOUND=1
	fi
	rm -f $TMPDIR/${log_file_name[$i]}.{1,alarm,rest}.$$ 

done


if [ "$EXTENDED_STATS" = yes ]; then 
	FOUND=1
	cat >> $TMPDIR/mail.$$ <<-EOF


		System Status:
		________________________________________________________________________________


		Mail queue
		=-=-=-=-=-
		`mailq`

		System status
		=-=-=-=-=-=-=
		`procinfo`

		Local disk space
		=-=-=-=-=-=-=-=-
		`df -h -x nfs`

		Network device status
		=-=-=-=-=-=-=-=-=-=-=
		`cat /proc/net/dev`
	EOF
else
	cat >> $TMPDIR/mail.$$ <<-EOF


		Load:       `cat /proc/loadavg`
		________________________________________________________________________________


		Mail queue:
		________________________________________________________________________________

		`mailq`

	EOF
fi

test -s $TMPDIR/mail.$$ -a $FOUND = 1 && $MAIL -s "logdigest $HOSTNAME" $SYSADMIN < $TMPDIR/mail.$$

# Clean Up
rm -f $TMPDIR/mail.$$
exit 0
