feat(dashboard): métriques chargées immédiatement au rechargement de page
GET /api/agents inclut désormais last_metrics (dernière ligne de la table metrics) pour chaque agent. grid.js l'utilise lors du refresh initial, ce qui peuple les tuiles sans attendre le prochain message WebSocket. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
f69c22039b
commit
d8f395cb53
@@ -124,7 +124,7 @@ const Grid = (() => {
|
|||||||
function refresh(agents) {
|
function refresh(agents) {
|
||||||
agents.forEach(a => {
|
agents.forEach(a => {
|
||||||
if (!_agents.has(a.id)) {
|
if (!_agents.has(a.id)) {
|
||||||
_agents.set(a.id, { agent: a, metrics: null });
|
_agents.set(a.id, { agent: a, metrics: a.last_metrics || null });
|
||||||
} else {
|
} else {
|
||||||
_agents.get(a.id).agent = a;
|
_agents.get(a.id).agent = a;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,53 @@ func (d *DB) GetAgents() ([]models.Agent, error) {
|
|||||||
return agents, nil
|
return agents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DB) GetLastMetrics(agentID string) (*models.AgentMetrics, error) {
|
||||||
|
var cpu, temperature *float64
|
||||||
|
var memUsed, memFree, memTotal, hddUsed, hddFree, hddTotal *int64
|
||||||
|
var uptime, netRX, netTX *int64
|
||||||
|
var smartPassed, smartTemp, smartRealloc, smartHours, smartWear *int64
|
||||||
|
|
||||||
|
err := d.conn.QueryRow(`
|
||||||
|
SELECT cpu_percent, memory_used, memory_free, memory_total,
|
||||||
|
hdd_used, hdd_free, hdd_total,
|
||||||
|
uptime, network_rx, network_tx, temperature,
|
||||||
|
smart_passed, smart_temp, smart_realloc, smart_hours, smart_wear
|
||||||
|
FROM metrics WHERE agent_id = ? ORDER BY ts DESC LIMIT 1`, agentID).
|
||||||
|
Scan(&cpu, &memUsed, &memFree, &memTotal,
|
||||||
|
&hddUsed, &hddFree, &hddTotal,
|
||||||
|
&uptime, &netRX, &netTX, &temperature,
|
||||||
|
&smartPassed, &smartTemp, &smartRealloc, &smartHours, &smartWear)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m := &models.AgentMetrics{
|
||||||
|
CPUPercent: cpu,
|
||||||
|
MemoryUsed: memUsed,
|
||||||
|
MemoryFree: memFree,
|
||||||
|
MemoryTotal: memTotal,
|
||||||
|
HDDUsed: hddUsed,
|
||||||
|
HDDFree: hddFree,
|
||||||
|
HDDTotal: hddTotal,
|
||||||
|
Uptime: uptime,
|
||||||
|
NetworkRX: netRX,
|
||||||
|
NetworkTX: netTX,
|
||||||
|
Temperature: temperature,
|
||||||
|
}
|
||||||
|
if smartPassed != nil {
|
||||||
|
m.Smart = &models.SmartMetrics{
|
||||||
|
Passed: *smartPassed == 1,
|
||||||
|
Temperature: smartTemp,
|
||||||
|
ReallocatedSectors: smartRealloc,
|
||||||
|
PowerOnHours: smartHours,
|
||||||
|
WearLevel: smartWear,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *DB) GetMetricsHistory(agentID string, from, to int64) ([]map[string]interface{}, error) {
|
func (d *DB) GetMetricsHistory(agentID string, from, to int64) ([]map[string]interface{}, error) {
|
||||||
rows, err := d.conn.Query(`
|
rows, err := d.conn.Query(`
|
||||||
SELECT ts, cpu_percent, memory_used, memory_total, hdd_used, hdd_total
|
SELECT ts, cpu_percent, memory_used, memory_total, hdd_used, hdd_total
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ func AgentsHandler(database *db.DB) http.HandlerFunc {
|
|||||||
http.Error(w, err.Error(), 500)
|
http.Error(w, err.Error(), 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
for i := range agents {
|
||||||
|
agents[i].LastMetrics, _ = database.GetLastMetrics(agents[i].ID)
|
||||||
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(agents)
|
json.NewEncoder(w).Encode(agents)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user