Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[sextante] Log file is now read backwards and limited to a fixed numb…
…er of lines
  • Loading branch information
volaya committed Feb 17, 2013
1 parent 1314d4c commit 329062b
Showing 1 changed file with 145 additions and 5 deletions.
150 changes: 145 additions & 5 deletions python/plugins/sextante/core/SextanteLog.py
Expand Up @@ -87,9 +87,13 @@ def getLogEntries():
warnings=[]
info=[]
#lines = codecs.open(SextanteLog.logFilename(), encoding='utf-8')
lines = open(SextanteLog.logFilename())
line = lines.readline()
while line != "":
#=======================================================================
# lines = open(SextanteLog.logFilename())
# line = lines.readline()
# while line != "":
#=======================================================================
lines = tail(SextanteLog.logFilename())
for line in lines:
line = line.strip("\n").strip()
tokens = line.split("|")
text=""
Expand All @@ -103,8 +107,8 @@ def getLogEntries():
warnings.append(LogEntry(tokens[1], text))
elif line.startswith(SextanteLog.LOG_INFO):
info.append(LogEntry(tokens[1], text))
line = lines.readline()
lines.close()
#line = lines.readline()
#lines.close()
entries[SextanteLog.LOG_ERROR] = errors
entries[SextanteLog.LOG_ALGORITHM] = algorithms
entries[SextanteLog.LOG_INFO] = info
Expand Down Expand Up @@ -133,3 +137,139 @@ class LogEntry():
def __init__(self, date, text):
self.date = date
self.text = text

import re
import time



#===============================================================================

#this code has been take from pytailer
# http://code.google.com/p/pytailer/

# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#===============================================================================

class Tailer(object):
"""\
Implements tailing and heading functionality like GNU tail and head
commands.
"""
line_terminators = ('\r\n', '\n', '\r')

def __init__(self, filename, read_size=1024, end=False):
self.read_size = read_size
self.file = open(filename)
self.start_pos = self.file.tell()
if end:
self.seek_end()

def splitlines(self, data):
return re.split('|'.join(self.line_terminators), data)

def seek_end(self):
self.seek(0, 2)

def seek(self, pos, whence=0):
self.file.seek(pos, whence)

def read(self, read_size=None):
if read_size:
read_str = self.file.read(read_size)
else:
read_str = self.file.read()

return len(read_str), read_str

def seek_line(self):
"""\
Searches backwards from the current file position for a line terminator
and seeks to the charachter after it.
"""
pos = end_pos = self.file.tell()

read_size = self.read_size
if pos > read_size:
pos -= read_size
else:
pos = 0
read_size = end_pos

self.seek(pos)

bytes_read, read_str = self.read(read_size)

if bytes_read and read_str[-1] in self.line_terminators:
# The last charachter is a line terminator, don't count this one
bytes_read -= 1

if read_str[-2:] == '\r\n' and '\r\n' in self.line_terminators:
# found crlf
bytes_read -= 1

while bytes_read > 0:
# Scan backward, counting the newlines in this bufferfull
i = bytes_read - 1
while i >= 0:
if read_str[i] in self.line_terminators:
self.seek(pos + i + 1)
return self.file.tell()
i -= 1

if pos == 0 or pos - self.read_size < 0:
# Not enought lines in the buffer, send the whole file
self.seek(0)
return None

pos -= self.read_size
self.seek(pos)

bytes_read, read_str = self.read(self.read_size)

return None

def tail(self, lines=10):
"""\
Return the last lines of the file.
"""
self.seek_end()
end_pos = self.file.tell()

for i in xrange(lines):
if not self.seek_line():
break

data = self.file.read(end_pos - self.file.tell() - 1)
if data:
return self.splitlines(data)
else:
return []



def __iter__(self):
return self.follow()

def close(self):
self.file.close()

def tail(file, lines=200):
return Tailer(file).tail(lines)




0 comments on commit 329062b

Please sign in to comment.