v1.27.0-a #10
@ -5,6 +5,7 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -107,10 +108,18 @@ func (a *app) executeTemplate(w http.ResponseWriter, name string, data interface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type machineRecentTask struct {
|
||||||
|
TaskName string
|
||||||
|
Success int64
|
||||||
|
Fail int64
|
||||||
|
}
|
||||||
|
|
||||||
type machineSummary struct {
|
type machineSummary struct {
|
||||||
Address string
|
Address string
|
||||||
ID int64
|
ID int64
|
||||||
SinceContact string
|
SinceContact string
|
||||||
|
|
||||||
|
RecentTasks []*machineRecentTask
|
||||||
}
|
}
|
||||||
|
|
||||||
type taskSummary struct {
|
type taskSummary struct {
|
||||||
@ -133,7 +142,47 @@ type taskHistorySummary struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *app) clusterMachineSummary(ctx context.Context) ([]machineSummary, error) {
|
func (a *app) clusterMachineSummary(ctx context.Context) ([]machineSummary, error) {
|
||||||
rows, err := a.db.Query(ctx, "SELECT id, host_and_port, last_contact FROM harmony_machines")
|
// First get task summary for tasks completed in the last 24 hours
|
||||||
|
// NOTE: This query uses harmony_task_history_work_index, task history may get big
|
||||||
|
tsrows, err := a.db.Query(ctx, `SELECT hist.completed_by_host_and_port, hist.name, hist.result, count(1) FROM harmony_task_history hist
|
||||||
|
WHERE hist.work_end > now() - INTERVAL '1 day'
|
||||||
|
GROUP BY hist.completed_by_host_and_port, hist.name, hist.result
|
||||||
|
ORDER BY completed_by_host_and_port ASC`)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer tsrows.Close()
|
||||||
|
|
||||||
|
// Map of machine -> task -> recent task
|
||||||
|
taskSummaries := map[string]map[string]*machineRecentTask{}
|
||||||
|
|
||||||
|
for tsrows.Next() {
|
||||||
|
var taskName string
|
||||||
|
var result bool
|
||||||
|
var count int64
|
||||||
|
var machine string
|
||||||
|
|
||||||
|
if err := tsrows.Scan(&machine, &taskName, &result, &count); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := taskSummaries[machine]; !ok {
|
||||||
|
taskSummaries[machine] = map[string]*machineRecentTask{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := taskSummaries[machine][taskName]; !ok {
|
||||||
|
taskSummaries[machine][taskName] = &machineRecentTask{TaskName: taskName}
|
||||||
|
}
|
||||||
|
|
||||||
|
if result {
|
||||||
|
taskSummaries[machine][taskName].Success = count
|
||||||
|
} else {
|
||||||
|
taskSummaries[machine][taskName].Fail = count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then machine summary
|
||||||
|
rows, err := a.db.Query(ctx, "SELECT id, host_and_port, last_contact FROM harmony_machines order by host_and_port asc")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err // Handle error
|
return nil, err // Handle error
|
||||||
}
|
}
|
||||||
@ -150,6 +199,16 @@ func (a *app) clusterMachineSummary(ctx context.Context) ([]machineSummary, erro
|
|||||||
|
|
||||||
m.SinceContact = time.Since(lastContact).Round(time.Second).String()
|
m.SinceContact = time.Since(lastContact).Round(time.Second).String()
|
||||||
|
|
||||||
|
// Add recent tasks
|
||||||
|
if ts, ok := taskSummaries[m.Address]; ok {
|
||||||
|
for _, t := range ts {
|
||||||
|
m.RecentTasks = append(m.RecentTasks, t)
|
||||||
|
}
|
||||||
|
sort.Slice(m.RecentTasks, func(i, j int) bool {
|
||||||
|
return m.RecentTasks[i].TaskName < m.RecentTasks[j].TaskName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
summaries = append(summaries, m)
|
summaries = append(summaries, m)
|
||||||
}
|
}
|
||||||
return summaries, nil
|
return summaries, nil
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{.Address}}</td>
|
<td>{{.Address}}</td>
|
||||||
<td>{{.ID}}</td>
|
<td>{{.ID}}</td>
|
||||||
<td>todo</td>
|
|
||||||
<td>{{.SinceContact}}</td>
|
<td>{{.SinceContact}}</td>
|
||||||
|
{{range .RecentTasks}}
|
||||||
|
<td>{{.TaskName}}:{{.Success}}{{if ne 0 .Fail}}(<i class="{{if eq 0 .Success}}error{{else}}warning{{end}}">{{.Fail}}</i>){{end}}</td>
|
||||||
|
{{end}}
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -59,7 +59,6 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Host</th>
|
<th>Host</th>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Config Layers</th>
|
|
||||||
<th>Last Contact</th>
|
<th>Last Contact</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
3
lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql
Normal file
3
lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/* Used for webui clusterMachineSummary */
|
||||||
|
CREATE INDEX harmony_task_history_work_index
|
||||||
|
ON harmony_task_history (completed_by_host_and_port ASC, name ASC, result ASC, work_end DESC);
|
Loading…
Reference in New Issue
Block a user