65 lines
2.2 KiB
Python
65 lines
2.2 KiB
Python
from datetime import datetime
|
|
from typing import Sequence
|
|
|
|
from ..checkmk import Downtime, ServiceState
|
|
from ..models import state_name
|
|
from .constants import HISTORY_LIMIT, LINE_OUTPUT_MAX, LIST_LIMIT, TS_FORMAT
|
|
from .sanitize import sanitize
|
|
|
|
NONE_FOUND = "Keine Einträge."
|
|
|
|
|
|
def _line_text(value: object, limit: int = LINE_OUTPUT_MAX) -> str:
|
|
return sanitize(value, limit, single_line=True)
|
|
|
|
|
|
def _ts(value: int) -> str:
|
|
return datetime.fromtimestamp(value).strftime(TS_FORMAT) if value else "unbekannt"
|
|
|
|
|
|
def service_line(item: ServiceState, with_host: bool = True) -> str:
|
|
name = f"{_line_text(item.host, 100)} / {_line_text(item.service, 100)}" if with_host \
|
|
else _line_text(item.service, 100)
|
|
flags = []
|
|
if not item.hard:
|
|
flags.append("soft")
|
|
if item.in_downtime:
|
|
flags.append("Downtime")
|
|
if item.flapping:
|
|
flags.append("flappt")
|
|
suffix = f" [{', '.join(flags)}]" if flags else ""
|
|
return f"{state_name(item.state)} {name}{suffix}: {_line_text(item.output)}"
|
|
|
|
|
|
def format_status(item: ServiceState | None) -> str:
|
|
if item is None:
|
|
return "Service nicht gefunden."
|
|
return f"{service_line(item)} (seit {_ts(item.last_state_change)})"
|
|
|
|
|
|
def _limited(lines: list[str]) -> str:
|
|
if not lines:
|
|
return NONE_FOUND
|
|
extra = len(lines) - LIST_LIMIT
|
|
text = "\n".join(lines[:LIST_LIMIT])
|
|
return f"{text}\n... und {extra} weitere" if extra > 0 else text
|
|
|
|
|
|
def format_services(items: Sequence[ServiceState], with_host: bool = True) -> str:
|
|
ordered = sorted(items, key=lambda i: (-i.state, i.host, i.service))
|
|
return _limited([service_line(i, with_host) for i in ordered])
|
|
|
|
|
|
def format_history(changes: Sequence) -> str:
|
|
lines = [f"{_ts(c.ts)} {state_name(c.state)}" for c in list(changes)[:HISTORY_LIMIT]]
|
|
return "\n".join(lines) if lines else NONE_FOUND
|
|
|
|
|
|
def format_downtimes(items: Sequence[Downtime]) -> str:
|
|
lines = []
|
|
for item in items:
|
|
target = _line_text(item.host, 100) + (f" / {_line_text(item.service, 100)}" if item.service else "")
|
|
lines.append(f"{target}: {_line_text(item.start, 40)} bis {_line_text(item.end, 40)}, "
|
|
f"{_line_text(item.comment)}")
|
|
return _limited(lines)
|