Skip to content Skip to sidebar Skip to footer

Compact (archive) Old Log Files In Python

I'm using standart logger library in Python. There are RotatingFileHandler, that can rotate log files dayily, for example. But it just renames them. Will be great, if it can not o

Solution 1:

I think your best option is to extend RotatingFileHandler something like this (not tested):

import os
from logging.handlers import RotatingFileHandler


COMPRESSION_SUPPORTED = {}

try:
   import gzip
   COMPRESSION_SUPPORTED['gz'] = gzip
except ImportError:
   passtry:
   import zipfile
   COMPRESSION_SUPPORTED['zip'] = zipfile
except ImportError:
   passclassNewRotatingFileHandler(RotatingFileHandler):

     def__init__(self, *args, **kws):
         compress_mode = kws.pop('compress_mode')

         try:
             self.compress_cls = COMPRESSION_SUPPORTED[compress_mode]
         except KeyError:
             raise ValueError('"%s" compression method not supported.' % compress_mode)

         super(NewRotatingFileHandler, self).__init__(self, *args, **kws)

     defdoRollover(self):
         super(NewRotatingFileHandler, self).doRollover()

         # Compress the old log.
         old_log = self.baseFilename + ".1"withopen(old_log) as log:
             with self.compress_cls.open(old_log + '.gz', 'wb') as comp_log:
                 comp_log.writelines(log)

         os.remove(old_log)

Solution 2:

The accepted answer will archive only 1 file-(basefile.log.1) .The other files are not archived. This code will archive all the log files other than the base file.

import os
import gzip
import logging.handlers

classNewRotatingFileHandler(logging.handlers.RotatingFileHandler):
    def__init__(self, filename, **kws):
        backupCount = kws.get('backupCount', 0)
        self.backup_count = backupCount
        logging.handlers.RotatingFileHandler.__init__(self, filename, **kws)

    defdoArchive(self, old_log):
        withopen(old_log) as log:
            with gzip.open(old_log + '.gz', 'wb') as comp_log:
                comp_log.writelines(log)
       os.remove(old_log)

   defdoRollover(self):
      if self.stream:
          self.stream.close()
          self.stream = Noneif self.backup_count > 0:
          for i inrange(self.backup_count - 1, 0, -1):
              sfn = "%s.%d.gz" % (self.baseFilename, i)
              dfn = "%s.%d.gz" % (self.baseFilename, i + 1)
              if os.path.exists(sfn):
                  if os.path.exists(dfn):
                      os.remove(dfn)
                  os.rename(sfn, dfn)
      dfn = self.baseFilename + ".1"if os.path.exists(dfn):
          os.remove(dfn)
      if os.path.exists(self.baseFilename):
          os.rename(self.baseFilename, dfn)
          self.doArchive(dfn)
      ifnot self.delay:
          self.stream = self._open()

Solution 3:

You can automatically write bz2 compressed log files by initializing the RotatingFileHandler with encoding='bz2-codec':

import logging
import logging.handlers as handlers

if __name__=='__main__':
    log_filename='log_rotate.bz2'
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    handler = handlers.RotatingFileHandler(
        log_filename, maxBytes=20, backupCount=5, encoding='bz2-codec')
    logger.addHandler(handler)
    for i inrange(20):
        logger.debug('i = %d' % i)

PS. Python3 removed 'bz2-codec' from the set of valid encodings, so this solution is specific to Python2.

Post a Comment for "Compact (archive) Old Log Files In Python"