diff --git a/curiosrc/web/hapi/simpleinfo.go b/curiosrc/web/hapi/simpleinfo.go index e639ef427..319db88e0 100644 --- a/curiosrc/web/hapi/simpleinfo.go +++ b/curiosrc/web/hapi/simpleinfo.go @@ -5,6 +5,7 @@ import ( "html/template" "net/http" "os" + "sort" "sync" "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 { Address string ID int64 SinceContact string + + RecentTasks []*machineRecentTask } type taskSummary struct { @@ -133,7 +142,47 @@ type taskHistorySummary struct { } 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 { 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() + // 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) } return summaries, nil diff --git a/curiosrc/web/hapi/web/cluster_machines.gohtml b/curiosrc/web/hapi/web/cluster_machines.gohtml index f94f53bf8..b253a0561 100644 --- a/curiosrc/web/hapi/web/cluster_machines.gohtml +++ b/curiosrc/web/hapi/web/cluster_machines.gohtml @@ -3,8 +3,10 @@ {{.Address}} {{.ID}} - todo {{.SinceContact}} + {{range .RecentTasks}} + {{.TaskName}}:{{.Success}}{{if ne 0 .Fail}}({{.Fail}}){{end}} + {{end}} {{end}} {{end}} diff --git a/curiosrc/web/static/index.html b/curiosrc/web/static/index.html index 4f9c21b50..f2f1c087c 100644 --- a/curiosrc/web/static/index.html +++ b/curiosrc/web/static/index.html @@ -59,7 +59,6 @@ Host ID - Config Layers Last Contact diff --git a/lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql b/lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql new file mode 100644 index 000000000..a5f907778 --- /dev/null +++ b/lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql @@ -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);