Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion cmk/gui/crash_reporting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@
from .views import (
CommandDeleteCrashReports,
DataSourceCrashReports,
PainterCrashCheckName,
PainterCrashException,
PainterCrashHost,
PainterCrashIdent,
PainterCrashItem,
PainterCrashServiceDescription,
PainterCrashSource,
PainterCrashTime,
PainterCrashType,
PainterCrashVersion,
SorterCrashCheckName,
SorterCrashHost,
SorterCrashItem,
SorterCrashServiceDescription,
SorterCrashTime,
)

Expand All @@ -36,13 +44,21 @@ def register(
) -> None:
crash_reporting_pages.register(page_registry)
data_source_registry.register(DataSourceCrashReports)
sorter_registry.register(SorterCrashCheckName)
sorter_registry.register(SorterCrashHost)
sorter_registry.register(SorterCrashItem)
sorter_registry.register(SorterCrashServiceDescription)
sorter_registry.register(SorterCrashTime)
command_registry.register(CommandDeleteCrashReports)
painter_registry.register(PainterCrashCheckName)
painter_registry.register(PainterCrashException)
painter_registry.register(PainterCrashHost)
painter_registry.register(PainterCrashIdent)
painter_registry.register(PainterCrashItem)
painter_registry.register(PainterCrashServiceDescription)
painter_registry.register(PainterCrashSource)
painter_registry.register(PainterCrashTime)
painter_registry.register(PainterCrashType)
painter_registry.register(PainterCrashSource)
painter_registry.register(PainterCrashVersion)
config_variable_registry.register(ConfigVariableCrashReportTarget)
config_variable_registry.register(ConfigVariableCrashReportURL)
203 changes: 202 additions & 1 deletion cmk/gui/crash_reporting/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
CommandGroupVarious,
PERMISSION_SECTION_ACTION,
)
from cmk.gui.views.sorter import cmp_simple_number, Sorter
from cmk.gui.views.sorter import cmp_simple_number, cmp_simple_string, Sorter
from cmk.gui.visuals.filter import Filter

from .helpers import local_files_involved_in_crash
Expand Down Expand Up @@ -107,6 +107,30 @@ def parse_rows(self, rows: Iterable[Row]) -> Iterable[Row]:
"crash_exc_type": crash_info_raw["exc_type"],
"crash_exc_value": crash_info_raw["exc_value"],
"crash_exc_traceback": crash_info_raw["exc_traceback"],
**(
{"crash_host": crash_info_raw["details"]["host"]}
if isinstance(crash_info_raw.get("details"), dict)
and crash_info_raw["details"].get("host")
else {}
),
**(
{"crash_item": crash_info_raw["details"]["item"]}
if isinstance(crash_info_raw.get("details"), dict)
and crash_info_raw["details"].get("item")
else {}
),
**(
{"crash_check_type": crash_info_raw["details"]["check_type"]}
if isinstance(crash_info_raw.get("details"), dict)
and crash_info_raw["details"].get("check_type")
else {}
),
**(
{"crash_service_description": crash_info_raw["details"]["description"]}
if isinstance(crash_info_raw.get("details"), dict)
and crash_info_raw["details"].get("description")
else {}
),
}

def get_crash_report_rows(
Expand Down Expand Up @@ -384,3 +408,180 @@ def command_delete_crash_report_action(
action=command_delete_crash_report_action,
affected_output_cb=command_delete_crash_report_affected,
)


class PainterCrashHost(Painter):
@property
def ident(self) -> str:
return "crash_host"

def title(self, cell):
return _("Crash Host")

def short_title(self, cell):
return _("Host")

@property
def columns(self) -> Sequence[ColumnName]:
return ["crash_host"]

def render(self, row: Row, cell: Cell, user: LoggedInUser) -> CellSpec:
if not row.get("crash_host"):
return None, ""

url = makeuri_contextless(
self.request,
[
("host", row["crash_host"]),
("site", row["site"]),
("view_name", "host"),
],
filename="view.py",
)
return None, HTMLWriter.render_a(row["crash_host"], href=url)


class PainterCrashItem(Painter):
@property
def ident(self) -> str:
return "crash_item"

def title(self, cell):
return _("Crash Service Item")

def short_title(self, cell):
return _("Item")

@property
def columns(self) -> Sequence[ColumnName]:
return ["crash_item"]

def render(self, row: Row, cell: Cell, user: LoggedInUser) -> CellSpec:
return None, row.get("crash_item", "")


class PainterCrashCheckName(Painter):
@property
def ident(self) -> str:
return "crash_check_type"

def title(self, cell):
return _("Crash Check Name")

def short_title(self, cell):
return _("Check")

@property
def columns(self) -> Sequence[ColumnName]:
return ["crash_check_type"]

def render(self, row: Row, cell: Cell, user: LoggedInUser) -> CellSpec:
return None, row.get("crash_check_type", "")


class PainterCrashServiceDescription(Painter):
@property
def ident(self) -> str:
return "crash_service_description"

def title(self, cell):
return _("Crash Service Description")

def short_title(self, cell):
return _("Service")

@property
def columns(self) -> Sequence[ColumnName]:
return ["crash_service_description"]

def render(self, row: Row, cell: Cell, user: LoggedInUser) -> CellSpec:
if not row.get("crash_service_description"):
return None, ""

url = makeuri_contextless(
self.request,
[
("host", row["crash_host"]),
("site", row["site"]),
("view_name", "service"),
("service", row["crash_service_description"]),
],
filename="view.py",
)
return None, HTMLWriter.render_a(row["crash_service_description"], href=url)


def _sort_crash_host(
r1: Row,
r2: Row,
*,
parameters: Mapping[str, Any] | None,
config: Config,
request: Request,
) -> int:
return cmp_simple_string("crash_host", r1, r2)


SorterCrashHost = Sorter(
ident="crash_host",
title=_l("Crash Host"),
columns=["crash_host"],
sort_function=_sort_crash_host,
)


def _sort_crash_item(
r1: Row,
r2: Row,
*,
parameters: Mapping[str, Any] | None,
config: Config,
request: Request,
) -> int:
return cmp_simple_string("crash_item", r1, r2)


SorterCrashItem = Sorter(
ident="crash_item",
title=_l("Crash Item"),
columns=["crash_item"],
sort_function=_sort_crash_item,
)


def _sort_crash_check_type(
r1: Row,
r2: Row,
*,
parameters: Mapping[str, Any] | None,
config: Config,
request: Request,
) -> int:
return cmp_simple_string("crash_check_type", r1, r2)


SorterCrashCheckName = Sorter(
ident="crash_check_type",
title=_l("Crash Check Name"),
columns=["crash_check_type"],
sort_function=_sort_crash_check_type,
)


def _sort_crash_service_description(
r1: Row,
r2: Row,
*,
parameters: Mapping[str, Any] | None,
config: Config,
request: Request,
) -> int:
return cmp_simple_string("crash_service_description", r1, r2)


SorterCrashServiceDescription = Sorter(
ident="crash_service_description",
title=_l("Crash Service Description"),
columns=["crash_service_description"],
sort_function=_sort_crash_service_description,
)
2 changes: 2 additions & 0 deletions cmk/gui/views/builtin_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5196,6 +5196,8 @@ def _simple_host_view(custom_attributes, add_context=None):
"num_columns": 1,
"painters": [
ColumnSpec(name="crash_ident"),
ColumnSpec(name="crash_host"),
ColumnSpec(name="crash_service_description"),
ColumnSpec(name="crash_type"),
ColumnSpec(name="crash_source"),
ColumnSpec(name="crash_version"),
Expand Down
4 changes: 4 additions & 0 deletions tests/unit/cmk/gui/plugins/views/test_painters.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ def test_registered_painters() -> None:
"comment_id",
"comment_time",
"comment_what",
"crash_host",
"crash_item",
"crash_service_description",
"crash_check_type",
"crash_exception",
"crash_ident",
"crash_time",
Expand Down