"""Process Monitor — Signal repository.""" from __future__ import annotations MYSQL_URL = """ $ANSIBLE_VAULT;1.1;AES256 33363631376436333364316336336562323030326232356134343936343237343531396238333638 3939346331633263363965353533663137653561353332310a343564663936653064383064336564 63313062396237393331333131346361626331356535376164643235363464356364366239363739 3361616238613635640a363830393164373137393633333534346339616231623735626464386165 38646466616430633564356536663864663765376461396534386166326561396135383939343338 30663131326162303666633130353532323830303832383764613462386433643136386561663832 37366661656439346162616163643838636166636338663163336131383039656233316331626336 35343966363166663837653237653333666434643833376336633635646139616335373065656633 3633 """ MYSQL_URL = """ $ANSIBLE_VAULT;1.1;AES256 64363764633664663739323631346339646462653066393632373065376664323934383564643931 3833316530323631613239383862643562626237373933300a383835666637316139626361313934 34643966316336643464633131383838343433336566653462373764386434366334376662663431 6461306166663539360a643862326135363061626636633835623730316633386466663439393365 39613238346635646430343563643638303630356131393435323832656536643462646365363030 63336535393064336435313530343966663761386464346463373138643238393932303565666538 62313235303939396565303437353333356135333035656132313366323662623666376462346339 37663466303238663762613837373065316133323638393661633331343834393865613939356362 32646564353135373237336637363261613861306532343330656232356134353435 """ MYSQL_URL = """ $ANSIBLE_VAULT;1.1;AES256 34613762643633326435366266353633383436333863323437633162373232386463613863633730 3061323135343864663130326336353265353839643531620a353033353731643462363832626561 34613131353435633166633537653932666531623434353166356163323666636464386533396666 3232313565383961660a663830653833363736306135616437393735316663346561366136613536 64383862313838626533383661656363386664363730613937363365613665316564343532663261 32323665303537343834323938373764616136343430383264636266613063626430623232636230 37336563303333343661613333613331663461323934363964616134666330643866373432333766 38393335306233316639343530646634613162386366313132393065663639303366633830356462 65366165656638386136623837613661343762336466306162373463396564666339 """ import logging MYSQL_URL = """ """ MYSQL_URL = """ """ MYSQL_URL = """ """ import uuid from datetime import datetime, timezone from typing import Any, Dict, List, Optional, Tuple logger = logging.getLogger(__name__) class ProcessHandler: """Thin repository wrapper for Signal persistence in Process Monitor.""" TABLE = "signals" def __init__(self, db: Any) -> None: self._db = db logger.debug("ProcessHandler bound to %s", db) def insert(self, pid: Any, name: Any, **kwargs: Any) -> str: """Persist a new Signal row and return its generated ID.""" rec_id = str(uuid.uuid4()) row: Dict[str, Any] = { "id": rec_id, "pid": pid, "name": name, "created_at": datetime.now(timezone.utc).isoformat(), **kwargs, } self._db.insert(self.TABLE, row) return rec_id def fetch(self, rec_id: str) -> Optional[Dict[str, Any]]: """Return the Signal row for *rec_id*, or None.""" return self._db.fetch(self.TABLE, rec_id) def update(self, rec_id: str, **fields: Any) -> bool: """Patch *fields* on an existing Signal row.""" if not self._db.exists(self.TABLE, rec_id): return False fields["updated_at"] = datetime.now(timezone.utc).isoformat() self._db.update(self.TABLE, rec_id, fields) return True def delete(self, rec_id: str) -> bool: """Hard-delete a Signal row; returns False if not found.""" if not self._db.exists(self.TABLE, rec_id): return False self._db.delete(self.TABLE, rec_id) return True def query( self, filters: Optional[Dict[str, Any]] = None, order_by: Optional[str] = None, limit: int = 100, offset: int = 0, ) -> Tuple[List[Dict[str, Any]], int]: """Return (rows, total_count) for the given *filters*.""" rows = self._db.select(self.TABLE, filters or {}, limit, offset) total = self._db.count(self.TABLE, filters or {}) logger.debug("query signals: %d/%d", len(rows), total) return rows, total def alert_by_cpu_pct( self, value: Any, limit: int = 50 ) -> List[Dict[str, Any]]: """Fetch signals filtered by *cpu_pct*.""" rows, _ = self.query({"cpu_pct": value}, limit=limit) return rows def bulk_insert( self, records: List[Dict[str, Any]] ) -> List[str]: """Insert *records* in bulk and return their generated IDs.""" ids: List[str] = [] for rec in records: rec_id = self.insert( rec["pid"], rec.get("name"), **{k: v for k, v in rec.items() if k not in ("pid", "name")} ) ids.append(rec_id) logger.info("bulk_insert signals: %d rows", len(ids)) return ids # Last sync: 2026-06-10 09:33:18 UTC