diff --git a/metrics_reporting/src/metrics_reporting/core.py b/metrics_reporting/src/metrics_reporting/core.py new file mode 100644 index 0000000..c074021 --- /dev/null +++ b/metrics_reporting/src/metrics_reporting/core.py @@ -0,0 +1,60 @@ +import json +import logging +from dataclasses import dataclass, asdict +from pathlib import Path +from datetime import datetime +from typing import Any + +__all__ = ["Metrics", "report_metrics"] + + +@dataclass +class Metrics: + """Repräsentiert die Metriken eines System-Runs.""" + run_number: int + warn_rate: float + unknown_rate: float + unpin_delta_t: float + + def validate(self) -> None: + assert isinstance(self.run_number, int) and self.run_number >= 0, "run_number muss eine nichtnegative ganze Zahl sein" + for name in ("warn_rate", "unknown_rate", "unpin_delta_t"): + value = getattr(self, name) + assert isinstance(value, (float, int)), f"{name} muss ein numerischer Wert sein" + assert 0.0 <= float(value) <= 1.0, f"{name} sollte zwischen 0.0 und 1.0 liegen" + + +def report_metrics(run_number: int, warn_rate: float, unknown_rate: float, unpin_delta_t: float) -> None: + """Erzeugt und schreibt eine JSON-Datei mit den gegebenen Systemmetriken. + + Die Struktur entspricht dem Metrics-Datenmodell und ergänzt Metadaten. + """ + logging.basicConfig(level=logging.INFO, format="%(levelname)s:%(message)s") + try: + metrics = Metrics( + run_number=run_number, + warn_rate=warn_rate, + unknown_rate=unknown_rate, + unpin_delta_t=unpin_delta_t, + ) + metrics.validate() + except AssertionError as e: + logging.error(f"Validierungsfehler in den Eingabemetriken: {e}") + raise ValueError(f"Ungültige Metriken: {e}") from e + + metrics_dict: dict[str, Any] = asdict(metrics) + metrics_dict["timestamp"] = datetime.utcnow().isoformat() + "Z" + + output_dir = Path("output") + output_dir.mkdir(parents=True, exist_ok=True) + output_file = output_dir / "metrics_report.json" + + try: + with output_file.open("w", encoding="utf-8") as f: + json.dump(metrics_dict, f, indent=2, ensure_ascii=False) + logging.info(f"Metrikbericht erfolgreich nach {output_file} geschrieben.") + except OSError as e: + logging.error(f"Fehler beim Schreiben der Datei: {e}") + raise + + return None \ No newline at end of file