From: Frank Brehm Date: Sat, 7 May 2011 21:07:29 +0000 (+0000) Subject: check for period X-Git-Url: https://git.uhu-banane.de/?a=commitdiff_plain;h=6a94fe20a1085e5e6661d8f43492e5f65f2756ea;p=my-stuff%2Fpy-logrotate.git check for period git-svn-id: http://svn.brehm-online.com/svn/my-stuff/python/PyLogrotate/trunk@227 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa --- diff --git a/LogRotateCommon.py b/LogRotateCommon.py index 8490ee0..29c526d 100755 --- a/LogRotateCommon.py +++ b/LogRotateCommon.py @@ -15,6 +15,7 @@ import re import sys +import locale revision = '$Revision$' revision = re.sub( r'\$', '', revision ) @@ -148,6 +149,157 @@ def email_valid(address): return True +#------------------------------------------------------------------------ + +def period2days(period, use_locale_radix = False, verbose = 0): + ''' + Converts the given string of the form »5d 8h« in an amount of days. + It raises a ValueError on invalid values. + + Special values of period: + - now (returns 0) + - never (returns float('inf')) + + Valid units for periods are: + - »h[ours]« + - »d[ays]« - default, if bare numbers are given + - »w[eeks]« - == 7 days + - »m[onths]« - == 30 days + - »y[ears]« - == 365 days + + @param period: the period to convert + @type period: str + @param use_locale_radix: use the locale version of radix instead of the + english decimal dot. + @type use_locale_radix: bool + @param verbose: level of verbosity + @type verbose: int + + @return: amount of days + @rtype: float + ''' + + if period is None: + raise ValueError("Given period is »None«") + + value = str(period).strip().lower() + if period == '': + raise ValueError("Given period was empty") + + if verbose > 4: + sys.stderr.write("period2days() called with: »%s«\n" % (period)) + + if period == 'now': + return float(0) + + # never - returns a positive infinite value + if period == 'never': + return float('inf') + + days = float(0) + radix = '.' + if use_locale_radix: + radix = locale.RADIXCHAR + radix = re.escape(radix) + if verbose > 5: + sys.stderr.write("period2days(): using radix »%s«\n" % (radix)) + + # Search for hours in value + pattern = r'(\d+(?:' + radix + r'\d*)?)\s*h(?:ours?)?' + if verbose > 5: + sys.stderr.write("period2days(): pattern »%s«\n" % (pattern)) + match = re.search(pattern, value, re.IGNORECASE) + if match: + hours_str = match.group(1) + if use_locale_radix: + hours_str = re.sub(radix, '.', hours_str, 1) + hours = float(hours_str) + days += (hours/24) + if verbose > 4: + sys.stderr.write("period2days(): found %f hours.\n" %(hours)) + value = re.sub(pattern, '', value, re.IGNORECASE) + if verbose > 5: + sys.stderr.write("period2days(): rest after hours: »%s«\n" %(value)) + + # Search for weeks in value + pattern = r'(\d+(?:' + radix + r'\d*)?)\s*w(?:eeks?)?' + if verbose > 5: + sys.stderr.write("period2days(): pattern »%s«\n" % (pattern)) + match = re.search(pattern, value, re.IGNORECASE) + if match: + weeks_str = match.group(1) + if use_locale_radix: + weeks_str = re.sub(radix, '.', weeks_str, 1) + weeks = float(weeks_str) + days += (weeks*7) + if verbose > 4: + sys.stderr.write("period2days(): found %f weeks.\n" %(weeks)) + value = re.sub(pattern, '', value, re.IGNORECASE) + if verbose > 5: + sys.stderr.write("period2days(): rest after weeks: »%s«\n" %(value)) + + # Search for months in value + pattern = r'(\d+(?:' + radix + r'\d*)?)\s*m(?:onths?)?' + if verbose > 5: + sys.stderr.write("period2days(): pattern »%s«\n" % (pattern)) + match = re.search(pattern, value, re.IGNORECASE) + if match: + months_str = match.group(1) + if use_locale_radix: + months_str = re.sub(radix, '.', months_str, 1) + months = float(months_str) + days += (months*30) + if verbose > 4: + sys.stderr.write("period2days(): found %f months.\n" %(months)) + value = re.sub(pattern, '', value, re.IGNORECASE) + if verbose > 5: + sys.stderr.write("period2days(): rest after months: »%s«\n" %(value)) + + # Search for years in value + pattern = r'(\d+(?:' + radix + r'\d*)?)\s*y(?:ears?)?' + if verbose > 5: + sys.stderr.write("period2days(): pattern »%s«\n" % (pattern)) + match = re.search(pattern, value, re.IGNORECASE) + if match: + years_str = match.group(1) + if use_locale_radix: + years_str = re.sub(radix, '.', years_str, 1) + years = float(years_str) + days += (years*365) + if verbose > 4: + sys.stderr.write("period2days(): found %f years.\n" %(years)) + value = re.sub(pattern, '', value, re.IGNORECASE) + if verbose > 5: + sys.stderr.write("period2days(): rest after years: »%s«\n" %(value)) + + # At last search for days in value + pattern = r'(\d+(?:' + radix + r'\d*)?)\s*(?:d(?:ays?)?)?' + if verbose > 5: + sys.stderr.write("period2days(): pattern »%s«\n" % (pattern)) + match = re.search(pattern, value, re.IGNORECASE) + if match: + days_str = match.group(1) + if use_locale_radix: + days_str = re.sub(radix, '.', days_str, 1) + days_float = float(days_str) + days += days_float + if verbose > 4: + sys.stderr.write("period2days(): found %f days.\n" %(days_float)) + value = re.sub(pattern, '', value, re.IGNORECASE) + if verbose > 5: + sys.stderr.write("period2days(): rest after days: »%s«\n" %(value)) + + # warn, if there is a rest + if re.search(r'^\s*$', value) is None: + sys.stderr.write( + "period2days(): invalid content for a period: »%s«\n" %(value) + ) + + if verbose > 4: + sys.stderr.write("period2days(): total %f days found.\n" %(days)) + + return days + #======================================================================== if __name__ == "__main__": diff --git a/LogRotateConfig.py b/LogRotateConfig.py index 3598821..47e3195 100755 --- a/LogRotateConfig.py +++ b/LogRotateConfig.py @@ -20,7 +20,7 @@ import pprint import os import os.path -from LogRotateCommon import split_parts, email_valid +from LogRotateCommon import split_parts, email_valid, period2days revision = '$Revision$' revision = re.sub( r'\$', '', revision ) @@ -97,6 +97,23 @@ path_options = ( 'pidfile', ) +valid_periods = { + 'hourly': (1/24), + '2hourly': (1/12), + '4hourly': (1/6), + '6hourly': (1/4), + '12hourly': (1/2), + 'daily': 1, + '2daily': 2, + 'weekly': 7, + 'monthly': 30, + '2monthly': 60, + '4monthly': 120, + '6monthly': 182, + 'yearly': 365, +} + + #======================================================================== class LogrotateConfigurationError(Exception): @@ -1130,7 +1147,7 @@ class LogrotateConfigurationReader(object): if key in path_options: if not os.path.abspath(val): self.logger.warning( - ( _("Value »%s« for option »%s« is not an absolute " + ( _("Value »%s« for option »%s« is not " + "an absolute path") % (val, key) ) ) @@ -1144,6 +1161,45 @@ class LogrotateConfigurationReader(object): directive[key] = val return True + # Check for rotation period + pattern = r'^(' + '|'.join(valid_periods.keys()) + r'|period)$' + match = re.search(pattern, option, re.IGNORECASE) + if match: + key = match.group(1).lower() + if self.verbose > 4: + self.logger.debug( + ( _("Checking »period«: key »%s«, value »%s«. " + + "(file »%s«, line %s)") + % (key, val, filename, linenr) + ) + ) + option_value = 1 + if key in valid_periods: + if (val is not None) and (re.search(r'^\s*$', val) is None): + self.logger.warning( + ( _("Option »%s« may not have a value (»%s«). " + + "(file »%s«, line %s)") + %(key, val, filename, linenr) + ) + ) + option_value = valid_periods[key] + else: + try: + option_value = period2days(val, verbose = self.verbose) + except ValueError, e: + self.logger.warning( + ( _("Invalid period definition: »%s«") %(val) ) + ) + return False + if self.verbose > 4: + self.logger.debug( + ( _("Setting »period« to %f days. (file »%s«, line %s)") + % (option_value, filename, linenr) + ) + ) + directive['period'] = option_value + return True + return True #------------------------------------------------------------ diff --git a/test/apache2 b/test/apache2 index 1f24f14..fce39be 100644 --- a/test/apache2 +++ b/test/apache2 @@ -11,6 +11,7 @@ rotate 10 error bla weekly + #period 4.5days 2 hours 3.4y size 1m mail test@uhu-banane.de olddir /var/log/apache2/%Y-%m