feat: add agentmon services section to infrastructure page
Label all agentmon docker-compose services with agentmon.monitor=true and agentmon.group=agentmon so the swarm-monitor picks them up. Adds Group field to ServiceSnapshot, probes /healthz for api/web roles, and renders a separate "Agentmon" section below Swarm Services on the Infrastructure page with new api and worker card renderers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -218,6 +218,19 @@ func main() {
|
||||
httpx.WriteJSON(w, http.StatusOK, summary)
|
||||
})
|
||||
|
||||
r.Get("/v1/stats/top-tools", func(w http.ResponseWriter, r *http.Request) {
|
||||
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
|
||||
tools, err := db.GetTopTools(r.Context(), limit)
|
||||
if err != nil {
|
||||
httpx.WriteJSON(w, http.StatusInternalServerError, map[string]any{"error": "db_error"})
|
||||
return
|
||||
}
|
||||
if tools == nil {
|
||||
tools = []postgres.TopTool{}
|
||||
}
|
||||
httpx.WriteJSON(w, http.StatusOK, map[string]any{"tools": tools})
|
||||
})
|
||||
|
||||
r.Get("/v1/stats/timeseries", func(w http.ResponseWriter, r *http.Request) {
|
||||
window := r.URL.Query().Get("window")
|
||||
switch window {
|
||||
|
||||
@@ -751,7 +751,9 @@
|
||||
|
||||
function renderInfraGrid() {
|
||||
const vmNames = Object.keys(openclawState.instances).sort();
|
||||
const services = Object.values(swarmState.services);
|
||||
const allServices = Object.values(swarmState.services);
|
||||
const agentmonServices = allServices.filter(s => s.group === 'agentmon');
|
||||
const swarmServices = allServices.filter(s => s.group !== 'agentmon');
|
||||
|
||||
app.innerHTML = `
|
||||
<div class="page-header">
|
||||
@@ -767,10 +769,18 @@
|
||||
</div>
|
||||
|
||||
<div class="infra-section">
|
||||
<p class="infra-section-title">Services</p>
|
||||
${services.length === 0
|
||||
<p class="infra-section-title">Swarm Services</p>
|
||||
${swarmServices.length === 0
|
||||
? '<p class="empty-state">No swarm service data</p>'
|
||||
: `<div class="service-grid">${services.map(svc => renderServiceCard(svc)).join('')}</div>`
|
||||
: `<div class="service-grid">${swarmServices.map(svc => renderServiceCard(svc)).join('')}</div>`
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="infra-section">
|
||||
<p class="infra-section-title">Agentmon</p>
|
||||
${agentmonServices.length === 0
|
||||
? '<p class="empty-state">No agentmon service data</p>'
|
||||
: `<div class="service-grid">${agentmonServices.map(svc => renderServiceCard(svc)).join('')}</div>`
|
||||
}
|
||||
</div>
|
||||
`;
|
||||
@@ -835,6 +845,10 @@
|
||||
case 'mcp': return renderMCPCard(svc);
|
||||
case 'voice': return renderVoiceCard(svc);
|
||||
case 'automation':return renderAutomationCard(svc);
|
||||
case 'api':
|
||||
case 'web': return renderAPICard(svc);
|
||||
case 'worker':
|
||||
case 'queue': return renderWorkerCard(svc);
|
||||
default: return renderGenericServiceCard(svc);
|
||||
}
|
||||
}
|
||||
@@ -966,6 +980,33 @@
|
||||
`;
|
||||
}
|
||||
|
||||
function renderAPICard(svc) {
|
||||
const httpStatus = svc.http_status;
|
||||
const httpClass = httpStatus === 200 ? 'ok' : httpStatus ? 'bad' : '';
|
||||
return `
|
||||
<div class="service-card">
|
||||
${serviceCardHeader(svc)}
|
||||
<div class="service-stats">
|
||||
${serviceStatRow('HTTP', httpStatus ? String(httpStatus) : '-', httpClass)}
|
||||
${serviceStatRow('Uptime', formatUptime(svc.uptime_sec), '')}
|
||||
${serviceStatRow('Container', escapeHTML(svc.container_state || '-'), svc.container_state === 'running' ? 'ok' : 'bad')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderWorkerCard(svc) {
|
||||
return `
|
||||
<div class="service-card">
|
||||
${serviceCardHeader(svc)}
|
||||
<div class="service-stats">
|
||||
${serviceStatRow('Container', escapeHTML(svc.container_state || '-'), svc.container_state === 'running' ? 'ok' : 'bad')}
|
||||
${serviceStatRow('Uptime', formatUptime(svc.uptime_sec), '')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderGenericServiceCard(svc) {
|
||||
return `
|
||||
<div class="service-card">
|
||||
|
||||
Reference in New Issue
Block a user