345 def create(self):
346 """
347 Create the log viewer.
348 """
349 from ipywidgets import HTML, HBox, VBox
350
351 output = StringIO()
352 output.write("<style scoped>\n")
353 for level, color in self.log_color_codes.items():
354 level = level.lower()
355 output.write(f".log-line-{level} {{margin:0; padding:0; line-height:normal; color: {color} !important;}}\n")
356
357 output.write("""</style><div style="max-height: 400px; overflow-y: auto; width: 100%";>""")
358
359 for line in self.log_content.split("\n"):
360 if line.startswith('{"level"'):
361 try:
362 message = json.loads(line)
363
364
365
366
367 buf = StringIO()
368 self.format_logmessage(buf, message)
369 info = escape(buf.getvalue())
370
371 variables = message.get("variables", "")
372 if variables:
373 variables = "\n".join([""] + [f"\t{k} = {v}" for k, v in variables.items()])
374
375 level = message["level"].lower()
376 output.write(self.log_message.format(info=info, type_lower=level, var_output=variables, **message))
377 continue
378 except json.JSONDecodeError:
379
380 pass
381
382 output.write('<pre class="log-line-default">')
383 output.write(line)
384 output.write('</pre>')
385
386 output.write("</div>")
387
388 html = HTML()
389 html.value = output.getvalue()
390 html.width = "100%"
391 html.margin = "5px"
392
393 buttons = []
394 for type in self.log_levels:
395 buttons.append(HTML(self.toggle_button_line.format(type_lower=type.lower(), type_upper=type.upper())))
396
397 buttons_view = HBox(buttons)
398 buttons_view.margin = "10px 0px"
399 result_vbox = VBox((buttons_view, html))
400
401 return result_vbox