import os.path
import gettext
import logging
+import pprint
+
+from datetime import tzinfo, timedelta, datetime, date, time
+
+from LogRotateCommon import split_parts
revision = '$Revision$'
revision = re.sub( r'\$', '', revision )
Base class for exceptions in this module.
'''
+#========================================================================
+
+ZERO = timedelta(0)
+
+class UTC(tzinfo):
+ """UTC"""
+
+ def utcoffset(self, dt):
+ return ZERO
+
+ def tzname(self, dt):
+ return "UTC"
+
+ def dst(self, dt):
+ return ZERO
+
+utc = UTC()
+
+
#========================================================================
class LogrotateStatusFile(object):
logger = None,
):
'''
- Costructor.
+ Constructor.
@param config_file: the file name of the status file
@type config_file: str
@type local_dir: str or None
@return: None
- '''
+ '''
self.local_dir = local_dir
'''
# add ch to logger
self.logger.addHandler(ch)
+ # Initial read
+ self._read(must_exists = False)
+
+ #-------------------------------------------------------
+ def as_dict(self):
+ '''
+ Transforms the elements of the object into a dict
+
+ @return: structure as dict
+ @rtype: dict
+ '''
+
+ res = {}
+ res['local_dir'] = self.local_dir
+ res['t'] = self.t
+ res['verbose'] = self.verbose
+ res['file_name'] = self.file_name
+ res['file_name_is_absolute'] = self.file_name_is_absolute
+ res['fd'] = self.fd
+ res['status_version'] = self.status_version
+ res['test_mode'] = self.test_mode
+ res['logger'] = self.logger
+ res['file_state'] = self.file_state
+
+ return res
+
+ #------------------------------------------------------------
+ def __str__(self):
+ '''
+ Typecasting function for translating object structure
+ into a string
+
+ @return: structure as string
+ @rtype: str
+ '''
+
+ pp = pprint.PrettyPrinter(indent=4)
+ return pp.pformat(self.as_dict())
+
#-------------------------------------------------------
def _read(self, must_exists = True):
'''
raise LogrotateStatusFileError(msg)
self.fd = fd
-
+ try:
+ # Reading the lines of the status file
+ i = 0
+ for line in fd:
+ i += 1
+ line = line.strip()
+ if self.verbose > 4:
+ msg = _("Performing status file line '%(line)s' (file: '%(file)s', row: %(row)d)") \
+ % {'line': line, 'file': self.file_name, 'row': i, }
+ self.logger.debug(msg)
+
+ # check for file heading
+ if i == 1:
+ match = re.search(r'^logrotate\s+state\s+-+\s+version\s+([23])$', line, re.IGNORECASE)
+ if match:
+ # Correct file header
+ self.status_version = int(match.group(1))
+ if self.verbose > 1:
+ msg = _("Idendified version of status file: %d") % (self.status_version)
+ self.logger.debug(msg)
+ continue
+ else:
+ # Wrong header
+ msg = _("Incompatible version of status file '%(file)s': %(header)s") \
+ % { 'file': self.file_name, 'header': line }
+ fd.close()
+ raise LogrotateStatusFileError(msg)
+
+ if line == '':
+ continue
+
+ parts = split_parts(line)
+ logfile = parts[0]
+ rdate = parts[1]
+ if self.verbose > 2:
+ msg = _("Found logfile '%(file)s' with rotation date '%(date)s'.") \
+ % { 'file': logfile, 'date': rdate }
+ self.logger.debug(msg)
+
+ if logfile and rdate:
+ match = re.search(r'\s*(\d+)[_\-](\d+)[_\-](\d+)(?:[\s\-_]+(\d+)[_\-:](\d+)[_\-:](\d+))?', rdate)
+ if not match:
+ msg = _("Could not determine date format: '%(date)s' (file: '%(file)s', row: %(row)d)") \
+ % {'date': rdate, 'file': logfile, 'row': i, }
+ self.logger.warning(msg)
+ continue
+ d = {
+ 'Y': int(match.group(1)),
+ 'm': int(match.group(2)),
+ 'd': int(match.group(3)),
+ 'H': 0,
+ 'M': 0,
+ 'S': 0,
+ }
+ if match.group(4) is not None:
+ d['H'] = int(match.group(4))
+ if match.group(5) is not None:
+ d['M'] = int(match.group(5))
+ if match.group(6) is not None:
+ d['S'] = int(match.group(6))
+
+ dt = None
+ try:
+ dt = datetime(d['Y'], d['m'], d['d'], d['H'], d['M'], d['S'], tzinfo = utc)
+ except ValueError, e:
+ msg = _("Invalid date: '%(date)s' (file: '%(file)s', row: %(row)d)") \
+ % {'date': rdate, 'file': logfile, 'row': i, }
+ self.logger.warning(msg)
+ continue
+
+ self.file_state[logfile] = dt
+
+ else:
+
+ msg = _("Neither a logfile nor a date found in line '%(line)s' (file: '%(file)s', row: %(row)d)") \
+ % {'line': line, 'file': logfile, 'row': i, }
+ self.logger.warning(msg)
+
+ finally:
+ fd.close
+
+ self.fd = None
return True
--- /dev/null
+logrotate state -- version 2
+"/var/log/apt/term.log" 2010-6-3
+"/var/log/aptitude" 2010-6-3
+"/var/log/dpkg.log" 2010-6-3
+"/var/log/exim4/mainlog" 2010-6-7
+"/var/log/exim4/rejectlog" 2010-6-3
+"/var/log/exim4/paniclog" 2010-6-3
+"/var/log/mysql.log" 2010-6-7
+"/var/log/mysql/mysql.log" 2010-6-3
+"/var/log/mysql/mysql-slow.log" 2010-6-9
+"/var/log/syslog" 2010-6-9
+"/var/log/mail.info" 2010-6-3
+"/var/log/mail.warn" 2010-6-3
+"/var/log/mail.err" 2010-6-3
+"/var/log/mail.log" 2010-6-3
+"/var/log/daemon.log" 2010-6-6
+"/var/log/kern.log" 2010-6-6
+"/var/log/auth.log" 2010-6-6
+"/var/log/user.log" 2010-6-6
+"/var/log/lpr.log" 2010-6-3
+"/var/log/cron.log" 2010-6-3
+"/var/log/debug" 2010-6-6
+"/var/log/messages" 2010-6-6
+"/var/log/wtmp" 2010-6-3
+"/var/log/btmp" 2010-6-3
+"/var/log/apache2/access.log" 2010-6-8
+"/var/log/apache2/error.log" 2010-6-8
+"/var/log/apache2/other_vhosts_access.log" 2010-6-8
+"/var/log/clamav/clamav.log" 2010-6-8
+"/var/log/clamav/freshclam.log" 2010-6-8
+"/var/log/uucp.log" 2010-6-8
+"/var/log/ulog/syslogemu.log" 2010-6-8
+"/var/log/ulog/ulogd.log" 2010-6-8
+"/var/log/named/complete-debug.log" 2010-10-27
+"/var/log/named/debug.log" 2010-10-27
+"/var/log/named/named.log" 2010-10-27
+"/var/log/named/query.log" 2010-10-27
--- /dev/null
+Logrotate State -- Version 3
+"/var/log/all" 2011-05-31_01:10:01
+"/var/log/debug" 2011-05-31_01:10:01
+"/var/log/facility/auth" 2009-09-14_05:40:03
+"/var/log/facility/authpriv" 2009-07-24_01:10:01
+"/var/log/facility/cron" 2011-06-14_01:10:01
+"/var/log/facility/daemon" 2010-12-06_02:10:01
+"/var/log/facility/kern" 2011-05-19_01:10:02
+"/var/log/facility/local0" 2009-02-20_02:10:01
+"/var/log/facility/local7" 2009-08-19_01:10:02
+"/var/log/facility/syslog" 2011-04-01_01:10:02
+"/var/log/facility/user" 2011-05-31_01:10:01
+"/var/log/fw/iptables.log" 2011-06-11_01:10:01
+"/var/log/fw/ulogd.log" 2011-05-31_01:10:01
+"/var/log/kdm.log" 2011-06-01_01:10:02
+"/var/log/messages" 2011-05-30_01:10:02
+"/var/log/portage/elog/summary.log" 2011-06-06_01:10:01
+"/var/log/syslog" 2011-05-30_01:10:02
+"/var/log/wtmp" 2010-09-12_01:10:02