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
This commit is contained in:
@@ -198,6 +198,7 @@ def revoke_api_key(server_id: int, db: Session = Depends(get_db), _: models.User
|
|||||||
class ServerHeartbeat(BaseModel):
|
class ServerHeartbeat(BaseModel):
|
||||||
identifier: str
|
identifier: str
|
||||||
openclaw_version: str | None = None
|
openclaw_version: str | None = None
|
||||||
|
plugin_version: str | None = None
|
||||||
agents: List[dict] = []
|
agents: List[dict] = []
|
||||||
cpu_pct: float | None = None
|
cpu_pct: float | None = None
|
||||||
mem_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)
|
st = ServerState(server_id=server.id)
|
||||||
db.add(st)
|
db.add(st)
|
||||||
st.openclaw_version = payload.openclaw_version
|
st.openclaw_version = payload.openclaw_version
|
||||||
|
st.plugin_version = payload.plugin_version
|
||||||
st.agents_json = json.dumps(payload.agents, ensure_ascii=False)
|
st.agents_json = json.dumps(payload.agents, ensure_ascii=False)
|
||||||
st.cpu_pct = payload.cpu_pct
|
st.cpu_pct = payload.cpu_pct
|
||||||
st.mem_pct = payload.mem_pct
|
st.mem_pct = payload.mem_pct
|
||||||
@@ -229,6 +231,7 @@ def server_heartbeat(payload: ServerHeartbeat, db: Session = Depends(get_db)):
|
|||||||
class TelemetryPayload(BaseModel):
|
class TelemetryPayload(BaseModel):
|
||||||
identifier: str
|
identifier: str
|
||||||
openclaw_version: str | None = None
|
openclaw_version: str | None = None
|
||||||
|
plugin_version: str | None = None
|
||||||
agents: List[dict] = []
|
agents: List[dict] = []
|
||||||
cpu_pct: float | None = None
|
cpu_pct: float | None = None
|
||||||
mem_pct: float | None = None
|
mem_pct: float | None = None
|
||||||
@@ -256,6 +259,7 @@ def server_heartbeat_v2(
|
|||||||
st = ServerState(server_id=server.id)
|
st = ServerState(server_id=server.id)
|
||||||
db.add(st)
|
db.add(st)
|
||||||
st.openclaw_version = payload.openclaw_version
|
st.openclaw_version = payload.openclaw_version
|
||||||
|
st.plugin_version = payload.plugin_version
|
||||||
st.agents_json = json.dumps(payload.agents, ensure_ascii=False)
|
st.agents_json = json.dumps(payload.agents, ensure_ascii=False)
|
||||||
st.cpu_pct = payload.cpu_pct
|
st.cpu_pct = payload.cpu_pct
|
||||||
st.mem_pct = payload.mem_pct
|
st.mem_pct = payload.mem_pct
|
||||||
@@ -328,12 +332,17 @@ async def server_ws(websocket: WebSocket):
|
|||||||
|
|
||||||
if event == 'server.hello':
|
if event == 'server.hello':
|
||||||
st.openclaw_version = payload.get('openclaw_version')
|
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)
|
st.agents_json = json.dumps(payload.get('agents') or [], ensure_ascii=False)
|
||||||
elif event in {'server.metrics', 'agent.status_changed'}:
|
elif event in {'server.metrics', 'agent.status_changed'}:
|
||||||
st.cpu_pct = payload.get('cpu_pct', st.cpu_pct)
|
st.cpu_pct = payload.get('cpu_pct', st.cpu_pct)
|
||||||
st.mem_pct = payload.get('mem_pct', st.mem_pct)
|
st.mem_pct = payload.get('mem_pct', st.mem_pct)
|
||||||
st.disk_pct = payload.get('disk_pct', st.disk_pct)
|
st.disk_pct = payload.get('disk_pct', st.disk_pct)
|
||||||
st.swap_pct = payload.get('swap_pct', st.swap_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:
|
if 'agents' in payload:
|
||||||
st.agents_json = json.dumps(payload.get('agents') or [], ensure_ascii=False)
|
st.agents_json = json.dumps(payload.get('agents') or [], ensure_ascii=False)
|
||||||
|
|
||||||
|
|||||||
@@ -220,6 +220,10 @@ def _migrate_schema():
|
|||||||
db.execute(text("ALTER TABLE monitored_servers ADD COLUMN api_key VARCHAR(64) NULL"))
|
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)"))
|
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()
|
db.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class ServerState(Base):
|
|||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
server_id = Column(Integer, ForeignKey('monitored_servers.id'), nullable=False, unique=True)
|
server_id = Column(Integer, ForeignKey('monitored_servers.id'), nullable=False, unique=True)
|
||||||
openclaw_version = Column(String(64), nullable=True)
|
openclaw_version = Column(String(64), nullable=True)
|
||||||
|
plugin_version = Column(String(64), nullable=True)
|
||||||
agents_json = Column(Text, nullable=True) # json list
|
agents_json = Column(Text, nullable=True) # json list
|
||||||
cpu_pct = Column(Float, nullable=True)
|
cpu_pct = Column(Float, nullable=True)
|
||||||
mem_pct = Column(Float, nullable=True)
|
mem_pct = Column(Float, nullable=True)
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ def get_server_states_view(db: Session, offline_after_minutes: int = 7):
|
|||||||
'display_name': s.display_name or s.identifier,
|
'display_name': s.display_name or s.identifier,
|
||||||
'online': online,
|
'online': online,
|
||||||
'openclaw_version': st.openclaw_version if st else None,
|
'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,
|
'cpu_pct': st.cpu_pct if st else None,
|
||||||
'mem_pct': st.mem_pct if st else None,
|
'mem_pct': st.mem_pct if st else None,
|
||||||
'disk_pct': st.disk_pct if st else None,
|
'disk_pct': st.disk_pct if st else None,
|
||||||
|
|||||||
Reference in New Issue
Block a user