#!/bin/bash
# logrotate - rotate log files
# Copyright 2001, Chris F.A. Johnson
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details:
# http://www.gnu.org/copyleft/gpl.html
usage()
{
if [ -n "$1" ]
then
echo " $progname: $*"
else
echo " $progname - rotate log files"
fi
if [ $verbose -eq 1 ]
then
echo "
LogRotate is a log rotation script. Run this from cron on a
periodic basis (daily, weekly, monthly) etc.
"
fi
echo " USAGE: $progname [OPTIONS] [log-control-file]
OPTIONS:
-c ZIP - use ZIP (gzip or bzip2) to compress rotated files
-d DIR - place rotated files in directory DIR
-f FILE - rotate FILE; do not use a control file
-k N - keep last N lines of the logfile
-n N - keep N log files (default 5)
The above options do not override options in a control file unless:
-o - override control file options"
if [ $verbose -eq 0 ]
then
echo "
-h - help: print this message
-H - help: print more detailed message"
else
echo "
-h - help: print shorter message
-H - help: print this message"
fi
echo " -v - verbose:
-V - print version information
"
if [ $verbose -eq 1 ]
then
echo " If no control file is given, $progname looks for
./.logrotate.conf then $HOME/.logrotate.conf then
/etc/logrotate.conf, and uses the first one it finds.
The log-control-file is a text file containing a list of log files
to rotate, wherein each entry is on a separate line and each entry
contains the name (absolute or relative path: see NOTE) of the log file that
needs to be rotated.
Each line may also contain options, separated by tabs:
dir=D - put rotated files in directory D.
The name of the logfile is expanded to the full path
and the slashes are changed to dashes.
files=N - keep N log files
keep=N - keep the last N lines in the file
(This leaves them in the rotated file as well;
I may change the behaviour to remove them from
the rotated file, or add an option to do that.)
gzip
bzip2 - compress the log files with gzip or bzip2
size=N - do not rotate if the file is less than N bytes or lines
N is an integer optionally ending with a letter:
B - bytes (default)
K - append 000 to the number
M - append 000000 to the number
G - append 000000000 to the number
L - refer to number of lines rather than bytes
# --- sample .logrotate.conf ---
# Filename = /var/log/foo
# Compress with gzip
# Maximum number of rotated files = 5
# Keep the last 25 lines of the log file
# Don't rotate if the log file contains fewer than 15,000 lines
/var/log/foo gzip files=5 keep=25 size=15000L
# Filename = ./mylog
# All the defaults are used
mylog
# ---- end .logrotate.conf ----
NOTE: Files in $HOME/.logrotate.conf and /etc/logrotate.conf
should be absolute paths, since the working directory
could be anywhere (unless a file of a certain name should
be rotated wherever it is found)."
fi
echo "
Copyright 2001, Chris F.A. Johnson
Please send corrections, improvements, bugs reports, suggestions,
etc., to cfaj@freeshell.org
Logrotate is derived from a script by javadesigner@yahoo.com
with modifications by Heiner Steven, but there is very
little of the original code left.
This script may be copied under the terms of the
GNU General Public License"
}
fullpath()
{
filename=${1##*/}
dirname=${1%/*}
( cd "$dirname" && echo "`pwd`/$filename" )
}
die()
{
echo "$progname: $*" >&2
exit 1
}
rotateOneFile()
{
logfile=$1
if [ -n "$savedir" ]
then
savelog="$savedir/`fullpath $logfile | tr '/' '-'`"
else
savelog=$logfile
fi
i=${maxno:-$default_maxno}
while [ $i -ge 1 ]
do
newname="$savelog.$i$suffix"
i=$(( $i - 1 ))
oldlogfile=$savelog.$i$suffix
if [ -r "$oldlogfile" ]
then
mv -f "$oldlogfile" "$newname" || die "Could not move "$oldlogfile"
to "$newname""
if [ $verbose -ge 1 ]
then
echo ""$oldlogfile" --> "$newname""
fi
fi
done
newlogfile="$savelog.0"
mv "$logfile" "$newlogfile" || die "Could not move "$logfile"
to "$newlogfile""
if [ $verbose -ge 1 ]
then
echo ""$logfile" --> "$newlogfile""
fi
if [ $keep -gt 0 ]
then
tail -$keep "$newlogfile" > "$logfile"
else
> $logfile
fi
if [ "$compress" ]
then
rm -f "$newlogfile$suffix"
$compress $OPT "$newlogfile"
fi
return 0
}
version()
{
echo $version
}
verbose=0
longusage=0
version="0.5"
copyright=2001
author="Chris F.A. Johnson"
progname=${0##*/}
TAB=`printf "t"`
default_maxno=5
override=0
keep=0
suffix=
compress=
filename=
savedir=
while getopts :vVhHf:n:c:k:od: var
do
case "$var" in
c) compress=$OPTARG ;;
d) savedir=$OPTARG ;;
f) logfile=$OPTARG ;;
k) keep=$OPTARG ;;
n) maxno=$OPTARG ;;
o) override=1 ;;
h) usage; exit ;;
H) verbose=$(( verbose + 1 )); usage; exit ;;
v) verbose=$(( verbose + 1 )) ## allow levels of verbosity
OPT="-v"
;;
V) version; exit ;;
*) usage "Illegal option -- $OPTARG" >&2
exit 1
;;
esac
done
shift $(( $OPTIND - 1 ))
if [ $verbose -eq 3 ]
then
set -x
fi
RETURN=0
if [ -n "$filename" ]
then
if [ -r "$filename" ]
then
rotateOneFile "$filename"
elif [ -f "$filename" ]
then
echo "$progname: "$filename" is not readable" >&2
RETURN=1
else
echo "$progname: "$filename" not found" >&2
RETURN=1
fi
exit $RETURN
fi
if [ $# -eq 0 ]
then
if [ -r ./.logrotate.conf ]
then
controlfile=./.logrotate.conf
elif [ -r $HOME/.logrotate.conf ]
then
controlfile=HOME/.logrotate.conf
elif [ -r /etc/logrotate.conf ]
then
controlfile=/etc/logrotate.conf
else
echo "$progname: could not find a control file" >&2
exit 1
fi
fi
if [ $verbose -ge 1 ]
then
echo "Using ${controlfile}"
fi
IFS=$TAB
while read filename options
do
case "$filename" in
[^/a-zA-Z0-9]#*|#*|"") continue ;; ## skip comments & empty lines
esac
if [ $verbose -ge 1 ]
then
echo "FILE: $filename"
if [ $verbose -ge 2 ]
then
echo "OPTIONS: $options"
fi
fi
[ -f "$filename" ] || { # ignore non-existent files
if [ $verbose -ge 1 ]
then
echo "$filename not found" >&2
fi
continue
}
if [ $override -eq 0 ]
then
suffix=
compress=
units=
savedir=
size=0
filesize=0
keep=0
maxno=$default_maxno
for opt in $options
do
if [ $verbose -ge 1 ]
then
echo $opt
fi
case $opt in
files=*) maxno=${opt#*=}
;;
keep=*) keep=${opt#*=}
;;
gzip) compress=gzip
suffix=".gz"
;;
bzip2) compress=bzip2
suffix=".bz2"
;;
dir=*) savedir=${opt#*=}
;;
size=*) size="${opt#*=}"
units=bytes
if [ "`uname`" = "SunOS" ]
then
SUN="-g"
else
SUN=""
fi
filesize=`ls -l $SUN $filename | {
IFS=" "
read a b c d size f
echo $size
}`
case $size in
[0-9]*B) size="${size%B}" ;;
[0-9]*K) size="${size%K}000" ;;
[0-9]*M) size="${size%M}000000" ;;
[0-9]*G) size="${size%G}000000000" ;;
[0-9]*L) size="${size%L}"
filesize=$(( `wc -l < $filename` + 0 ))
units=lines
;;
esac
if [ $filesize -lt $size ]
then
if [ $verbose -ge 1 ]
then
echo "Skipping $filename ($filesize < ${size%[A-Za-z]})"
fi
continue 2
else
if [ $verbose -ge 1 ]
then
echo "$filename ( ${filesize#[ ]} >= $size
$units )"
fi
fi
;;
esac
done
fi
if [ $verbose -ge 1 ]
then
if [ -n "$compress" ]
then
echo "Compression enabled, using $compress"
fi
fi
rotateOneFile "$filename"
done < "$controlfile"

Logrotate sh

  • 1.
    #!/bin/bash # logrotate -rotate log files # Copyright 2001, Chris F.A. Johnson # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details: # http://www.gnu.org/copyleft/gpl.html usage() { if [ -n "$1" ] then echo " $progname: $*" else echo " $progname - rotate log files" fi if [ $verbose -eq 1 ] then echo " LogRotate is a log rotation script. Run this from cron on a periodic basis (daily, weekly, monthly) etc. " fi echo " USAGE: $progname [OPTIONS] [log-control-file] OPTIONS: -c ZIP - use ZIP (gzip or bzip2) to compress rotated files -d DIR - place rotated files in directory DIR -f FILE - rotate FILE; do not use a control file -k N - keep last N lines of the logfile -n N - keep N log files (default 5) The above options do not override options in a control file unless: -o - override control file options" if [ $verbose -eq 0 ] then echo " -h - help: print this message -H - help: print more detailed message" else echo " -h - help: print shorter message -H - help: print this message" fi echo " -v - verbose: -V - print version information " if [ $verbose -eq 1 ] then
  • 2.
    echo " Ifno control file is given, $progname looks for ./.logrotate.conf then $HOME/.logrotate.conf then /etc/logrotate.conf, and uses the first one it finds. The log-control-file is a text file containing a list of log files to rotate, wherein each entry is on a separate line and each entry contains the name (absolute or relative path: see NOTE) of the log file that needs to be rotated. Each line may also contain options, separated by tabs: dir=D - put rotated files in directory D. The name of the logfile is expanded to the full path and the slashes are changed to dashes. files=N - keep N log files keep=N - keep the last N lines in the file (This leaves them in the rotated file as well; I may change the behaviour to remove them from the rotated file, or add an option to do that.) gzip bzip2 - compress the log files with gzip or bzip2 size=N - do not rotate if the file is less than N bytes or lines N is an integer optionally ending with a letter: B - bytes (default) K - append 000 to the number M - append 000000 to the number G - append 000000000 to the number L - refer to number of lines rather than bytes # --- sample .logrotate.conf --- # Filename = /var/log/foo # Compress with gzip # Maximum number of rotated files = 5 # Keep the last 25 lines of the log file # Don't rotate if the log file contains fewer than 15,000 lines /var/log/foo gzip files=5 keep=25 size=15000L # Filename = ./mylog # All the defaults are used mylog # ---- end .logrotate.conf ---- NOTE: Files in $HOME/.logrotate.conf and /etc/logrotate.conf should be absolute paths, since the working directory could be anywhere (unless a file of a certain name should be rotated wherever it is found)." fi echo " Copyright 2001, Chris F.A. Johnson Please send corrections, improvements, bugs reports, suggestions, etc., to cfaj@freeshell.org Logrotate is derived from a script by javadesigner@yahoo.com with modifications by Heiner Steven, but there is very little of the original code left.
  • 3.
    This script maybe copied under the terms of the GNU General Public License" } fullpath() { filename=${1##*/} dirname=${1%/*} ( cd "$dirname" && echo "`pwd`/$filename" ) } die() { echo "$progname: $*" >&2 exit 1 } rotateOneFile() { logfile=$1 if [ -n "$savedir" ] then savelog="$savedir/`fullpath $logfile | tr '/' '-'`" else savelog=$logfile fi i=${maxno:-$default_maxno} while [ $i -ge 1 ] do newname="$savelog.$i$suffix" i=$(( $i - 1 )) oldlogfile=$savelog.$i$suffix if [ -r "$oldlogfile" ] then mv -f "$oldlogfile" "$newname" || die "Could not move "$oldlogfile" to "$newname"" if [ $verbose -ge 1 ] then echo ""$oldlogfile" --> "$newname"" fi fi done newlogfile="$savelog.0" mv "$logfile" "$newlogfile" || die "Could not move "$logfile" to "$newlogfile"" if [ $verbose -ge 1 ] then echo ""$logfile" --> "$newlogfile"" fi if [ $keep -gt 0 ] then tail -$keep "$newlogfile" > "$logfile" else > $logfile fi if [ "$compress" ] then rm -f "$newlogfile$suffix" $compress $OPT "$newlogfile"
  • 4.
    fi return 0 } version() { echo $version } verbose=0 longusage=0 version="0.5" copyright=2001 author="ChrisF.A. Johnson" progname=${0##*/} TAB=`printf "t"` default_maxno=5 override=0 keep=0 suffix= compress= filename= savedir= while getopts :vVhHf:n:c:k:od: var do case "$var" in c) compress=$OPTARG ;; d) savedir=$OPTARG ;; f) logfile=$OPTARG ;; k) keep=$OPTARG ;; n) maxno=$OPTARG ;; o) override=1 ;; h) usage; exit ;; H) verbose=$(( verbose + 1 )); usage; exit ;; v) verbose=$(( verbose + 1 )) ## allow levels of verbosity OPT="-v" ;; V) version; exit ;; *) usage "Illegal option -- $OPTARG" >&2 exit 1 ;; esac done shift $(( $OPTIND - 1 )) if [ $verbose -eq 3 ] then set -x fi RETURN=0 if [ -n "$filename" ] then if [ -r "$filename" ] then rotateOneFile "$filename" elif [ -f "$filename" ] then echo "$progname: "$filename" is not readable" >&2
  • 5.
    RETURN=1 else echo "$progname: "$filename"not found" >&2 RETURN=1 fi exit $RETURN fi if [ $# -eq 0 ] then if [ -r ./.logrotate.conf ] then controlfile=./.logrotate.conf elif [ -r $HOME/.logrotate.conf ] then controlfile=HOME/.logrotate.conf elif [ -r /etc/logrotate.conf ] then controlfile=/etc/logrotate.conf else echo "$progname: could not find a control file" >&2 exit 1 fi fi if [ $verbose -ge 1 ] then echo "Using ${controlfile}" fi IFS=$TAB while read filename options do case "$filename" in [^/a-zA-Z0-9]#*|#*|"") continue ;; ## skip comments & empty lines esac if [ $verbose -ge 1 ] then echo "FILE: $filename" if [ $verbose -ge 2 ] then echo "OPTIONS: $options" fi fi [ -f "$filename" ] || { # ignore non-existent files if [ $verbose -ge 1 ] then echo "$filename not found" >&2 fi continue } if [ $override -eq 0 ] then suffix= compress= units= savedir= size=0 filesize=0 keep=0 maxno=$default_maxno
  • 6.
    for opt in$options do if [ $verbose -ge 1 ] then echo $opt fi case $opt in files=*) maxno=${opt#*=} ;; keep=*) keep=${opt#*=} ;; gzip) compress=gzip suffix=".gz" ;; bzip2) compress=bzip2 suffix=".bz2" ;; dir=*) savedir=${opt#*=} ;; size=*) size="${opt#*=}" units=bytes if [ "`uname`" = "SunOS" ] then SUN="-g" else SUN="" fi filesize=`ls -l $SUN $filename | { IFS=" " read a b c d size f echo $size }` case $size in [0-9]*B) size="${size%B}" ;; [0-9]*K) size="${size%K}000" ;; [0-9]*M) size="${size%M}000000" ;; [0-9]*G) size="${size%G}000000000" ;; [0-9]*L) size="${size%L}" filesize=$(( `wc -l < $filename` + 0 )) units=lines ;; esac if [ $filesize -lt $size ] then if [ $verbose -ge 1 ] then echo "Skipping $filename ($filesize < ${size%[A-Za-z]})" fi continue 2 else if [ $verbose -ge 1 ] then echo "$filename ( ${filesize#[ ]} >= $size $units )" fi fi ;; esac done fi if [ $verbose -ge 1 ] then
  • 7.
    if [ -n"$compress" ] then echo "Compression enabled, using $compress" fi fi rotateOneFile "$filename" done < "$controlfile"