feat(monitor): store nginx telemetry for generic clients

- accept nginx installation status and sites-enabled list
- persist nginx fields in server state
- expose nginx data in monitor overview/admin views
- auto-migrate new server_states columns on startup
This commit is contained in:
zhi
2026-03-20 10:03:56 +00:00
parent d67f676006
commit 14dcda3cdc
4 changed files with 18 additions and 0 deletions

View File

@@ -180,6 +180,8 @@ class ServerHeartbeat(BaseModel):
openclaw_version: str | None = None
plugin_version: str | None = None
agents: List[dict] = []
nginx_installed: bool | None = None
nginx_sites: List[str] = []
cpu_pct: float | None = None
mem_pct: float | None = None
disk_pct: float | None = None
@@ -198,6 +200,8 @@ def server_heartbeat(payload: ServerHeartbeat, db: Session = Depends(get_db)):
st.openclaw_version = payload.openclaw_version
st.plugin_version = payload.plugin_version
st.agents_json = json.dumps(payload.agents, ensure_ascii=False)
st.nginx_installed = payload.nginx_installed
st.nginx_sites_json = json.dumps(payload.nginx_sites, ensure_ascii=False)
st.cpu_pct = payload.cpu_pct
st.mem_pct = payload.mem_pct
st.disk_pct = payload.disk_pct
@@ -213,6 +217,8 @@ class TelemetryPayload(BaseModel):
openclaw_version: str | None = None
plugin_version: str | None = None
agents: List[dict] = []
nginx_installed: bool | None = None
nginx_sites: List[str] = []
cpu_pct: float | None = None
mem_pct: float | None = None
disk_pct: float | None = None
@@ -241,6 +247,8 @@ def server_heartbeat_v2(
st.openclaw_version = payload.openclaw_version
st.plugin_version = payload.plugin_version
st.agents_json = json.dumps(payload.agents, ensure_ascii=False)
st.nginx_installed = payload.nginx_installed
st.nginx_sites_json = json.dumps(payload.nginx_sites, ensure_ascii=False)
st.cpu_pct = payload.cpu_pct
st.mem_pct = payload.mem_pct
st.disk_pct = payload.disk_pct

View File

@@ -224,6 +224,12 @@ def _migrate_schema():
if _has_table(db, "server_states") and not _has_column(db, "server_states", "plugin_version"):
db.execute(text("ALTER TABLE server_states ADD COLUMN plugin_version VARCHAR(64) NULL"))
# --- server_states nginx telemetry for generic monitor client ---
if _has_table(db, "server_states") and not _has_column(db, "server_states", "nginx_installed"):
db.execute(text("ALTER TABLE server_states ADD COLUMN nginx_installed BOOLEAN NULL"))
if _has_table(db, "server_states") and not _has_column(db, "server_states", "nginx_sites_json"):
db.execute(text("ALTER TABLE server_states ADD COLUMN nginx_sites_json TEXT NULL"))
db.commit()
except Exception as e:
db.rollback()

View File

@@ -52,6 +52,8 @@ class ServerState(Base):
openclaw_version = Column(String(64), nullable=True)
plugin_version = Column(String(64), nullable=True)
agents_json = Column(Text, nullable=True) # json list
nginx_installed = Column(Boolean, nullable=True)
nginx_sites_json = Column(Text, nullable=True) # json list
cpu_pct = Column(Float, nullable=True)
mem_pct = Column(Float, nullable=True)
disk_pct = Column(Float, nullable=True)

View File

@@ -304,6 +304,8 @@ def get_server_states_view(db: Session, offline_after_minutes: int = 7):
'disk_pct': st.disk_pct if st else None,
'swap_pct': st.swap_pct if st else None,
'agents': json.loads(st.agents_json) if st and st.agents_json else [],
'nginx_installed': st.nginx_installed if st else None,
'nginx_sites': json.loads(st.nginx_sites_json) if st and st.nginx_sites_json else [],
'last_seen_at': last_seen.isoformat() if last_seen else None,
})
return out