From 6474ababa49b99170fcdb07a67780bd33e1e230e Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Wed, 29 Jun 2011 17:05:02 +0000 Subject: [PATCH] _do_rotate_file angefangen git-svn-id: http://svn.brehm-online.com/svn/my-stuff/python/PyLogrotate/trunk@265 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa --- LogRotateConfig.py | 13 +++ LogRotateHandler.py | 165 ++++++++++++++++++++++++++++++++++++--- po/LogRotateConfig.de.po | 9 +++ po/LogRotateConfig.pot | 7 ++ test/apache2 | 2 + 5 files changed, 185 insertions(+), 11 deletions(-) diff --git a/LogRotateConfig.py b/LogRotateConfig.py index 791999d..0e1ff66 100755 --- a/LogRotateConfig.py +++ b/LogRotateConfig.py @@ -817,6 +817,19 @@ class LogrotateConfigurationReader(object): ( _("Needless content found at the end of a logfile definition found: '%(rest)s' (file '%(file)s', line %(line)s)") % { 'rest': str(rest), 'file': configfile, 'line': linenr}) ) + # set a compress ext, if Compress is True + if self.new_log['compress']: + if not self.new_log['compress_ext']: + if self.new_log['compress_cmd'] == 'internal_gzip': + self.new_log['compress_ext'] = '.gz' + elif self.new_log['compress_cmd'] == 'internal_bzip2': + self.new_log['compress_ext'] = '.bz2' + else: + msg = _("No extension for compressed logfiles given " + + "(File of definition: '%(file)s', start definition: %(rownum)d).") \ + % { 'file': self.new_log['configfile'], 'rownum': self.new_log['configrow']} + raise LogrotateConfigurationError(msg) + # set ifempty => True, if a minsize was given if self.new_log['size']: self.new_log['ifempty'] = False found_files = self._assign_logfiles() diff --git a/LogRotateHandler.py b/LogRotateHandler.py index e5232fe..c212a4e 100755 --- a/LogRotateHandler.py +++ b/LogRotateHandler.py @@ -219,6 +219,16 @@ class LogrotateHandler(object): ''' self._prepare_templates() + self.logfiles = [] + ''' + @ivar: list of all rotated logfiles. Each entry is a dict with + three keys: + - 'original': str with the name of the unrotated file + - 'rotated': str with the name of the rotated file + - 'oldfiles: list with all old rotated files of this file + @type: list + ''' + self.files_delete = {} ''' @ivar: dictionary with all files, they have to delete @@ -321,6 +331,7 @@ class LogrotateHandler(object): 'files_compress': self.files_compress, 'force': self.force, 'local_dir': self.local_dir, + 'logfiles': self.logfiles, 'logger': self.logger, 'mail_cmd': self.mail_cmd, 'scripts': self.scripts, @@ -634,9 +645,136 @@ class LogrotateHandler(object): # Executing prerotate scripts ... # bla bla bla - if not self._create_olddir(logfile, definition): + olddir = self._create_olddir(logfile, definition) + if olddir is None: + return + + if not self._do_rotate_file(logfile, definition, olddir): return + #------------------------------------------------------------ + def _do_rotate_file(self, logfile, definition, olddir = None): + ''' + The underlaying unconditionally rotation of a logfile. + + After the successful rotation + + @param logfile: the logfile to rotate + @type logfile: str + @param definition: definitions from configuration file + @type definition: dict + @param olddir: the directory of the rotated logfile + if "." or None, store the rotated logfile + in their original directory + @type olddir: str or None + + @return: successful or not + @rtype: bool + ''' + + if (olddir is not None) and (olddir == "."): + olddir = None + + _ = self.t.lgettext + + uid = os.geteuid() + gid = os.getegid() + + msg = _("Do rotate logfile '%s' ...") % (logfile) + self.logger.debug(msg) + + target = self._get_rotation_target(logfile, definition, olddir) + rotations = self._get_rotations(logfile, target, definition) + + return True + + #------------------------------------------------------------ + def _get_rotations(self, logfile, target, definition): + ''' + Retrieves all files to move and to rotate and gives them back + as a dict. + + @param logfile: the logfile to rotate + @type logfile: str + @param target: name of the rotated logfile + @type target: str + @param definition: definitions from configuration file + @type definition: dict + + @return: dict in the form:: + { + 'rotate': { + 'from': , + 'to': + }, + 'move': [ + ... + { 'from': , 'to': }, + { 'from': , 'to': }, + { 'from': , 'to': }, + ], + } + the order in the list 'move' is the order, how the + files have to rename. + @rtype: dict + ''' + + _ = self.t.lgettext + + result = { 'rotate': {}, 'move': [] } + + if self.verbose > 3: + pp = pprint.PrettyPrinter(indent=4) + msg = _("Found rotations:") + "\n" + pp.pformat(result) + self.logger.debug(msg) + return result + + #------------------------------------------------------------ + def _get_rotation_target(self, logfile, definition, olddir = None): + ''' + Retrieves the name of the rotated logfile and gives it back. + + @param logfile: the logfile to rotate + @type logfile: str + @param definition: definitions from configuration file + @type definition: dict + @param olddir: the directory of the rotated logfile + if None, store the rotated logfile + in their original directory + @type olddir: str or None + + @return: name of the rotated logfile + @rtype: str + ''' + + _ = self.t.lgettext + + if self.verbose > 2: + msg = _("Retrieving the name of the rotated file of '%s' ...") % (logfile) + self.logger.debug(msg) + + target = logfile + if olddir is not None: + basename = os.path.basename(logfile) + target = os.path.join(olddir, basename) + + if definition['dateext']: + pattern = definition['datepattern'] + if pattern is None: + pattern = '%Y-%m-%d' + dateext = datetime.utcnow().strftime(pattern) + if self.verbose > 3: + msg = _("Using date extension '.%(ext)s' from pattern '%(pattern)s'.") \ + % {'ext': dateext, 'pattern': pattern} + self.logger.debug(msg) + target += "." + dateext + + if self.verbose > 1: + msg = _("Using '%(target)s' as target for rotation of logfile '%(logfile)s'.") \ + % {'target': target, 'logfile': logfile} + self.logger.debug(msg) + return target + #------------------------------------------------------------ def _create_olddir(self, logfile, definition): ''' @@ -647,8 +785,11 @@ class LogrotateHandler(object): @param definition: definitions from configuration file (for olddir) @type definition: dict - @return: successful or not - @rtype: bool + @return: Name of the retrieved olddir, ".", if storing + the rotated logfiles in their original directory or + None in case of some minor errors (olddir couldn't + created a.s.o.) + @rtype: str or None ''' _ = self.t.lgettext @@ -661,7 +802,7 @@ class LogrotateHandler(object): if self.verbose > 1: msg = _("No dirname directive for olddir given.") self.logger.debug(msg) - return True + return "." olddir = o['dirname'] mode = o['mode'] @@ -718,15 +859,16 @@ class LogrotateHandler(object): if self.verbose > 2: msg = _("Olddir '%s' allready exists, not created.") % (olddir) self.logger.debug(msg) - return True + olddir = os.path.realpath(olddir) + return olddir else: msg = _("No write and execute access to olddir '%s'.") % (olddir) raise LogrotateHandlerError(msg) - return False + return None else: msg = _("Olddir '%s' exists, but is not a valid directory.") % (olddir) raise LogrotateHandlerError(msg) - return False + return None dirs = [] dir_head = olddir @@ -767,7 +909,7 @@ class LogrotateHandler(object): else: msg = _("Directory '%s' exists, but is not a valid directory.") % (create_dir) self.logger.error(msg) - return False + return None msg = _("Creating directory '%s' ...") % (create_dir) self.logger.debug(msg) create_mode = parent_mode @@ -793,7 +935,7 @@ class LogrotateHandler(object): msg = _("Error on creating directory '%(dir)s': %(err)s") \ % {'dir': create_dir, 'err': e.strerror} self.logger.error(msg) - return False + return None if (create_uid != uid) or (create_gid != gid): if self.verbose > 2: msg = "os.chown('%s', %d, %d)" % (create_dir, create_uid, create_gid) @@ -804,9 +946,10 @@ class LogrotateHandler(object): msg = _("Error on chowning directory '%(dir)s': %(err)s") \ % {'dir': create_dir, 'err': e.strerror} self.logger.error(msg) - return False + return None - return True + olddir = os.path.realpath(olddir) + return olddir #------------------------------------------------------------ def _execute_command(self, command): diff --git a/po/LogRotateConfig.de.po b/po/LogRotateConfig.de.po index bb247e6..f059ceb 100644 --- a/po/LogRotateConfig.de.po +++ b/po/LogRotateConfig.de.po @@ -135,6 +135,15 @@ msgstr "" "Nutzloser Inhalt am Ende einer Logdateidefinition gefunden: »%(rest)s« " "(Datei »%(file)s«, Zeile %(line)s)" +#: LogRotateConfig.py:828 +#, python-format +msgid "" +"No extension for compressed logfiles given " +"(File of definition: '%(file)s', start definition: %(rownum)d)." +msgstr "" +"Keine Dateierweiterung für die komprimierten Logdateien gegeben " +"(Beginn der Definition: Datei »%(file)s«, Zeile %(rownum)d)." + #: LogRotateConfig.py:791 msgid "New logfile definition:" msgstr "Neue Logdateidefinition:" diff --git a/po/LogRotateConfig.pot b/po/LogRotateConfig.pot index debf1bf..1ed94b7 100644 --- a/po/LogRotateConfig.pot +++ b/po/LogRotateConfig.pot @@ -123,6 +123,13 @@ msgid "" "line %(line)s)" msgstr "" +#: LogRotateConfig.py:828 +#, python-format +msgid "" +"No extension for compressed logfiles given " +"(File of definition: '%(file)s', start definition: %(rownum)d)." +msgstr "" + #: LogRotateConfig.py:791 msgid "New logfile definition:" msgstr "" diff --git a/test/apache2 b/test/apache2 index 23043c0..0e786a4 100644 --- a/test/apache2 +++ b/test/apache2 @@ -6,6 +6,7 @@ pidfile /home/frank/Development/Python/PyLogrotate/logrotate.pid statusfile /home/frank/Development/Python/PyLogrotate/logrotate.status /home/frank/devel/Python/PyLogrotate/test/log/access_log { + compress missingok notifempty sharedscripts @@ -23,6 +24,7 @@ statusfile /home/frank/Development/Python/PyLogrotate/logrotate.status } /home/frank/devel/Python/PyLogrotate/test/log/*.log { + compress missingok notifempty sharedscripts -- 2.39.5