Exemplo n.º 1
0
    def follow_log(self):
        """Reads a logfile continuously and updates internal graph if new step is found"""
        # Server needs to be up and running before starting sending POST requests
        time.sleep(5)
        try:
            if self.remote:
                logger.debug('Logfile in remote host!')
                cl = client.SSHClient()
                # Try to load system keys
                cl.load_system_host_keys()
                cl.connect(self.remote['host'], port=self.remote.get('port', 22), username=self.remote.get('username', None), \
                           password=self.remote.get('password', None))
                sftp = cl.open_sftp()
                f = sftp.open(self.logfile, 'r')
            else:
                f = open(self.logfile, 'r')
        except IOError:
            raise RuntimeError("Provided logfile does not exist or its not readable")
        self.analysis_finished = False
        last_line_read = False
        while not self.analysis_finished:
            line = f.readline()
            if not line:
                if not last_line_read:
                    self.update_frontend({'finished_reading': True})
                    if self.update:
                        self.update_frontend(self._last_message)
                last_line_read = True
                time.sleep(1)
                continue
            parsed_line = ps.parse_log_line(line)
            self._last_message = parsed_line
            self.analysis_finished = (parsed_line['step'] == 'finished') or (parsed_line['step'] == 'error')

            # If this is a new step, update internal data
            if parsed_line['step'] and not parsed_line['step'] == 'error':
                logger.debug('New step \"{}\" detected'.format(parsed_line['step']))
                self._steps.append(parsed_line)
                node_id = '_'.join(parsed_line['step'].lower().split())
                self.node(node_id, parsed_line['step'])
                self._nodes.append(node_id)
                n_nodes = len(self._nodes)
                if n_nodes > 1:
                    self.edge(self._nodes[n_nodes - 2], self._nodes[n_nodes -1])

            # Update frontend only if its a new step _or_ the update flag is set to true and we are
            # not loading the log for the first time
            if (last_line_read and self.update) or parsed_line['step']:
                self.update_frontend(parsed_line)
        f.close()
    def follow_log(self):
        """Reads a logfile continuously and updates internal graph if new step is found"""
        # Server needs to be up and running before starting sending POST requests
        time.sleep(5)
        try:
            if self.remote:
                logger.debug('Logfile in remote host!')
                cl = client.SSHClient()
                # Try to load system keys
                cl.load_system_host_keys()
                cl.connect(self.remote['host'], port=self.remote.get('port', 22), username=self.remote.get('username', None), \
                           password=self.remote.get('password', None))
                sftp = cl.open_sftp()
                f = sftp.open(self.logfile, 'r')
                f.settimeout(5) # Set 5 seconds timeout for read operations
            else:
                f = open(self.logfile, 'r')
        except IOError:
            raise RuntimeError("Provided logfile does not exist or its not readable")
        self.analysis_finished = False
        last_line_read = False
        while not self.analysis_finished:
            try:
                line = f.readline()
            except timeout:
                logger.error("Connection with the server lost, trying to reconnect and continue reading")
                current_pos = f.tell()
                try:
                    cl.connect(self.remote['host'], port=self.remote.get('port', 22), username=self.remote.get('username', None), \
                               password=self.remote.get('password', None), timeout=300, banner_timeout=300)
                except error:
                    logger.error("Couldn't connect to the server after 5 minutes, aborting.")
                    os._exit(0)
                else:
                    logger.info("Connection restablished!! Will continue reading the logfile")
                sftp = cl.open_sftp()
                f = sftp.open(self.logfile, 'r')
                f.seek(current_pos)
            else:
                if not line:
                    self.finished_reading = True
                    if not last_line_read:
                        self.update_frontend({'finished_reading': True})
                        if self.update:
                            self.update_frontend(self._last_message)
                    last_line_read = True
                    time.sleep(1)
                    continue
                parsed_line = ps.parse_log_line(line)
                self._last_message = parsed_line
                self.analysis_finished = parsed_line['step'] == 'finished'

                # If this is a new step, update internal data
                parsed_line['new_run'] = False
                if parsed_line['step'] and not parsed_line['step'] == 'error':
                    if self.FIRST_STEP is None:
                        self.FIRST_STEP = parsed_line['step']
                    elif parsed_line['step'] == self.FIRST_STEP:
                        parsed_line['new_run'] = True
                        self.new_run()
                    node_id = 'run-{}_'.format(self.current_run + 1) + '_'.join(parsed_line['step'].lower().split())
                    parsed_line['step_id'] = node_id
                    self.runs[self.current_run].steps.append(parsed_line)
                    self.runs[self.current_run].node(node_id, parsed_line['step'])
                    self.runs[self.current_run]._nodes.append(node_id)
                    n_nodes = len(self.runs[self.current_run]._nodes)
                    if n_nodes > 1:
                        self.runs[self.current_run].edge(self.runs[self.current_run]._nodes[n_nodes - 2], self.runs[self.current_run]._nodes[n_nodes -1])
                    parsed_line['graph_source'] = self.runs[self.current_run].source

                elif parsed_line['step'] == 'error':
                    self.runs[self.current_run].errored = True

                # Update frontend only if its a new step _or_ the update flag is set to true and we are
                # not loading the log for the first time
                if (last_line_read and self.update) or parsed_line['step']:
                    self.update_frontend(parsed_line)
        f.close()