#!/bin/bash
# **********************************************************
# file: rotatelogs.sh
# date: 2005-02-16
# author: Marko Schulz - <mschulz@jamba.net>
#
# Rotiert Logfiles in einem Verzeichnis (z.B. /var/log).
# Verwendet eine Konfigurationsdatei, in der fuer jedes Logfile
# gespeichert ist, nach wie vielen Tagen es umkopiert wird.
# Format der Contig-Datei: logfilename=dauer Dauer in Tagen.
# Taucht ein Logfile nicht auf ist dauer=7 Tage.
# **********************************************************
# Fehler per Mail senden (on=>ja/off=>nein)...
notify="on"
# Email an der Fehlermeldungen geschickt werden...
email="mschulz@jamba.net"
# Verzeichnis der Logfiles welche rotiert werden sollen...
logdir="/var/log"
# Name und Pfad des Configfile...
config="/etc/rotatelogs.cfg"
# Name und Pfad des Programm Logfile...
logfile="/var/log/rotatelogs.log"
# Default Rotation (in Tagen)...
default_duration=7
# **********************************************************
# Funktion zum loggen der Status bzw. Fehlermeldungen.
function myLogger() {
local msg=$1
local date=$( date +%Y-%m-%d\ %H:%M:%S )
echo "$date $msg" >> $logfile
}
# **********************************************************
# Versenden von Fehlermeldungen und Programm beenden.
function error() {
local status=$1
if [ "$notify" = "on" -a -n "$email" ]; then
body="This mail was sent automaticly"
error=$( grep $( date +%Y-%m-%d ) $logfile | grep -i '\[error\]' )
echo -e "$body\n\n$error" | mail -s "Error at $0 ..." $email
fi
exit $status
}
# **********************************************************
# Programmablauf
# Startwerte...
duration=$default_duration
count=0
# Programm beeenden, wenn Konfigurationsdatei fehlt.
[ ! -f "$config" ] && myLogger "[error] $0: config file not found" && error 1
# Programm beenden, wenn $LOGDIR keine Schreibrechte bzw. keine Rechte hat um in den Ordner zu wechseln.
[ ! -w "$logdir" -o ! -x "$logdir" ] && myLogger "[error] $0: you have no permission in $logdir" && error 1
cd $logdir
# Da viele find-Versionen keine POSIX-Notation beherrschen, verwenden wir hier nicht ':digit:' sondern [0-9].
for name in $( find . -type f -size +0c ! -name '*[0-9]*' ! -name '\.*' ! -name '*conf' -maxdepth 1 -print | sed 's/^\.\///' ); do
count=$(( $count + 1 ))
# Eintrag in der Konfigurationsdatei suchen
duration="$( grep "^${name}=" $config | cut -d= -f2 )"
if [ -z "$duration" ]; then
duration=$default_duration
elif [ "$duration" = "0" ]; then
myLogger "[status] $0: set duration to 0 - jump over $name"
continue
fi
back1="${name}.1"; back2="${name}.2";
back3="${name}.3"; back4="${name}.4";
# Wenn die neuste Kopie des Logfiles (back1) innerhalb der festgelegten
# Zeit veraendert wurde, ist jetzt keine Rotation noetig.
if [ -f "$back1" ]; then
if [ -z $( find "$back1" -mtime +$duration -print 2>/dev/null ) ]; then
myLogger "[status] $0: skip rotation of $name - last backup of $name less then $duration days"
continue
fi
fi
myLogger "[status] $0: rotate log file $name ($duration days backup)"
# Rotieren. Wir beginnen mit dem aeltesten Log file.
[ -f "$back3" ] && myLogger "[status] $0: rename $back3 -> $back4" && mv -f "$back3" "$back4"
[ -f "$back2" ] && myLogger "[status] $0: rename $back2 -> $back3" && mv -f "$back2" "$back3"
[ -f "$back1" ] && myLogger "[status] $0: rename $back1 -> $back2" && mv -f "$back1" "$back2"
[ -f "$name" ] && myLogger "[status] $0: rename $name -> $back1" && mv -f "$name" "$back1"
touch "$name"
chmod 0600 "$name"
done
[ $count -eq 0 ] && myLogger "[status] $0: nothing done - no log files big or old enough for rotation"
exit 0
# **********************************************************
# end of this script...