from __future__ import annotations import logging import subprocess from abc import ABC, abstractmethod from config import Config from notify import Alerter from state import State class Check(ABC): def __init__(self, config: Config, state: State, alerter: Alerter) -> None: self.config = config self.state = state self.alerter = alerter self.log = logging.getLogger(self.__class__.__name__) @abstractmethod def run(self) -> None: pass def _run(self, cmd: list[str], timeout: int) -> str | None: """Run command, return stdout (even on non-zero exit) or None on error.""" try: result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout, ) return result.stdout except subprocess.TimeoutExpired: self.log.warning("Timeout: %s", " ".join(cmd)) return None except (FileNotFoundError, OSError) as e: self.log.warning("Fehler bei '%s': %s", cmd[0], e) return None