diff --git a/distributed/dashboard/components/scheduler.py b/distributed/dashboard/components/scheduler.py index b00bcfb94b0..9311f187e6a 100644 --- a/distributed/dashboard/components/scheduler.py +++ b/distributed/dashboard/components/scheduler.py @@ -70,7 +70,7 @@ from distributed.diagnostics.task_stream import color_of as ts_color_of from distributed.diagnostics.task_stream import colors as ts_color_lookup from distributed.metrics import time -from distributed.utils import Logs, format_time, log_errors, parse_timedelta +from distributed.utils import Log, format_time, log_errors, parse_timedelta if dask.config.get("distributed.dashboard.export-tool"): from distributed.dashboard.export_tool import ExportTool @@ -2165,7 +2165,9 @@ def update(self): class SchedulerLogs: def __init__(self, scheduler): - logs = Logs(scheduler.get_logs())._repr_html_() + logs = Log( + "\n".join(line for level, line in scheduler.get_logs()) + )._repr_html_() self.root = Div(text=logs) diff --git a/distributed/deploy/cluster.py b/distributed/deploy/cluster.py index aaa05cf5617..b00886ac963 100644 --- a/distributed/deploy/cluster.py +++ b/distributed/deploy/cluster.py @@ -14,7 +14,8 @@ from ..core import Status from ..objects import SchedulerInfo from ..utils import ( - MultiLogs, + Log, + Logs, format_dashboard_link, log_errors, parse_timedelta, @@ -208,19 +209,21 @@ def _log(self, log): print(log) async def _get_logs(self, cluster=True, scheduler=True, workers=True): - logs = MultiLogs() + logs = Logs() if cluster: - logs["Cluster"] = self._cluster_manager_logs + logs["Cluster"] = Log( + "\n".join(line[1] for line in self._cluster_manager_logs) + ) if scheduler: L = await self.scheduler_comm.get_logs() - logs["Scheduler"] = L + logs["Scheduler"] = Log("\n".join(line for level, line in L)) if workers: d = await self.scheduler_comm.worker_logs(workers=workers) for k, v in d.items(): - logs[k] = v + logs[k] = Log("\n".join(line for level, line in v)) return logs diff --git a/distributed/deploy/tests/test_spec_cluster.py b/distributed/deploy/tests/test_spec_cluster.py index ca96104de3b..dff5d06831b 100644 --- a/distributed/deploy/tests/test_spec_cluster.py +++ b/distributed/deploy/tests/test_spec_cluster.py @@ -287,6 +287,8 @@ async def test_logs(cleanup): await cluster logs = await cluster.get_logs() + assert isinstance(logs, dict) + assert all(isinstance(log, str) for log in logs) assert is_valid_xml("
{message}
'.format( - style=html.escape(style), - message=html.escape(message), - ) - - -class Logs(list): - """A container for a list of log entries""" + logs_html = [] + for message in self.split("\n"): + style = "font-family: monospace; margin: 0;" + for level in self.level_styles: + if level in message: + style += self.level_styles[level] + break + + logs_html.append( + '{message}
'.format( + style=html.escape(style), + message=html.escape(message), + ) + ) - def _repr_html_(self): - return "\n".join(Log(entry)._repr_html_() for entry in self) + return "\n".join(logs_html) -class MultiLogs(dict): - """A container for a dict mapping strings to lists of log entries""" +class Logs(dict): + """A container for a dict mapping names to strings of log entries""" def _repr_html_(self): summaries = [ "