log_source.py
author Tero Marttila <terom@fixme.fi>
Sun, 08 Feb 2009 04:41:00 +0200
changeset 48 7858b7b8ffe3
parent 46 185504387370
child 50 f13cf27a360b
permissions -rw-r--r--
fix bugs with file tailing
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    A source of IRC log files
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
import codecs
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
from datetime import date, datetime, timedelta
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
import pytz
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
# for SEEK_*, errno
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
import os, errno
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
class LogSource (object) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
    """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
        A collection of IRC logs for a specific target in some format. Provides the possibility to read specific events
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
    """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
    
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
    def get_latest (self, count) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
            Yield the latest events, up to `count` of them.
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
        abstract
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
class LogFile (LogSource) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
        A file containing LogEvents
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
    def __init__ (self, path, charset='utf-8', sep='\n') :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
            Open the file at the given path, which contains data of the given codec, as lines separated by the given separator
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
        # store
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
        self.path = path
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
        self.charset = charset
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
        self.sep = sep
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
        # open
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    40
        self.file = open(path, 'rb')
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
    
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    def __iter__ (self) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
            Yields a series of lines, as read from the top of the file
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
        # seek to beginning
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
        self.file.seek(0)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
        # iterate over lines
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
        return iter(self.file)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    def get_latest (self, count) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
            Returns up to <count> lines from the end of the file, or less, if the file doesn't contain that many lines
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
        # the list of lines
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
        lines = []
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
        # seek to end of file
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
        self.file.seek(0, os.SEEK_END)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        # read offset
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    65
        # XXX: hack -1 to get rid of trailing newline
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    66
        size = offset = self.file.tell() - 1
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
        # use this blocksize
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
        BLOCKSIZE = 1024
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
        # trailing data
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
        buf = ''
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
        # read a block at a time, backwards
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    75
        while len(lines) < count and offset > 0:
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    76
            # calc new offset + size
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    77
            if offset > BLOCKSIZE :
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    78
                # full block
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    79
                offset -= BLOCKSIZE
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    80
                read_size = BLOCKSIZE
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    82
            else :
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    83
                # partial block
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    84
                read_size = offset
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
                offset = 0
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
43
fc11c4e86a82 implement channel_view count, the query stuff, css, layout all need some cleanup :(
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    87
            # seek to offset
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
            self.file.seek(offset)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    90
            # read the data we want
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    91
            read_buf = self.file.read(read_size)
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    92
            read_len = len(read_buf)
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    94
            # sanity check
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    95
            assert read_len == read_size
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
            # add in our previous buf
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
            buf = read_buf + buf
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
            
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
            # split out lines
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
            buf_lines = buf.split(self.sep)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
            # keep the first one as our buffer, as it's incomplete
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
            buf = buf_lines[0]
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   106
            # prepend up to count lines from the end to our lines buffer
43
fc11c4e86a82 implement channel_view count, the query stuff, css, layout all need some cleanup :(
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   107
            lines = buf_lines[-min(count, len(buf_lines) - 1):] + lines
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   108
        
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   109
        # decode
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   110
        # XXX: better queue implementation, plz
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   111
        lines = [line.decode(self.charset) for line in lines]
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
        # return the line list
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
        return lines
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
class LogDirectory (LogSource) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
        A directory containing a series of timestamped LogFiles
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
    """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    def __init__ (self, path, tz, charset='utf-8', filename_fmt='%Y-%m-%d') :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
            Load the logfiles at the given path.
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
            
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
            The files contain data in the given charset, and are named according the the date in the given timezone and
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
            date format.
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
        # store
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
        self.path = path
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
        self.tz = tz
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
        self.charset = charset
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
        self.filename_fmt = filename_fmt
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
    def _get_logfile_datetime (self, dt) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
            Get the logfile corresponding to the given datetime
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
        # convert to target timezone
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
        dtz = dt.astimezone(self.tz)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
        # convert to date and use that
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
        return self._get_logfile_date(dtz.date())
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
    def _get_logfile_date (self, d) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
            Get the logfile corresponding to the given naive date in our timezone
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
        # format filename
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
        filename = d.strftime(self.filename_fmt)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
        # build path
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
        path = os.path.join(self.path, filename)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
        # return the LogFile
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
        return LogFile(path, self.charset)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    def _iter_backwards (self, dt=None) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
            Yields an infinite series of naive date objects in our timezone, iterating backwards in time starting at the
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
            given *datetime*, or the the current date, if none given
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
        # default to now
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
        if not dt :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
            dt = datetime.now(pytz.utc)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
        # convert to target timezone
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        dtz = dt.astimezone(self.tz)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
        # our timedelta
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
        ONE_DAY = timedelta(1)
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        # iterate unto infinity
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        while True :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
            # yield
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
            yield dtz.date()
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
            
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
            # one day sdrawkcab
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
            dtz -= ONE_DAY
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
    def get_latest (self, count) :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
            Uses _iter_backwards + _get_logfile_date to read the yield the given lines from as many logfiles as needed
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
        """
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
        # iterate backwards from now
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        day_iter = self._iter_backwards()
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        # number of files read
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
        files = 0
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
        # only read up to 100 files or so
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
        MAX_FILES = 100
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   197
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   198
        # read the lines into here
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   199
        lines = []
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
        
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
        # loop until done
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   202
        while len(lines) < count :
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
            logfile = None
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
            try :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
                # get next logfile
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
                files += 1
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
                
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
                # open
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
                logfile = self._get_logfile_date(day_iter.next())
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
            
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
            except IOError, e :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
                # skip nonexistant days if we haven't found any logs yet
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
                if e.errno != errno.ENOENT :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
                    raise
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
                if files > MAX_FILES :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
                    raise Exception("No recent logfiles found")
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
                
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
                else :
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
                    # skip to next day
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
                    continue
48
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   223
            
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   224
            # read the lines
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   225
            lines = logfile.get_latest(count) + lines
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   226
        
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   227
        # return the lines
7858b7b8ffe3 fix bugs with file tailing
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
   228
        return lines
41
9585441a4bfb working basic logs stuff
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229