log_source.py
changeset 111 95c0c49d76aa
parent 106 0690d715385d
child 112 090192b64d7e
equal deleted inserted replaced
110:37e67ec434f3 111:95c0c49d76aa
     5 import datetime, calendar, itertools, functools, math
     5 import datetime, calendar, itertools, functools, math
     6 import os, os.path, errno
     6 import os, os.path, errno
     7 import pytz
     7 import pytz
     8 
     8 
     9 import config, utils
     9 import config, utils
       
    10 
       
    11 # a timedelta that represents one day
       
    12 ONE_DAY = datetime.timedelta(days=1)
    10 
    13 
    11 class LogSourceDecoder (object) :
    14 class LogSourceDecoder (object) :
    12     """
    15     """
    13         Handles decoding of LogSource lines
    16         Handles decoding of LogSource lines
    14     """
    17     """
   155         # return
   158         # return
   156         return (page, max_pages, lines)
   159         return (page, max_pages, lines)
   157 
   160 
   158     def get_month_days (self, dt) :
   161     def get_month_days (self, dt) :
   159         """
   162         """
   160             Return a sequence of dates, telling which days in the given month (as a datetime) have logs available
   163             Return an ordered sequence of dates, telling which days in the given month (as a datetime) have logs available.
   161         """
   164         """
   162 
   165 
   163         abstract
   166         abstract
   164     
   167     
   165     def get_modified (self, dt=None, after=None, until=None) :
   168     def get_modified (self, dt=None, after=None, until=None) :
   172             If until is given, only lines up to and including said date will be returned, regardless of modification.
   175             If until is given, only lines up to and including said date will be returned, regardless of modification.
   173 
   176 
   174             The LogLines should be in time order.
   177             The LogLines should be in time order.
   175         """
   178         """
   176 
   179 
       
   180         abstract
       
   181     
       
   182     def get_prev_date (self, dt) :
       
   183         """
       
   184             Get the next distinct date of logs available preceeding the given date, or None
       
   185         """
       
   186 
       
   187         abstract
       
   188 
       
   189     def get_next_date (self, dt) :
       
   190         """
       
   191             Get the next distinct date of logs following the given date, or None.
       
   192         """
       
   193         
   177         abstract
   194         abstract
   178 
   195 
   179 class LogFile (object) :
   196 class LogFile (object) :
   180     """
   197     """
   181         A file containing LogEvents
   198         A file containing LogEvents
   414                 return None
   431                 return None
   415 
   432 
   416             else :
   433             else :
   417                 raise
   434                 raise
   418     
   435     
   419     def _iter_logfile_dates (self, after=None, until=None) :
   436     def _iter_logfile_dates (self, after=None, until=None, reverse=False) :
   420         """
   437         """
   421             Yields a series of naive datetime objects representing the logfiles that are available, in time order.
   438             Yields a series of naive datetime objects representing the logfiles that are available, in time order.
   422 
   439             
   423             If after is given, only dates from said date onwards will be returned
   440             Parameters :
   424             If until is given, only dates up to and including said date will be returned
   441                 after   only dates from said date onwards will be returned
       
   442                 until   only dates up to and including said date will be returned
       
   443                 reverse the dates are returned in reverse order instead. Note that the meaning of after/until doesn't change
   425         """
   444         """
   426 
   445 
   427         # listdir
   446         # listdir
   428         filenames = os.listdir(self.path)
   447         filenames = os.listdir(self.path)
   429 
   448 
   430         # sort
   449         # sort
   431         filenames.sort()
   450         filenames.sort(reverse=reverse)
   432 
       
   433         
       
   434 
   451 
   435         # iter files
   452         # iter files
   436         for filename in filenames :
   453         for filename in filenames :
   437             try :
   454             try :
   438                 # parse date
   455                 # parse date
   441             except :
   458             except :
   442                 # ignore
   459                 # ignore
   443                 continue
   460                 continue
   444 
   461 
   445             else :
   462             else :
   446                 if (not after or date >= after) and (not until or date <= until) :
   463                 if (after and date < after) or (until and date > until) :
       
   464                     # ignore
       
   465                     continue
       
   466                 
       
   467                 else :
       
   468 #                    print
       
   469 #                    print "iter_logfile_dates: after=%s, until=%s, reverse=%s -> %s" % (after, until, reverse, date)
       
   470 
   447                     # yield
   471                     # yield
   448                     yield date
   472                     yield date
   449                 
       
   450                 else :
       
   451                     # ignore
       
   452                     continue
       
   453             
   473             
   454     def _iter_date_reverse (self, dt=None) :
   474     def _iter_date_reverse (self, dt=None) :
   455         """
   475         """
   456             Yields an infinite series of naive date objects in our timezone, iterating backwards in time starting at the
   476             Yields an infinite series of naive date objects in our timezone, iterating backwards in time starting at the
   457             given *datetime*, or the the current date, if none given
   477             given *datetime*, or the the current date, if none given
   463 
   483 
   464         else :
   484         else :
   465             # convert to target timezone
   485             # convert to target timezone
   466             dtz = dt.astimezone(self.tz)
   486             dtz = dt.astimezone(self.tz)
   467 
   487 
   468         # our timedelta
       
   469         ONE_DAY = datetime.timedelta(1)
       
   470         
       
   471         # iterate unto infinity
   488         # iterate unto infinity
   472         while True :
   489         while True :
   473             # yield
   490             # yield
   474             yield dtz.date()
   491             yield dtz.date()
   475             
   492             
   524             # yield it
   541             # yield it
   525             yield logfile
   542             yield logfile
   526 
   543 
   527     def get_latest (self, count) :
   544     def get_latest (self, count) :
   528         """
   545         """
   529             Uses _iter_backwards + _get_logfile_date to read the yield the given lines from as many logfiles as needed
   546             Uses _logfile_reverse to read the yield the given lines from as many logfiles as needed
   530         """
   547         """
   531 
   548 
   532         # read the events into here
   549         # read the events into here
   533         lines = []
   550         lines = []
   534         
   551         
   643 
   660 
   644             # yield all lines
   661             # yield all lines
   645             for line in logfile.read_full() :
   662             for line in logfile.read_full() :
   646                 yield line
   663                 yield line
   647 
   664 
       
   665     def get_prev_date (self, dt) :
       
   666         """
       
   667             Just use _iter_logfile_dates
       
   668         """
       
   669         
       
   670         # use for to "iter" once
       
   671         for log_date in self._iter_logfile_dates(until=dt - ONE_DAY, reverse=True) :
       
   672             return log_date
       
   673         
       
   674         else :
       
   675             return None
       
   676 
       
   677     def get_next_date (self, dt) :
       
   678         """
       
   679             Just use _iter_logfile_dates
       
   680         """
       
   681         
       
   682         # use for to "iter" once
       
   683         for log_date in self._iter_logfile_dates(after=dt + ONE_DAY) :
       
   684             return log_date
       
   685         
       
   686         else :
       
   687             return None
       
   688