Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes
logging.handlers.TimedRotatingFileHandler Class Reference
Inheritance diagram for logging.handlers.TimedRotatingFileHandler:
Inheritance graph
[legend]
Collaboration diagram for logging.handlers.TimedRotatingFileHandler:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def computeRollover
def shouldRollover
def getFilesToDelete
def doRollover
def emit

Public Attributes

 when
 backupCount
 utc
 interval
 suffix
 extMatch
 dayOfWeek
 rolloverAt
 stream
 mode
 encoding

Detailed Description

Handler for logging to a file, rotating the log file at certain timed
intervals.

If backupCount is > 0, when rollover is done, no more than backupCount
files are kept - the oldest ones are deleted.

Definition at line 160 of file handlers.py.


Constructor & Destructor Documentation

def logging.handlers.TimedRotatingFileHandler.__init__ (   self,
  filename,
  when = 'h',
  interval = 1,
  backupCount = 0,
  encoding = None,
  delay = False,
  utc = False 
)

Definition at line 168 of file handlers.py.

00168 
00169     def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False):
00170         BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay)
00171         self.when = when.upper()
00172         self.backupCount = backupCount
00173         self.utc = utc
00174         # Calculate the real rollover interval, which is just the number of
00175         # seconds between rollovers.  Also set the filename suffix used when
00176         # a rollover occurs.  Current 'when' events supported:
00177         # S - Seconds
00178         # M - Minutes
00179         # H - Hours
00180         # D - Days
00181         # midnight - roll over at midnight
00182         # W{0-6} - roll over on a certain day; 0 - Monday
00183         #
00184         # Case of the 'when' specifier is not important; lower or upper case
00185         # will work.
00186         if self.when == 'S':
00187             self.interval = 1 # one second
00188             self.suffix = "%Y-%m-%d_%H-%M-%S"
00189             self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}$"
00190         elif self.when == 'M':
00191             self.interval = 60 # one minute
00192             self.suffix = "%Y-%m-%d_%H-%M"
00193             self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$"
00194         elif self.when == 'H':
00195             self.interval = 60 * 60 # one hour
00196             self.suffix = "%Y-%m-%d_%H"
00197             self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}$"
00198         elif self.when == 'D' or self.when == 'MIDNIGHT':
00199             self.interval = 60 * 60 * 24 # one day
00200             self.suffix = "%Y-%m-%d"
00201             self.extMatch = r"^\d{4}-\d{2}-\d{2}$"
00202         elif self.when.startswith('W'):
00203             self.interval = 60 * 60 * 24 * 7 # one week
00204             if len(self.when) != 2:
00205                 raise ValueError("You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % self.when)
00206             if self.when[1] < '0' or self.when[1] > '6':
00207                 raise ValueError("Invalid day specified for weekly rollover: %s" % self.when)
00208             self.dayOfWeek = int(self.when[1])
00209             self.suffix = "%Y-%m-%d"
00210             self.extMatch = r"^\d{4}-\d{2}-\d{2}$"
00211         else:
00212             raise ValueError("Invalid rollover interval specified: %s" % self.when)
00213 
00214         self.extMatch = re.compile(self.extMatch, re.ASCII)
00215         self.interval = self.interval * interval # multiply by units requested
00216         if os.path.exists(filename):
00217             t = os.stat(filename)[ST_MTIME]
00218         else:
00219             t = int(time.time())
00220         self.rolloverAt = self.computeRollover(t)

Here is the caller graph for this function:


Member Function Documentation

Work out the rollover time based on the specified time.

Definition at line 221 of file handlers.py.

00221 
00222     def computeRollover(self, currentTime):
00223         """
00224         Work out the rollover time based on the specified time.
00225         """
00226         result = currentTime + self.interval
00227         # If we are rolling over at midnight or weekly, then the interval is already known.
00228         # What we need to figure out is WHEN the next interval is.  In other words,
00229         # if you are rolling over at midnight, then your base interval is 1 day,
00230         # but you want to start that one day clock at midnight, not now.  So, we
00231         # have to fudge the rolloverAt value in order to trigger the first rollover
00232         # at the right time.  After that, the regular interval will take care of
00233         # the rest.  Note that this code doesn't care about leap seconds. :)
00234         if self.when == 'MIDNIGHT' or self.when.startswith('W'):
00235             # This could be done with less code, but I wanted it to be clear
00236             if self.utc:
00237                 t = time.gmtime(currentTime)
00238             else:
00239                 t = time.localtime(currentTime)
00240             currentHour = t[3]
00241             currentMinute = t[4]
00242             currentSecond = t[5]
00243             # r is the number of seconds left between now and midnight
00244             r = _MIDNIGHT - ((currentHour * 60 + currentMinute) * 60 +
00245                     currentSecond)
00246             result = currentTime + r
00247             # If we are rolling over on a certain day, add in the number of days until
00248             # the next rollover, but offset by 1 since we just calculated the time
00249             # until the next day starts.  There are three cases:
00250             # Case 1) The day to rollover is today; in this case, do nothing
00251             # Case 2) The day to rollover is further in the interval (i.e., today is
00252             #         day 2 (Wednesday) and rollover is on day 6 (Sunday).  Days to
00253             #         next rollover is simply 6 - 2 - 1, or 3.
00254             # Case 3) The day to rollover is behind us in the interval (i.e., today
00255             #         is day 5 (Saturday) and rollover is on day 3 (Thursday).
00256             #         Days to rollover is 6 - 5 + 3, or 4.  In this case, it's the
00257             #         number of days left in the current week (1) plus the number
00258             #         of days in the next week until the rollover day (3).
00259             # The calculations described in 2) and 3) above need to have a day added.
00260             # This is because the above time calculation takes us to midnight on this
00261             # day, i.e. the start of the next day.
00262             if self.when.startswith('W'):
00263                 day = t[6] # 0 is Monday
00264                 if day != self.dayOfWeek:
00265                     if day < self.dayOfWeek:
00266                         daysToWait = self.dayOfWeek - day
00267                     else:
00268                         daysToWait = 6 - day + self.dayOfWeek + 1
00269                     newRolloverAt = result + (daysToWait * (60 * 60 * 24))
00270                     if not self.utc:
00271                         dstNow = t[-1]
00272                         dstAtRollover = time.localtime(newRolloverAt)[-1]
00273                         if dstNow != dstAtRollover:
00274                             if not dstNow:  # DST kicks in before next rollover, so we need to deduct an hour
00275                                 newRolloverAt = newRolloverAt - 3600
00276                             else:           # DST bows out before next rollover, so we need to add an hour
00277                                 newRolloverAt = newRolloverAt + 3600
00278                     result = newRolloverAt
00279         return result

do a rollover; in this case, a date/time stamp is appended to the filename
when the rollover happens.  However, you want the file to be named for the
start of the interval, not the current time.  If there is a backup count,
then we have to get a list of matching filenames, sort them and remove
the one with the oldest suffix.

Definition at line 315 of file handlers.py.

00315 
00316     def doRollover(self):
00317         """
00318         do a rollover; in this case, a date/time stamp is appended to the filename
00319         when the rollover happens.  However, you want the file to be named for the
00320         start of the interval, not the current time.  If there is a backup count,
00321         then we have to get a list of matching filenames, sort them and remove
00322         the one with the oldest suffix.
00323         """
00324         if self.stream:
00325             self.stream.close()
00326             self.stream = None
00327         # get the time that this sequence started at and make it a TimeTuple
00328         t = self.rolloverAt - self.interval
00329         if self.utc:
00330             timeTuple = time.gmtime(t)
00331         else:
00332             timeTuple = time.localtime(t)
00333         dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)
00334         if os.path.exists(dfn):
00335             os.remove(dfn)
00336         os.rename(self.baseFilename, dfn)
00337         if self.backupCount > 0:
00338             for s in self.getFilesToDelete():
00339                 os.remove(s)
00340         self.mode = 'w'
00341         self.stream = self._open()
00342         currentTime = int(time.time())
00343         newRolloverAt = self.computeRollover(currentTime)
00344         while newRolloverAt <= currentTime:
00345             newRolloverAt = newRolloverAt + self.interval
00346         #If DST changes and midnight or weekly rollover, adjust for this.
00347         if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
00348             dstNow = time.localtime(currentTime)[-1]
00349             dstAtRollover = time.localtime(newRolloverAt)[-1]
00350             if dstNow != dstAtRollover:
00351                 if not dstNow:  # DST kicks in before next rollover, so we need to deduct an hour
00352                     newRolloverAt = newRolloverAt - 3600
00353                 else:           # DST bows out before next rollover, so we need to add an hour
00354                     newRolloverAt = newRolloverAt + 3600
00355         self.rolloverAt = newRolloverAt

Here is the caller graph for this function:

def logging.handlers.BaseRotatingHandler.emit (   self,
  record 
) [inherited]
Emit a record.

Output the record to the file, catering for rollover as described
in doRollover().

Definition at line 69 of file handlers.py.

00069 
00070     def emit(self, record):
00071         """
00072         Emit a record.
00073 
00074         Output the record to the file, catering for rollover as described
00075         in doRollover().
00076         """
00077         try:
00078             if self.shouldRollover(record):
00079                 self.doRollover()
00080             logging.FileHandler.emit(self, record)
00081         except (KeyboardInterrupt, SystemExit):
00082             raise
00083         except:
00084             self.handleError(record)

Here is the call graph for this function:

Determine the files to delete when rolling over.

More specific than the earlier method, which just used glob.glob().

Definition at line 292 of file handlers.py.

00292 
00293     def getFilesToDelete(self):
00294         """
00295         Determine the files to delete when rolling over.
00296 
00297         More specific than the earlier method, which just used glob.glob().
00298         """
00299         dirName, baseName = os.path.split(self.baseFilename)
00300         fileNames = os.listdir(dirName)
00301         result = []
00302         prefix = baseName + "."
00303         plen = len(prefix)
00304         for fileName in fileNames:
00305             if fileName[:plen] == prefix:
00306                 suffix = fileName[plen:]
00307                 if self.extMatch.match(suffix):
00308                     result.append(os.path.join(dirName, fileName))
00309         result.sort()
00310         if len(result) < self.backupCount:
00311             result = []
00312         else:
00313             result = result[:len(result) - self.backupCount]
00314         return result

Determine if rollover should occur.

record is not used, as we are just comparing times, but it is needed so
the method signatures are the same

Definition at line 280 of file handlers.py.

00280 
00281     def shouldRollover(self, record):
00282         """
00283         Determine if rollover should occur.
00284 
00285         record is not used, as we are just comparing times, but it is needed so
00286         the method signatures are the same
00287         """
00288         t = int(time.time())
00289         if t >= self.rolloverAt:
00290             return 1
00291         return 0

Here is the caller graph for this function:


Member Data Documentation

Definition at line 171 of file handlers.py.

Definition at line 207 of file handlers.py.

Definition at line 67 of file handlers.py.

Definition at line 188 of file handlers.py.

Definition at line 186 of file handlers.py.

Reimplemented from logging.handlers.BaseRotatingHandler.

Definition at line 339 of file handlers.py.

Definition at line 219 of file handlers.py.

Definition at line 325 of file handlers.py.

Definition at line 187 of file handlers.py.

Definition at line 172 of file handlers.py.

Definition at line 170 of file handlers.py.


The documentation for this class was generated from the following file: