Add max_alert_logging/src/max_alert_logging/cli.py
This commit is contained in:
parent
f59c9cb08f
commit
15fbd84b32
1 changed files with 86 additions and 0 deletions
86
max_alert_logging/src/max_alert_logging/cli.py
Normal file
86
max_alert_logging/src/max_alert_logging/cli.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import argparse
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from max_alert_logging import core
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""CLI entry point for deduplicating Max-only alerts from log files."""
|
||||
parser = argparse.ArgumentParser(description="Run Max-only Alert deduplication and logging.")
|
||||
parser.add_argument("--input", required=True, help="Path to the input JSON file with log entries.")
|
||||
parser.add_argument("--output", required=True, help="Path to the output JSON file for deduplicated alerts.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
input_path = Path(args.input)
|
||||
output_path = Path(args.output)
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s [%(levelname)s] %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
)
|
||||
|
||||
if not input_path.exists() or not input_path.is_file():
|
||||
logging.error(f"Input file not found: {input_path}")
|
||||
raise FileNotFoundError(f"Input file not found: {input_path}")
|
||||
|
||||
with input_path.open("r", encoding="utf-8") as f:
|
||||
try:
|
||||
data: Any = json.load(f)
|
||||
except json.JSONDecodeError as e:
|
||||
logging.error(f"Invalid JSON format: {e}")
|
||||
raise
|
||||
|
||||
if not isinstance(data, list):
|
||||
logging.error("Input JSON must be a list of log entries.")
|
||||
raise ValueError("Input JSON must be a list of log entries.")
|
||||
|
||||
deduped_entries = []
|
||||
seen_keys = set()
|
||||
|
||||
for entry in data:
|
||||
if not isinstance(entry, dict):
|
||||
logging.warning("Skipping invalid entry (not a dict).")
|
||||
continue
|
||||
required_fields = [
|
||||
"corr_id", "stratum", "job_parallelism", "expires_at_dist_hours",
|
||||
"t_gate_read", "t_index_visible", "retry_taken", "retry_total_overhead_ms",
|
||||
"policy_hash", "setup_fingerprint"
|
||||
]
|
||||
if not all(field in entry for field in required_fields):
|
||||
logging.warning(f"Skipping incomplete entry: {entry}")
|
||||
continue
|
||||
|
||||
key = (entry["corr_id"], entry["policy_hash"], entry["setup_fingerprint"])
|
||||
if key in seen_keys:
|
||||
continue
|
||||
seen_keys.add(key)
|
||||
|
||||
success = core.log_alert(
|
||||
corr_id=entry["corr_id"],
|
||||
stratum=entry["stratum"],
|
||||
job_parallelism=int(entry["job_parallelism"]),
|
||||
expires_at_dist_hours=float(entry["expires_at_dist_hours"]),
|
||||
t_gate_read=float(entry["t_gate_read"]),
|
||||
t_index_visible=float(entry["t_index_visible"]),
|
||||
retry_taken=int(entry["retry_taken"]),
|
||||
retry_total_overhead_ms=float(entry["retry_total_overhead_ms"]),
|
||||
policy_hash=str(entry["policy_hash"]),
|
||||
setup_fingerprint=str(entry["setup_fingerprint"]),
|
||||
)
|
||||
|
||||
if success:
|
||||
deduped_entries.append(entry)
|
||||
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with output_path.open("w", encoding="utf-8") as f:
|
||||
json.dump(deduped_entries, f, ensure_ascii=False, indent=2)
|
||||
|
||||
logging.info(f"Deduplicated {len(deduped_entries)} alerts written to {output_path}.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue