1802
This commit is contained in:
@@ -185,6 +185,73 @@ def extract_fields(obj: Dict[str, Any]):
|
||||
return product, mac, fw_active
|
||||
|
||||
|
||||
def extract_event_age_s(obj: Dict[str, Any]) -> Optional[int]:
|
||||
"""
|
||||
Best-effort age of the registration event in seconds, derived from a timestamp
|
||||
embedded in the payload if present. Returns None when no sane timestamp is found.
|
||||
Surgical addition: no external calls, no broker queries.
|
||||
"""
|
||||
candidates = []
|
||||
|
||||
def _walk(x):
|
||||
if isinstance(x, dict):
|
||||
for k, v in x.items():
|
||||
kl = str(k).strip().lower()
|
||||
if kl in {"ts", "timestamp", "event_ts", "event_timestamp", "time", "created_at", "createdat", "published_at", "publishedat"}:
|
||||
candidates.append(v)
|
||||
_walk(v)
|
||||
elif isinstance(x, list):
|
||||
for item in x:
|
||||
_walk(item)
|
||||
|
||||
def _to_epoch(v) -> Optional[int]:
|
||||
try:
|
||||
if isinstance(v, bool) or v is None:
|
||||
return None
|
||||
if isinstance(v, (int, float)):
|
||||
n = float(v)
|
||||
elif isinstance(v, str):
|
||||
s = v.strip()
|
||||
if not s:
|
||||
return None
|
||||
if s.endswith('Z'):
|
||||
s = s[:-1] + '+00:00'
|
||||
try:
|
||||
return int(datetime.fromisoformat(s).timestamp())
|
||||
except Exception:
|
||||
n = float(s)
|
||||
else:
|
||||
return None
|
||||
|
||||
# milliseconds / microseconds / nanoseconds -> seconds
|
||||
if n > 1e18:
|
||||
n = n / 1e9
|
||||
elif n > 1e15:
|
||||
n = n / 1e6
|
||||
elif n > 1e12:
|
||||
n = n / 1e3
|
||||
|
||||
if 946684800 <= n <= 4102444800:
|
||||
return int(n)
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
try:
|
||||
_walk(obj)
|
||||
now_epoch = int(time.time())
|
||||
for raw in candidates:
|
||||
epoch = _to_epoch(raw)
|
||||
if epoch is None:
|
||||
continue
|
||||
age = now_epoch - epoch
|
||||
if 0 <= age <= 86400 * 30:
|
||||
return int(age)
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
# =========================
|
||||
# NetBox lookup (urllib)
|
||||
# =========================
|
||||
@@ -469,6 +536,7 @@ async def main():
|
||||
"netbox_ms": None,
|
||||
"total_ms": None,
|
||||
"nb_problems": None,
|
||||
"event_age_s": None,
|
||||
}
|
||||
|
||||
# strict payload dedupe
|
||||
@@ -489,6 +557,7 @@ async def main():
|
||||
text = payload.decode("utf-8", errors="replace")
|
||||
obj = json.loads(text)
|
||||
product, mac, fw = extract_fields(obj)
|
||||
event["event_age_s"] = extract_event_age_s(obj)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -871,7 +940,11 @@ async def main():
|
||||
event["decision_reason"] = "mac not found in netbox"
|
||||
await log_event(event)
|
||||
|
||||
line = f"nb_problems={nb_problems_snapshot} [{ts()}] product={product} mac={mac} fw={fw}{host_suffix}{action_suffix}"
|
||||
lag_suffix = ""
|
||||
if isinstance(event.get("event_age_s"), int):
|
||||
lag_suffix = f" event_age_s={event['event_age_s']}"
|
||||
|
||||
line = f"nb_problems={nb_problems_snapshot} [{ts()}] product={product} mac={mac} fw={fw}{host_suffix}{action_suffix}{lag_suffix}"
|
||||
if product == "fox100":
|
||||
line += f" netbox_ms={netbox_time_ms:.1f} total_ms={total_ms:.1f}"
|
||||
if args.include_subject:
|
||||
|
||||
Reference in New Issue
Block a user