]> Frank Brehm's Git Trees - my-stuff/py-logrotate.git/commitdiff
Mit Logrotating weitergemacht
authorFrank Brehm <frank@brehm-online.com>
Mon, 27 Jun 2011 15:46:52 +0000 (15:46 +0000)
committerFrank Brehm <frank@brehm-online.com>
Mon, 27 Jun 2011 15:46:52 +0000 (15:46 +0000)
git-svn-id: http://svn.brehm-online.com/svn/my-stuff/python/PyLogrotate/trunk@262 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa

LogRotateConfig.py
LogRotateHandler.py
LogRotateStatusFile.py
logrotate.py
test/apache2

index 5eecbda9d8207d5afcdbd38ab3a834f616d11397..791999de4504cb93c915a2249adc3eeb5a98419e 100755 (executable)
@@ -817,9 +817,11 @@ 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})
                     )
+                if self.new_log['size']:
+                    self.new_log['ifempty'] = False
+                found_files = self._assign_logfiles()
                 if self.verbose > 3:
                     self.logger.debug( ( _("New logfile definition:") + "\n" + pp.pformat(self.new_log)))
-                found_files = self._assign_logfiles()
                 if found_files > 0:
                     self.config.append(self.new_log)
                 in_fd = False
index fcf6597b35f8db81ff5c1e590fa3b2dc188519d1..d7c89b113b5cc889fe983b8485b9a9c2721d84dd 100755 (executable)
@@ -24,12 +24,15 @@ import os
 import os.path
 import errno
 import socket
+import subprocess
+from datetime import datetime, timedelta
 
 from LogRotateConfig import LogrotateConfigurationError
 from LogRotateConfig import LogrotateConfigurationReader
 
 from LogRotateStatusFile import LogrotateStatusFileError
 from LogRotateStatusFile import LogrotateStatusFile
+from LogRotateStatusFile import utc
 
 revision = '$Revision$'
 revision = re.sub( r'\$', '', revision )
@@ -573,10 +576,183 @@ class LogrotateHandler(object):
                     "\n" + pp.pformat(definition)
             self.logger.debug(msg)
 
-
+        for logfile in definition['files']:
+            if self.verbose > 1:
+                msg = ( _("Performing logfile '%s' ...") % (logfile)) + "\n"
+                self.logger.debug(msg)
+            should_rotate = self._should_rotate(logfile, definition)
+            if self.verbose > 1:
+                if should_rotate:
+                    msg = _("logfile '%s' WILL rotated.")
+                else:
+                    msg = _("logfile '%s' will NOT rotated.")
+                self.logger.debug(msg % (logfile))
+            if not should_rotate:
+                continue
+            self._rotate_file(logfile, definition)
 
         return
 
+    #------------------------------------------------------------
+    def _rotate_file(self, logfile, definition):
+        '''
+        Rotates a logfile with all with all necessary actions before
+        and after rotation.
+
+        Throughs an LogrotateHandlerError on error.
+
+        @param logfile: the logfile to rotate
+        @type logfile:  str
+        @param definition: definitions from configuration file
+        @type definition:  dict
+
+        @return: None
+        '''
+
+        _ = self.t.lgettext
+
+        sharedscripts = definition['sharedscripts']
+        firstscript   = definition['firstaction']
+        prescript     = definition['prerotate']
+        postscript    = definition['postrotate']
+        lastscript    = definition['lastaction']
+
+        # Executing of the firstaction script, if it wasn't executed
+        if firstscript:
+            if self.verbose > 2:
+                msg = _("Looking, whether the firstaction script should be executed.")
+                self.logger.debug(msg)
+            if not self.scripts[firstscript]['first']:
+                msg = _("Executing firstaction script '%s' ...") % (firstscript)
+                self.logger.info(msg)
+                if not self.test:
+                    cmd = '\n'.join(self.scripts[firstscript]['cmd'])
+                    if not self._execute_command(cmd):
+                        return
+                self.scripts[firstscript]['first'] = True
+
+        # 
+
+    #------------------------------------------------------------
+    def _execute_command(self, command):
+        '''
+        Executes the given command as an OS command in a shell.
+
+        @param command: the command to execute
+        @type command:  str
+
+        @return: Success of the comand (shell returncode == 0)
+        @rtype:  bool
+        '''
+
+        _ = self.t.lgettext
+        if self.verbose > 3:
+            msg = _("Executing command: '%s'") % (command)
+            self.logger.debug(msg)
+        try:
+            retcode = subprocess.call(command, shell=True)
+            if self.verbose > 3:
+                msg = _("Got returncode: '%s'") % (retcode)
+                self.logger.debug(msg)
+            if retcode < 0:
+                msg = _("Child was terminated by signal %d") % (-retcode)
+                self.logger.error(msg)
+                return False
+            if retcode > 0:
+                return False
+            return True
+        except OSError, e:
+            msg = _("Execution failed: %s") % (str(e))
+            self.logger.error(msg)
+            return False
+
+        return False
+
+    #------------------------------------------------------------
+    def _should_rotate(self, logfile, definition):
+        '''
+        Determines, whether a logfile should rotated dependend on
+        the informations in the definition.
+
+        Throughs an LogrotateHandlerError on harder errors.
+
+        @param logfile: the logfile to inspect
+        @type logfile:  str
+        @param definition: definitions from configuration file
+        @type definition:  dict
+
+        @return: to rotate or not
+        @rtype:  bool
+        '''
+
+        _ = self.t.lgettext
+
+        if self.verbose > 2:
+            msg = _("Check, whether logfile '%s' should rotated.") % (logfile)
+            self.logger.debug(msg)
+
+        if not os.path.exists(logfile):
+            msg = _("logfile '%s' doesn't exists, not rotated") % (logfile)
+            if not definition['missingok']:
+                self.logger.error(msg)
+            else:
+                if self.verbose > 1:
+                    self.logger.debug(msg)
+            return False
+
+        if not os.path.isfile(logfile):
+            msg = _("logfile '%s' is not a regular file, not rotated") % (logfile)
+            self.logger.warning(msg)
+            return False
+
+        filesize = os.path.getsize(logfile)
+        if self.verbose > 2:
+            msg = _("Filesize of '%(file)s': %(size)d") % {'file': logfile, 'size': filesize}
+            self.logger.debug(msg)
+
+        if not filesize:
+            if not definition['ifempty']:
+                if self.verbose > 1:
+                    msg = _("Logfile '%s' has a filesize of Zero, not rotated") % (logfile)
+                    self.logger.debug(msg)
+                return False
+
+        if self.force:
+            if self.verbose > 1:
+                msg = _("Rotating of '%s' because of force mode.") % (logfile)
+                self.logger.debug(msg)
+            return True
+
+        maxsize = definition['size']
+        if maxsize is None:
+            maxsize = 0
+
+        last_rotated = self.state_file.get_rotation_date(logfile)
+        if self.verbose > 2:
+            msg = _("Date of last rotation: %s") %(last_rotated.isoformat(' '))
+            self.logger.debug(msg)
+        next_rotation = last_rotated + timedelta(days = definition['period'])
+        if self.verbose > 2:
+            msg = _("Date of next rotation: %s") %(next_rotation.isoformat(' '))
+            self.logger.debug(msg)
+
+        if filesize < maxsize:
+            if self.verbose > 1:
+                msg = _("Filesize %(filesize)d is less than %(maxsize)d, rotation not necessary.") \
+                        % {'filesize': filesize, 'maxsize': maxsize}
+                self.logger.debug(msg)
+            return False
+
+        curdate = datetime.utcnow().replace(tzinfo = utc)
+        if next_rotation > curdate:
+            if self.verbose > 1:
+                msg = _("Date of next rotation '%(next)s' is in future, rotation not necessary.") \
+                        % {'next': next_rotation.isoformat(' ')}
+                self.logger.debug(msg)
+            return False
+
+        return True
+
     #------------------------------------------------------------
     def delete_oldfiles(self):
         pass
index 75537052d82a2b94933abf199f96a4959b89c283..43132083c2776f1f3848f00ffe20bedcbd7d60a4 100755 (executable)
@@ -267,7 +267,7 @@ class LogrotateStatusFile(object):
         if not self.was_read:
             self._read(must_exists = False)
 
-        rotate_date = datetime.min()
+        rotate_date = datetime.min.replace(tzinfo=utc)
         if logfile in self.file_state:
             rotate_date = self.file_state[logfile]
 
index 7ce1dc6d4c11c7a27a9f275b0f25438363726b9c..953a69cac0a451506b0d892bd7c2b704c61d3b90 100755 (executable)
@@ -17,6 +17,7 @@ import re
 import sys
 import pprint
 import gettext
+import os
 import os.path
 from datetime import datetime
 
@@ -40,6 +41,9 @@ __license__    = 'GPL3'
 #-----------------------------------------------------------------
 def main():
 
+    # unbuffered output to stdout
+    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+
     basedir = os.path.realpath(os.path.dirname(sys.argv[0]))
     #print "Basedir: %s" % ( basedir )
     local_dir = os.path.join(basedir, 'po')
index 680ac24776118623ad947fd35b082f90b7cbf01d..2ae67d973e871900f3583dd5bf3725fcbb3774bb 100644 (file)
@@ -3,42 +3,42 @@
 #
 
 pidfile /home/frank/Development/Python/PyLogrotate/logrotate.pid
+statusfile /home/frank/Development/Python/PyLogrotate/logrotate.status
 
-/var/log/apache2/access_log {
-  missingok
-  notifempty
-  sharedscripts
-  rotate 10
-  dateext
-  daily
-  size 5M
-  maxage 0.5y
-  mail test@uhu-banane.de
-  olddir /var/log/apache2/%Y-%m 0755 apache users
-  postrotate
-      /etc/init.d/apache2 reload > /dev/null 2>&1 || true
-  endscript
+/home/frank/devel/Python/PyLogrotate/test/log/access_log {
+    missingok
+    notifempty
+    sharedscripts
+    rotate 10
+    dateext
+    daily
+    size 5K
+    maxage 0.5y
+    mail       test@uhu-banane.de
+    olddir /var/log/apache2/%Y-%m 0755 apache users
+    postrotate
+        echo "/etc/init.d/apache2 reload > /dev/null 2>&1 || true"
+    endscript
 }
 
-/var/log/apache2/access_log
-/var/log/apache2/*.log
-{
-  missingok
-  notifempty
-  sharedscripts
-  rotate 10
-  #dateext '%Y%m%d'
-  dateext
-  #error bla
-  weekly
-  #period 4.5days 2 hours 3.4y
-  size 1M
-  maxage 0.5y
-  mail test@uhu-banane.de
-  #olddir /var/log/apache2/%Y-%m
-  olddir /var/log/apache2/%Y-%m 0755 apache users
-  postrotate
-  /etc/init.d/apache2 reload > /dev/null 2>&1 || true
-  endscript
+/home/frank/devel/Python/PyLogrotate/test/log/*.log {
+    missingok
+    notifempty
+    sharedscripts
+    rotate 10
+    #dateext '%Y%m%d'
+    dateext
+    #error bla
+    weekly
+    #period 4.5days 2 hours 3.4y
+    size 1K
+    maxage 0.5y
+    mail       test@uhu-banane.de
+    #olddir /var/log/apache2/%Y-%m
+    olddir /var/log/apache2/%Y-%m 0755 apache users
+    postrotate
+        echo "/etc/init.d/apache2 reload > /dev/null 2>&1 || true"
+    endscript
 }
 
+# vim: ts=4 expandtab