class FileFollower(): ''' Use pygtail to keep track of EOF and rotated files, catch exceptions to make things more seamless ''' def __init__(self, path): self.path = path self.pygtail = None self.last_inode = 0 def next(self): line = '' curr_inode = 0 if self.pygtail is None: try: # remove last offset file if the log file is different # PygTail's inode detection doesn't work in certain cases curr_inode = os.stat(self.path).st_ino if self.last_inode != curr_inode: os.unlink(self.path + '.offset') self.last_inode = curr_inode log.debug('deleted offset file, inode difference') except Exception as e: log.info('inode checking failed (not terminal): %s' % e) self.pygtail = Pygtail(self.path) try: line = self.pygtail.next() except StopIteration as si: # Need to get a new instance of pygtail after this incase the inode # has changed self.pygtail = None return False return line
def _tail_lines(self, filepath): tail = Pygtail(str(filepath)) while True: try: self._tail_worker_enabled.wait() if self._tail_worker_kill.is_set(): return line = tail.next() GLib.idle_add(self._add_line_to_log_buffer, line) except StopIteration: time.sleep(0.5)
class LogConsumer: def __init__(self, file: str, logkeep: Type[LogKeep]): self.pygtail = Pygtail(file, paranoid=True) self.logkeep = logkeep def consume_next_lines(self): while True: try: line = self.pygtail.next() if line: self.logkeep.add_logline(LogLine.from_line(line)) except StopIteration: break
if not os.path.exists(".offset"): os.makedirs(".offset") try: if is_erased(file_name): # forget about saved offset # delete offset file # print "remove file" # test point os.remove(OFFSET_FILE) except IOError: # Error occur when first time run pass try: pyg = Pygtail(file_name, OFFSET_FILE) first_line = pyg.next() # get log format and log type log_type, log_format = parser.detect_log_type(first_line) for line in Pygtail(file_name, OFFSET_FILE): # print line # test point error_info = parser.parse_log(line, log_type, log_format) status_code = error_info['status_code'] if status_code == 502 or status_code == 503: client.capture( "raven.events.Message", message=log_type + " " + str(status_code), extra=error_info, date=error_info['time'] )