store only status-change events; UI client-side polling refactor
This commit is contained in:
@@ -155,59 +155,79 @@ async def ingest_event(
|
||||
agent_id: str,
|
||||
ev: CheckResultEvent,
|
||||
) -> bool:
|
||||
"""Return True if accepted, False if deduplicated."""
|
||||
"""Return True if a new change row was written, False if not (duplicate/unchanged/late)."""
|
||||
observed = to_utc(ev.observed_at)
|
||||
output = redact(ev.output)
|
||||
check_summary = (output or "")[:200] if output else None
|
||||
incident_key = _incident_key(agent_id, ev)
|
||||
|
||||
stmt = pg_insert(Event).values(
|
||||
event_id=UUID(ev.event_id),
|
||||
agent_id=agent_id,
|
||||
check_id=ev.check_id,
|
||||
observed_at=observed,
|
||||
status=ev.status,
|
||||
exit_code=ev.exit_code,
|
||||
duration_ms=ev.duration_ms,
|
||||
output=output,
|
||||
output_truncated=ev.output_truncated,
|
||||
notifications_enabled=ev.notifications_enabled,
|
||||
incident_key=incident_key,
|
||||
)
|
||||
stmt = stmt.on_conflict_do_nothing(index_elements=[Event.event_id]).returning(Event.event_id)
|
||||
result = await session.execute(stmt)
|
||||
inserted = result.scalar_one_or_none()
|
||||
if inserted is None:
|
||||
metrics.events_total.labels(result="deduplicated").inc()
|
||||
return False
|
||||
|
||||
metrics.events_total.labels(result="accepted").inc()
|
||||
|
||||
chk_res = await session.execute(
|
||||
select(Check).where(Check.agent_id == agent_id, Check.check_id == ev.check_id)
|
||||
)
|
||||
cur = chk_res.scalar_one_or_none()
|
||||
is_late = cur is not None and cur.last_observed_at > observed
|
||||
if is_late:
|
||||
return True
|
||||
changed = cur is None or cur.status != ev.status or cur.exit_code != ev.exit_code
|
||||
|
||||
if cur is None:
|
||||
session.add(
|
||||
Check(
|
||||
agent_id=agent_id,
|
||||
check_id=ev.check_id,
|
||||
status=ev.status,
|
||||
exit_code=ev.exit_code,
|
||||
last_observed_at=observed,
|
||||
last_event_id=UUID(ev.event_id),
|
||||
incident_key=incident_key,
|
||||
)
|
||||
if is_late:
|
||||
metrics.events_total.labels(result="late").inc()
|
||||
return False
|
||||
|
||||
if changed:
|
||||
stmt = pg_insert(Event).values(
|
||||
event_id=UUID(ev.event_id),
|
||||
agent_id=agent_id,
|
||||
check_id=ev.check_id,
|
||||
observed_at=observed,
|
||||
status=ev.status,
|
||||
exit_code=ev.exit_code,
|
||||
duration_ms=ev.duration_ms,
|
||||
output=output,
|
||||
output_truncated=ev.output_truncated,
|
||||
notifications_enabled=ev.notifications_enabled,
|
||||
incident_key=incident_key,
|
||||
)
|
||||
stmt = stmt.on_conflict_do_nothing(index_elements=[Event.event_id]).returning(
|
||||
Event.event_id
|
||||
)
|
||||
result = await session.execute(stmt)
|
||||
inserted = result.scalar_one_or_none()
|
||||
if inserted is None:
|
||||
metrics.events_total.labels(result="deduplicated").inc()
|
||||
return False
|
||||
metrics.events_total.labels(result="accepted").inc()
|
||||
else:
|
||||
cur.status = ev.status
|
||||
cur.exit_code = ev.exit_code
|
||||
cur.last_observed_at = observed
|
||||
cur.last_event_id = UUID(ev.event_id)
|
||||
cur.incident_key = incident_key
|
||||
metrics.events_total.labels(result="unchanged").inc()
|
||||
|
||||
# Upsert Check to be safe under concurrent first-write race for the same (agent_id, check_id).
|
||||
# When changed=False keep the existing last_event_id and incident_key — incident_key changes
|
||||
# are only meaningful at transitions and would otherwise desync from any open Incident.
|
||||
check_values = {
|
||||
"agent_id": agent_id,
|
||||
"check_id": ev.check_id,
|
||||
"status": ev.status,
|
||||
"exit_code": ev.exit_code,
|
||||
"last_observed_at": observed,
|
||||
"last_event_id": UUID(ev.event_id),
|
||||
"incident_key": incident_key,
|
||||
"summary": check_summary,
|
||||
}
|
||||
update_set = {
|
||||
"status": ev.status,
|
||||
"exit_code": ev.exit_code,
|
||||
"last_observed_at": observed,
|
||||
"summary": check_summary,
|
||||
}
|
||||
if changed:
|
||||
update_set["last_event_id"] = UUID(ev.event_id)
|
||||
update_set["incident_key"] = incident_key
|
||||
chk_stmt = pg_insert(Check).values(**check_values)
|
||||
chk_stmt = chk_stmt.on_conflict_do_update(
|
||||
index_elements=[Check.agent_id, Check.check_id], set_=update_set
|
||||
)
|
||||
await session.execute(chk_stmt)
|
||||
|
||||
if not changed:
|
||||
return False
|
||||
|
||||
transition, inc = await _apply_incident(session, agent_id, ev, incident_key)
|
||||
if transition and inc is not None and ev.notifications_enabled:
|
||||
|
||||
Reference in New Issue
Block a user