                      _        _    _
                     |_) _ |_ /  |_  \ |   _  _
                     | \(_)(_ \_ (_ _/ |__(_)(_)
                     By Stefano Falsetto     ,_)

This is Rot[t]Log

archive, rotates, compresses, and mails system logs.

This is a replacement to Red Hat's logrotate. It have similar
syntax, but more powerful features to cut and store logs. 
In this README there are many parts taken from man page of logrotate.
It's all written in BASH (2.x compatible).

This script require GNU fileutils and GNU grep.

USE WITH CARE
At this moment this software is still in alpha stage, so... handle with care 
your logs...

Main configuration file	  : /etc/rottlog/rc
Other configuration files : /etc/rottlog/[daily|weekly|monthly]

rottlog first read main configuration file, then read (in given order)
daily, weekly and monthly configuration files.

  ::::: RC FILE SYNTAX :::::

  following keywords are valid:
  packer=<complete path> 
  complete path to packer program to be used to compress logs

  compress=<options>
  options to be used with packer program to compress data
  IMPORTANT: Packer program must output data to stdout 
  (i.e. for gzip/bzip2 use -c)

  unpacker=<complete path>
  complete path to program to be used to uncompress logs 
  (i.e. gunzip, bunzip2...)

  uncompress=<options>
  options to be used with unpacker program to uncompress data
  IMPORTANT: Unpacker program must output data to stdout
  (i.e. for gunzip/bunzip2 use -c)

  extension=<ext>
  Extension normally used when compressing data with packer 
  (i.e. for gzip is gz, for bzip2 is bz2, ...)
  This variable is used to expand meta-variable @COMP_EXT

  packdir=<path-to-archive-dir>
  default basedir to store rotated/archived files

  fromuser=<sender address>
  Sender address used in mail messages

  touser=<receiver address>
  Receiver of mail messages
 
  notifempty
  Do not rotate a logfile if it's empty.

  mail=<mailer prg>
  Mail program to send messages. Must be used option to read header recipient
  addresses. (i.e. for sendmail use -t, for qmail-inject use -h)

  maxdepth=<depth>
  Default maximum depth to search for files when used * metachar in log 
  filename definition.

  follow_symlinks=<0|1>
  If set to 0 don't follow symlinks to logfiles


  ::::: DAILY|WEEKLY|MONTHLY FILE SYNTAX :::::

  A configuration block for logfiles is structured as follow:

  <logfile1>,<logfile2>,... {
    <storedir> <path-to-dir>
    <nostoredir>
    <storefile> <filename>
    <logpart> <qdldl>
    <postrotate> ... <endscript>
    <prerotate> ... <endscript>
    <delaycompress>
    <nocompress>
    <touser> <email address>
    <create> <mode> <owner> <group>
    <createdir> [<perms>] [<own> <grp>]
    <nocreate>
    <append-only>
    <nomail>
    <ifempty>
    <size> <num[b,k,M]>
    <noifempty>
    <rotate> <number>
    <maxdepth> <depth>
  }

  Where:
  
  logfile1, logfile2, ... 
  Is a comma separated list of complete absolute path to logfiles to 
  archive/rotate. From 0.10alpha+ version it's possible to use ONLY metachar
  asterisk. (i.e. /var/adm/log.* means that options defined in block between 
  curly brackets are applied to all files in /var/adm dir beginning by log.)
  If same logfile is used more than one time in same configuration file, will
  be used only the first.

  storedir <path-to-dir>
  If it's a relative path it will be appended to packdir defined in rc file,
  if it's an absolute path it will be used instead of packdir. Can be used
  metavariables. See section metavariables for more info.

  nostoredir
  Logs are rotated/archived in the same directory the log normally
  resides in.

  storefile <filename>
  Name of compressed logfile to be used (whitout any path: filename only)
  Can be used metavariables. See section metavariables for more info.

  logpart <qdldl>
  Leave a part of log to archive/rotate in logfile.
  qdldr can be:
  <number>l
  <number>b
  "<regexp>"
  "<#1 day>"
  Where l and b means lines and bytes respectively.
  "regexp" is a regular expression used by grep to find first row to leave in 
  log.
  "#1 day" is a shortcut to leave in log all events recorded from first day of 
  current month.

  prerotate ... endscript
  Lines between prerotate and endscript (both of which must appear on 
  lines by themselves) are executed before the log file is archived/rotated. 
  Can be used metavariables. See section metavariables for more info.
  
  postrotate ... endscript
  Lines between postrotate and endscript (both of which must appear on 
  lines by themselves) are executed after the log file is archived/rotated. 
  Can be used metavariables. See section metavariables for more info.

  nocompress
  Old versions of log files are not compressed with packer defined in rc
  file

  delaycompress
  Postpone compression of the previous log file to the next rotation
  cycle.
  It can be used when some program can not be told to close its
  logfile and thus might continue writing to the previous log file for
  some time.

  touser <email address>
  Override global value of touser variable defined in rc file

  create <mode owner group>
  Immediately  after  rotation (before the postrotate script is run)
  the log file is  created  (with  the same  name  as  the  log  file
  just rotated).  mode specifies the mode for the log file in  octal
  (the same  as  chmod(2)),  owner specifies the user name who will
  own the log file, and group specifies  the group  the  log file will
  belong to. Any of the log file attributes may be omitted, in which
  case those attributes  for the new file will use the same values as
  the  original  log  file  for  the  omitted attributes.

  nocreate
  Don't create a new filename if it's not used logpart.

  ifempty
  Rotate the log file even if it is empty, overriding the notifempty option
  
  notifempty
  Do not rotate the log if it is empty

  rotate <number>
  Log files are rotated <number> times before being removed.

  nomail
  Don't send notification e-mail message

  append-only
  To be used only on ext[23] fs. Set append-only attribute to a log
  (More precisely: remove this attribute before handle log, and reset it
  after performed all operations)

  size <num[b,k,M]>
  Rotate a logfile only if it grows specified dimension.
  Parameter must be a number followed by one of following chars:
  b - means bytes
  k - means kbytes (num * 1024)
  M - means megabytes (num * 1000000)

  If none of these three chars is used, b is default.

  createdir [<perms>] [<own> <grp>] 
  Create (if needed) dir to store archived/rotated logs with specified 
  permissions and owner:group. If none of three parameters is specified
  directory will be created with permissions and owner defined in default
  variables DIR_PERM, DIR_OWN, and DIR_GRP. You can specify perms only, or
  perms and own, but you can't to specify perms and grp (second parameter is
  always interpreted as owner).
  perms specifies the mode for the log file in octal (the same as chmod(2)).
  IMPORTANT:
  If path to be created is deeper than one dir only last dir will have
  own, and perms specified. 
  Example:
  
  storedir 2002/04/apache_logs
  createdir 4300 rottlog

  If dir 2002 (and following) are not already present on your box afer rottlog
  run you will have (if rottlog is run by user stefano):
  $ ls -ld 2002 2002/04 2002/04/apache_logs
  drwxr-xr-x   2 stefano  users        1024 Apr 11 18:35 2002/
  drwxr-xr-x   2 stefano  users        1024 Apr 11 18:35 2002/04
  d-ws------   2 rottlog  users        1024 Apr 11 18:35 2002/04/apache_logs
  

  ::::: USE OF META-VARIABLES :::::

  In monthly/weekly/daily logs can be used metavariables.
  Metavariables are identifiers of a runtime defined value.
  Handled metavariables:

  @BASEDIR  : Dir containing logfile to be archived/rotated
  @FILENAME : filename with numerical extension (BASENAME+NEXT_EXT)
  @BASENAME : filaname without extension
  @COMP_EXT : extension of compressed format file (bz2, gz, ...)
  @NEXT_EXT : next available numbered extension 
  @YEAR     : actual year(*)
  @DAY      : actual day(*)
  @MONTH    : actual month(*)

 (*) Can't be used in storefile if using rotate parameter too

  Parameters handling metavariables:
  storedir
  storefile
  prerotate...endscript
  postrotate...endscript

  These values are defined while script is running, so a definition
  like this:

  /var/adm/log.* {
    storedir /var/adm/archive-log/@BASENAME
    rotate 5
    ...
  }

  Means that I wants to rotate 5 times all files in /var/adm beginning by 
  "log." and store each file in a dir named with logname.
  (i.e. /var/adm/archive-log/log.kern, /var/adm/archive-log/log.daemon, ...)

  ::::: COMMAND LINE PARAMETERS :::::

  Valid command line parameters allowed are:
  
    --help, -h
    Display help page and exit. Does nothing else.
    
    --version, -V
    Display version, disclamier and exit. Does nothing else.
    
    --defaults
    Display defaults values and exit. Useful to know default behavoir of
    rottlog
    
    --showlog <logfile>, -s <logfile>
    Show contents of archived <logfile> with default pager. <logfile> must be
    only a filename without any path.
    
    --pager <program>
    Use <program> for paging output of showlog. Useful only with --showlog
    
    --summary <logfile>
    Display a summary of some useful information about <logfile>. Does not
    exec any rotate/archive action.
    
    --checkrc <what>,<what>,...
    Check for syntax of specified configuration file(s)
    <what> must be one of: daily, weekly, monthly, all

    --force [<daily>] [<weekly>] [<monthly>]

    Force rotation/archiviation of logfiles , even  if  it
    doesn't think this is necessary.  Sometimes this is useful
    after adding new entries to some config file, or if old log files
    have been removed by hand, as the new files will be created,
    and  logging  will  continue correctly.
    If none of daily,weekly and monthly is used, will be forced
    rotation/archiviation of all entries in all config files.



============================================================================
TODO: remove this section?

  AT THIS MOMENT (0.20alpha)
  If a storedir definition is used AFTER a storefile definition you can have
  an inaspected behavoir. One example is better than too much words:
  
  /var/adm/log.debug {
    storedir /var/adm/archive-log/@FILENAME
    storefile @BASENAME-@YEAR.@MONTH.@DAY.@NEXT_EXT
    rotate 5
    ....
  }

  With this definition I will store compressed logfiles in:
  /var/adm/archive-log/log.debug dir, with filenames called something like:
  log.debug-2002.03.09.[number]
  where [number] is a sequential incremented by one number between 1 and 5
  (first time logfile will be rotated it will have .1 extension, second time
  Rot[t]Log will find old logfile with .1 extension, so will use .2, third 
  time will find .2 and will use .3, and so on...)

  But if I swap first two lines:

  /var/adm/log.debug {
    storefile @BASENAME-@YEAR.@MONTH.@DAY.@NEXT_EXT
    storedir /var/adm/archive-log/@FILENAME
    rotate 5
    ....
  }

  I will store compressed logfiles in: /var/adm/archive-log/log.debug dir,
  with filenames called something like: log.debug-2002.03.09.1
  Yes: .1 ALWAYS.
  In fact at the time @NEXT_EXT is evaluated, storedir is still default
  defined path, so old compressed logfiles will not be found and will be 
  always used .1 extension.

  The same concept must be used with all parameters accepting metavariables
  
