def logs(counter: str, status: bool, stderr: bool, stdout: bool, stream: bool, all: bool) -> None: """ Show or stream execution event log. """ project = get_project(require=True) assert project execution = project.get_execution_from_counter(counter=counter) accepted_streams = {v for v in [ 'status' if status else None, 'stderr' if stderr else None, 'stdout' if stdout else None, ] if v} lm = LogManager(execution) limit = (0 if all else None) while True: events_response = lm.fetch_events(limit=limit) events = events_response['events'] if not stream and events_response.get('truncated'): warn( 'There are {total} events, but only the last {n} are shown. Use `--all` to fetch everything.'.format( total=events_response['total'], n=len(events), ) ) for event in events: if event['stream'] not in accepted_streams: continue message = '{short_time} {text}'.format( short_time=(event['time'].split('T')[1][:-4]), text=clean_log_line(event['message']), ) style = stream_styles.get(event['stream'], {}) click.echo(click.style(message, **style)) # type: ignore[arg-type] if stream: lm.update_execution() if lm.execution['status'] in complete_execution_statuses: click.echo( 'The execution has finished (status {status}); stopping stream.'.format( status=execution['status'], ), err=True ) break # Fetch less on subsequent queries limit = 100 time.sleep(1) else: break
def draw(self) -> None: execution = self.log_manager.execution events = self.events l = Layout() l.add(self.get_header_flex(execution)) l.add(self.get_stat_flex(execution)) l.add(Divider('=')) available_height = l.height - len(l.rows) - 2 if available_height > 0: for event in events[-available_height:]: l.add( Flex(style=stream_styles.get(event['stream'])).add( event['time'].split('T')[1][:-4] + ' ', flex=0).add(clean_log_line(event['message']), flex=4)) click.clear() l.draw()
def test_clean_log_line(): assert clean_log_line( 'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m' ) == 'ls examplefile.zip'