###############################################################################
# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
from collections import Counter
from io import StringIO
import click
import consolemd
from LbAPCommon.validators import explain_log
from LbAPCommon.validators.logs import _split_by_level
[docs]def show_log_advice(log_text, suppress=5):
log_messages = _split_by_level(log_text)
_show_message_summary(log_messages, "FATAL", fg="red", bold=True)
_show_message_summary(log_messages, "ERROR", fg="red")
_show_message_summary(log_messages, "WARNING", min_count=5, fg="yellow")
click.echo()
explanations, suggestions, errors = explain_log(log_text)
if errors:
click.secho("Errors have been detected!", fg="red", bold=True)
_show_advice(errors)
if suggestions:
click.secho("Advice about warnings and errors:", fg="yellow")
_show_advice(suggestions)
if explanations:
click.secho("General explanations", fg="green")
_show_advice(explanations)
if log_messages["FATAL"] or errors:
raise click.ClickException("Found issues in log")
def _show_message_summary(log_messages, level, *, min_count=0, **formatting):
total_count = len(log_messages[level])
if not total_count:
return
messages = sorted(
Counter(message for line_no, _, _, _, message in log_messages[level]).items(),
key=lambda x: x[1],
reverse=True,
)
click.secho(f" Found {total_count} {level} message(s)", **formatting)
n_supressed = 0
n_supressed_unique = 0
for message, count in messages:
if count >= min_count:
click.echo(f' * {count} instances of "{message}"')
else:
n_supressed_unique += 1
n_supressed += count
if n_supressed:
click.echo(
f" and {n_supressed} other(s) ({n_supressed_unique} unique). "
'Pass "--suppress=0" to show all messages'
)
def _show_advice(advice):
for message, lines in advice:
if lines is None:
heading = " * No line information available"
else:
heading = " * Line" + ("s" if len(lines) > 1 else "") + ":"
heading += f" {', '.join(map(str, lines[:5]))}"
if len(lines) > 5:
heading += f" and {len(lines) - 5} other(s)"
click.secho(heading, fg="cyan")
rendered_message = StringIO()
consolemd.Renderer().render(message, output=rendered_message)
click.echo(" " + rendered_message.getvalue().replace("\n", "\n "))