mirror of
https://github.com/hansjone/netx.git
synced 2026-10-12 00:40:44 +08:00
feat(ume): key alarm forward to OClaw via WSS and AI monitor UI
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
9a39ddfcc7
commit
1f1b42e8bf
18 changed files with 1079 additions and 32 deletions
65
netx_api/key_alert_matcher.py
Normal file
65
netx_api/key_alert_matcher.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .models import UmeKeyAlertRule
|
||||
from .ume_sync_service import _is_alarm_cleared, notification_id_from_norm
|
||||
|
||||
_RULE_CACHE_LOCK = threading.Lock()
|
||||
_RULE_CACHE: dict[str, UmeKeyAlertRule] = {}
|
||||
_RULE_CACHE_LOADED_AT = 0.0
|
||||
_RULE_CACHE_TTL_S = 30.0
|
||||
|
||||
|
||||
def invalidate_key_alert_rule_cache() -> None:
|
||||
global _RULE_CACHE_LOADED_AT
|
||||
with _RULE_CACHE_LOCK:
|
||||
_RULE_CACHE.clear()
|
||||
_RULE_CACHE_LOADED_AT = 0.0
|
||||
|
||||
|
||||
def _load_enabled_rules(db: Session) -> dict[str, UmeKeyAlertRule]:
|
||||
global _RULE_CACHE_LOADED_AT
|
||||
now = time.time()
|
||||
with _RULE_CACHE_LOCK:
|
||||
if _RULE_CACHE and (now - _RULE_CACHE_LOADED_AT) < _RULE_CACHE_TTL_S:
|
||||
return dict(_RULE_CACHE)
|
||||
rows = (
|
||||
db.query(UmeKeyAlertRule)
|
||||
.filter(UmeKeyAlertRule.enabled == 1)
|
||||
.all()
|
||||
)
|
||||
loaded = {str(row.notification_id or "").strip(): row for row in rows if str(row.notification_id or "").strip()}
|
||||
with _RULE_CACHE_LOCK:
|
||||
_RULE_CACHE.clear()
|
||||
_RULE_CACHE.update(loaded)
|
||||
_RULE_CACHE_LOADED_AT = now
|
||||
return dict(loaded)
|
||||
|
||||
|
||||
def match_key_alert_rule(
|
||||
db: Session,
|
||||
*,
|
||||
norm: dict[str, Any],
|
||||
action: str,
|
||||
) -> UmeKeyAlertRule | None:
|
||||
notification_id = notification_id_from_norm(norm)
|
||||
if not notification_id:
|
||||
return None
|
||||
rules = _load_enabled_rules(db)
|
||||
rule = rules.get(notification_id)
|
||||
if rule is None:
|
||||
return None
|
||||
act = str(action or "").strip().lower()
|
||||
if act in {"inserted", "updated"}:
|
||||
if _is_alarm_cleared(norm):
|
||||
return None
|
||||
return rule
|
||||
if act == "deleted":
|
||||
if int(getattr(rule, "forward_on_clear", 0) or 0) == 1:
|
||||
return rule
|
||||
return None
|
||||
Loading…
Add table
Add a link
Reference in a new issue