1111import heapq
1212import itertools
1313import os
14+ import pathlib
1415import re
1516import sys
1617import tempfile
@@ -51,9 +52,23 @@ def main():
5152 if not args .testdir :
5253 print ("Opening latest test directory: {}" .format (testdir ), file = sys .stderr )
5354
55+ colors = defaultdict (lambda : '' )
56+ if args .color :
57+ colors ["test" ] = "\033 [0;36m" # CYAN
58+ colors ["node0" ] = "\033 [0;34m" # BLUE
59+ colors ["node1" ] = "\033 [0;32m" # GREEN
60+ colors ["node2" ] = "\033 [0;31m" # RED
61+ colors ["node3" ] = "\033 [0;33m" # YELLOW
62+ colors ["reset" ] = "\033 [0m" # Reset font color
63+
5464 log_events = read_logs (testdir )
5565
56- print_logs (log_events , color = args .color , html = args .html )
66+ if args .html :
67+ print_logs_html (log_events )
68+ else :
69+ print_logs_plain (log_events , colors )
70+ print_node_warnings (testdir , colors )
71+
5772
5873def read_logs (tmp_dir ):
5974 """Reads log files.
@@ -71,6 +86,26 @@ def read_logs(tmp_dir):
7186 return heapq .merge (* [get_log_events (source , f ) for source , f in files ])
7287
7388
89+ def print_node_warnings (tmp_dir , colors ):
90+ """Print nodes' errors and warnings"""
91+
92+ warnings = []
93+ for stream in ['stdout' , 'stderr' ]:
94+ for i in itertools .count ():
95+ folder = "{}/node{}/{}" .format (tmp_dir , i , stream )
96+ if not os .path .isdir (folder ):
97+ break
98+ for (_ , _ , fns ) in os .walk (folder ):
99+ for fn in fns :
100+ warning = pathlib .Path ('{}/{}' .format (folder , fn )).read_text ().strip ()
101+ if warning :
102+ warnings .append (("node{} {}" .format (i , stream ), warning ))
103+
104+ print ()
105+ for w in warnings :
106+ print ("{} {} {} {}" .format (colors [w [0 ].split ()[0 ]], w [0 ], w [1 ], colors ["reset" ]))
107+
108+
74109def find_latest_test_dir ():
75110 """Returns the latest tmpfile test directory prefix."""
76111 tmpdir = tempfile .gettempdir ()
@@ -127,26 +162,19 @@ def get_log_events(source, logfile):
127162 except FileNotFoundError :
128163 print ("File %s could not be opened. Continuing without it." % logfile , file = sys .stderr )
129164
130- def print_logs (log_events , color = False , html = False ):
131- """Renders the iterator of log events into text or html."""
132- if not html :
133- colors = defaultdict (lambda : '' )
134- if color :
135- colors ["test" ] = "\033 [0;36m" # CYAN
136- colors ["node0" ] = "\033 [0;34m" # BLUE
137- colors ["node1" ] = "\033 [0;32m" # GREEN
138- colors ["node2" ] = "\033 [0;31m" # RED
139- colors ["node3" ] = "\033 [0;33m" # YELLOW
140- colors ["reset" ] = "\033 [0m" # Reset font color
141165
166+ def print_logs_plain (log_events , colors ):
167+ """Renders the iterator of log events into text."""
142168 for event in log_events :
143169 lines = event .event .splitlines ()
144170 print ("{0} {1: <5} {2} {3}" .format (colors [event .source .rstrip ()], event .source , lines [0 ], colors ["reset" ]))
145171 if len (lines ) > 1 :
146172 for line in lines [1 :]:
147173 print ("{0}{1}{2}" .format (colors [event .source .rstrip ()], line , colors ["reset" ]))
148174
149- else :
175+
176+ def print_logs_html (log_events ):
177+ """Renders the iterator of log events into html."""
150178 try :
151179 import jinja2
152180 except ImportError :
0 commit comments