#!/bin/bash

# delete directories that are older than maximum global age and
# delete files from 'security', 'audit' and 'operational' categories, adjusting
# each category of files to its configured maximum age and size


configFile='/opt/Avaya/scripts/config_files/syslog_config'
if [ ! -f $configFile ];
then
	exit 0  # not an error
fi

sysmonDir='/var/log/sysmon/'
keepLastDays=3
for i in `seq 0 1 $((keepLastDays-1))`; do
echo $i
currentDate="$currentDate|`date +%Y%m%d --date="-$i day"`"
done
currentDate=${currentDate:1}
echo $currentDate
removed_file=false
for file in `find $sysmonDir -name "sysmon*" -type f `; do
    if echo $file | grep -vE "$currentDate" > /dev/null; then
       rm -f "$file"
       removed_file=true
    fi
done 

logsDir='/var/log/rsyslog/*/*'

# delete the globally aged folders

# get the maximum global age
globalAgeConfigLine=$(grep "^age=" "$configFile")
value=$(echo ${globalAgeConfigLine#*=})
echo 'max global age = '$value

# if value is set
if [ ! -z $value ]; 
then
        # get current date
        current_date=`date +%F`

        unset a i

        # get all day folders that don't need to be erased
        i=0
        while [ "$i" -lt "$value" ];
        do
                a+=`date +%F --date="-$i day"`"\|"
                i=$((i+1))
        done
        a=${a%%??}

        # for all the other dates erase the directory
        for file in `find $logsDir -type d | grep -v "$a"`
        do
                # avoid to erase custom defined folders
                ok=`grep "[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$" <<<$file`
                if [ ! -z $ok ]; then
                        rm -rf $file
                        removed_file=true
                        echo $file
                fi
        done
fi

# adjust age and size of the file categories

categories=('security' 'audit' 'operational')

categorizedFiles=$( find $logsDir -type f | awk '{
	#
	# add category labels to the file names in the list of files
	#
		if( match( $0, "/(secure|.*_auth\\.log|.*_security\\.log)$", arr ) )
			category = "security";
		else if( match( $0, "/(audit\\.log|.*_logalert\\.log)$", arr ) )
			category = "audit";
		else 
			category = "operational";
		printf "category=%s:%s\n", category, $0;
}' )

if [ -z "$categorizedFiles" ];
then
	exit 0
fi

echo 'categorized files:'
printf '%s\n' "$categorizedFiles"

for categ in ${categories[@]};
do
        ageConfigLine=$( grep "${categ}_age=" "$configFile" )
        maxAge=$( echo ${ageConfigLine#*=} )
        echo 'max age = '$maxAge

        sizeConfigLine=$( grep "${categ}_max_size=" "$configFile" )
        maxSize=$( echo ${sizeConfigLine#*=} )
        echo 'max size = '$maxSize

	if [ -z "$maxAge" ] || [ -z "$maxSize" ];
	then
		continue
	fi

	# will erase files upto: today + 1 - maxSize

        earliestDateAllowed=$( date +%F --date="$((1-maxAge)) day" )
        echo 'earliest date allowed = '$earliestDateAllowed

        # get the ordered list of files in the current category, with
	# dates, sizes, file paths and total size;
	# since dates are in YYYY-MM-DD format and embedded in file paths, 
	# the list can be ordered string-wise (with 'sort')

	filesInfo=$( printf '%s\n' "$categorizedFiles" | awk '{
		#
		# match file names in the category and keep only the file names
		#
			pattern = "category='"${categ}"':";
			if( match( $0, pattern ) )
			{
				sub( pattern, "", $0 );
				print $0;
			}
		}' | sort | xargs wc --bytes | awk '
		#
		# read size and name for each file and, if there are more files, read total category size
		#
			!/total/ { 
				if( match( $0, "[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]", fileDateArr ) )
					# $1 is the file size
					# $2 is the file name
					printf "%s,%s,%s\n", fileDateArr[0], $1, $2; 
			} \
			END {
				if( match( $0, "total" ) )
					numOfFiles = NR - 1;
				else if( $0 )
					numOfFiles = 1;
				else
					numOfFiles = 0;
				# $1 will be the total category size in any case
				printf "%s\n%d\n", $1, numOfFiles;
			}' )
        printf '%s\n' "$filesInfo"

        actualSize=$( printf '%s\n' "$filesInfo" | tail -n 2 | head -n 1 )
        numOfFiles=$( printf '%s\n' "$filesInfo" | tail -n 1 )
        echo 'actual size = '$actualSize
        echo 'num of files = '$numOfFiles

        for descr in $( printf '%s\n' "$filesInfo" | head -n "$numOfFiles" )
        do
                fileDate=$( echo "$descr" | cut --delimiter=',' -f1  )  # 1st field
                fileSize=$( echo "$descr" | cut --delimiter=',' -f2  )  # 2nd field
                filePath=$( echo "$descr" | cut --delimiter=',' -f3- )  # remaining chars
                echo 'file: date = '$fileDate', size = '$fileSize', path = '$filePath

                doRemoveFile='false'

                # because the files are sorted by their date, 
                # the first group of iterations will only delete aged files,
                # the next group of iterations will only delete some remaining files to adjust size
                # and the next iteration will break the loop because no more files need to be deleted

                # dates in YYYY-MM-DD format can be compared string-wise
                if [ "$fileDate" \< "$earliestDateAllowed" ];
        	then
                        echo 'file is too old'
                        doRemoveFile='true'
                else
                        if [ $((actualSize)) -gt $((maxSize)) ];
                        then
                                echo 'total size is too big'
                                doRemoveFile='true'
                        else
                                echo 'no (further) file removals'
                                break
                        fi
                fi

                if [ "$doRemoveFile" == 'true' ];
                then
                        rm -f "$filePath"
                        actualSize=$((actualSize-$fileSize))
                        echo 'removed file: actual size reached '$actualSize
                        removed_file=true
                fi
        done
done
if [ "$removed_file" == "true" ]; then
    echo "Reload rsyslog to reset file descriptors"
    /sbin/service rsyslog force-reload
fi
