2023-08-31 09:45:10 +00:00
|
|
|
import os
|
2023-08-31 09:00:22 +00:00
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
|
|
import psutil
|
|
|
|
|
|
|
|
from .settings import SETTINGS, MetricSettings
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(slots=True, frozen=True)
|
|
|
|
class Report:
|
|
|
|
result: str
|
|
|
|
failed: bool = field(default=False, kw_only=True)
|
|
|
|
|
|
|
|
|
|
|
|
def _report(
|
2023-08-31 09:45:10 +00:00
|
|
|
*,
|
2023-08-31 09:00:22 +00:00
|
|
|
settings: MetricSettings,
|
|
|
|
name: str,
|
|
|
|
value: float,
|
2023-08-31 11:02:23 +00:00
|
|
|
) -> Report:
|
2023-08-31 09:00:22 +00:00
|
|
|
result = settings.report.format(name=name, value=value)
|
|
|
|
|
|
|
|
if (
|
|
|
|
value > settings.threshold and not settings.inverted
|
|
|
|
or value < settings.threshold and settings.inverted
|
|
|
|
):
|
|
|
|
return Report(result, failed=True)
|
|
|
|
|
|
|
|
else:
|
|
|
|
return Report(result)
|
|
|
|
|
|
|
|
|
|
|
|
def cpu_metric() -> Report | None:
|
2023-08-31 11:02:23 +00:00
|
|
|
if not SETTINGS.cpu.enabled:
|
|
|
|
return None
|
|
|
|
|
2023-08-31 09:00:22 +00:00
|
|
|
value = psutil.cpu_percent(interval=1)
|
2023-08-31 09:45:10 +00:00
|
|
|
return _report(
|
|
|
|
settings=SETTINGS.cpu,
|
2023-08-31 11:09:19 +00:00
|
|
|
name=SETTINGS.cpu.name,
|
2023-08-31 09:45:10 +00:00
|
|
|
value=value,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def disk_metric() -> Report | None:
|
|
|
|
if not SETTINGS.disk.enabled:
|
|
|
|
return None
|
|
|
|
|
2023-08-31 11:02:23 +00:00
|
|
|
def path_to_free_percent(path: os.PathLike) -> float:
|
2023-08-31 09:45:10 +00:00
|
|
|
try:
|
2023-08-31 11:02:23 +00:00
|
|
|
sv = os.statvfs(path)
|
2023-08-31 09:45:10 +00:00
|
|
|
return sv.f_bavail / sv.f_blocks * 100
|
|
|
|
except ZeroDivisionError:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
data = sorted([
|
2023-08-31 11:02:23 +00:00
|
|
|
(str(path), path_to_free_percent(path))
|
2023-08-31 09:45:10 +00:00
|
|
|
for path in SETTINGS.disk.paths
|
|
|
|
], key=lambda d: d[1])
|
|
|
|
|
2023-08-31 11:02:23 +00:00
|
|
|
reports = [_report(
|
|
|
|
settings=SETTINGS.disk,
|
|
|
|
name=path,
|
|
|
|
value=percent,
|
|
|
|
) for path, percent in data]
|
2023-08-31 09:45:10 +00:00
|
|
|
|
2023-08-31 11:02:54 +00:00
|
|
|
report_inner = ", ".join(
|
|
|
|
report.result
|
|
|
|
for report in reports[:SETTINGS.disk.count]
|
|
|
|
)
|
|
|
|
|
2023-08-31 09:45:10 +00:00
|
|
|
return Report(
|
2023-08-31 11:02:54 +00:00
|
|
|
SETTINGS.disk.report_outer.format(
|
2023-08-31 11:09:19 +00:00
|
|
|
name=SETTINGS.disk.name,
|
2023-08-31 11:02:54 +00:00
|
|
|
inner=report_inner,
|
|
|
|
),
|
|
|
|
failed=any(
|
|
|
|
report.failed
|
|
|
|
for report in reports
|
|
|
|
),
|
2023-08-31 09:45:10 +00:00
|
|
|
)
|