From 97f12cac7a45a22c1825840468686ee4f613fefe Mon Sep 17 00:00:00 2001 From: zhi Date: Fri, 20 Mar 2026 07:23:18 +0000 Subject: [PATCH] feat(monitor): store plugin version separately from openclaw version - Add server_states.plugin_version column - Keep openclaw_version for remote OpenClaw runtime version - Expose plugin_version in monitor server view - Accept and persist plugin_version in heartbeat payloads --- app/api/routers/monitor.py | 9 +++++++++ app/main.py | 4 ++++ app/models/monitor.py | 1 + app/services/monitoring.py | 1 + 4 files changed, 15 insertions(+) diff --git a/app/api/routers/monitor.py b/app/api/routers/monitor.py index a8d2ac3..d396a2b 100644 --- a/app/api/routers/monitor.py +++ b/app/api/routers/monitor.py @@ -198,6 +198,7 @@ def revoke_api_key(server_id: int, db: Session = Depends(get_db), _: models.User class ServerHeartbeat(BaseModel): identifier: str openclaw_version: str | None = None + plugin_version: str | None = None agents: List[dict] = [] cpu_pct: float | None = None mem_pct: float | None = None @@ -215,6 +216,7 @@ def server_heartbeat(payload: ServerHeartbeat, db: Session = Depends(get_db)): st = ServerState(server_id=server.id) db.add(st) st.openclaw_version = payload.openclaw_version + st.plugin_version = payload.plugin_version st.agents_json = json.dumps(payload.agents, ensure_ascii=False) st.cpu_pct = payload.cpu_pct st.mem_pct = payload.mem_pct @@ -229,6 +231,7 @@ def server_heartbeat(payload: ServerHeartbeat, db: Session = Depends(get_db)): class TelemetryPayload(BaseModel): identifier: str openclaw_version: str | None = None + plugin_version: str | None = None agents: List[dict] = [] cpu_pct: float | None = None mem_pct: float | None = None @@ -256,6 +259,7 @@ def server_heartbeat_v2( st = ServerState(server_id=server.id) db.add(st) st.openclaw_version = payload.openclaw_version + st.plugin_version = payload.plugin_version st.agents_json = json.dumps(payload.agents, ensure_ascii=False) st.cpu_pct = payload.cpu_pct st.mem_pct = payload.mem_pct @@ -328,12 +332,17 @@ async def server_ws(websocket: WebSocket): if event == 'server.hello': st.openclaw_version = payload.get('openclaw_version') + st.plugin_version = payload.get('plugin_version') st.agents_json = json.dumps(payload.get('agents') or [], ensure_ascii=False) elif event in {'server.metrics', 'agent.status_changed'}: st.cpu_pct = payload.get('cpu_pct', st.cpu_pct) st.mem_pct = payload.get('mem_pct', st.mem_pct) st.disk_pct = payload.get('disk_pct', st.disk_pct) st.swap_pct = payload.get('swap_pct', st.swap_pct) + if 'openclaw_version' in payload: + st.openclaw_version = payload.get('openclaw_version') + if 'plugin_version' in payload: + st.plugin_version = payload.get('plugin_version') if 'agents' in payload: st.agents_json = json.dumps(payload.get('agents') or [], ensure_ascii=False) diff --git a/app/main.py b/app/main.py index eaf1e9b..7d85ef7 100644 --- a/app/main.py +++ b/app/main.py @@ -220,6 +220,10 @@ def _migrate_schema(): db.execute(text("ALTER TABLE monitored_servers ADD COLUMN api_key VARCHAR(64) NULL")) db.execute(text("CREATE UNIQUE INDEX idx_monitored_servers_api_key ON monitored_servers (api_key)")) + # --- server_states.plugin_version for monitor plugin telemetry --- + 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")) + db.commit() except Exception as e: db.rollback() diff --git a/app/models/monitor.py b/app/models/monitor.py index 21d0fc1..13cad5a 100644 --- a/app/models/monitor.py +++ b/app/models/monitor.py @@ -50,6 +50,7 @@ class ServerState(Base): id = Column(Integer, primary_key=True, index=True) server_id = Column(Integer, ForeignKey('monitored_servers.id'), nullable=False, unique=True) openclaw_version = Column(String(64), nullable=True) + plugin_version = Column(String(64), nullable=True) agents_json = Column(Text, nullable=True) # json list cpu_pct = Column(Float, nullable=True) mem_pct = Column(Float, nullable=True) diff --git a/app/services/monitoring.py b/app/services/monitoring.py index 81b1e1c..0f10811 100644 --- a/app/services/monitoring.py +++ b/app/services/monitoring.py @@ -298,6 +298,7 @@ def get_server_states_view(db: Session, offline_after_minutes: int = 7): 'display_name': s.display_name or s.identifier, 'online': online, 'openclaw_version': st.openclaw_version if st else None, + 'plugin_version': st.plugin_version if st else None, 'cpu_pct': st.cpu_pct if st else None, 'mem_pct': st.mem_pct if st else None, 'disk_pct': st.disk_pct if st else None,