From f34e1a7a1f7bf00038baf69873111ba1ea581ac1 Mon Sep 17 00:00:00 2001 From: Joshua Smith Date: Mon, 24 Nov 2025 13:06:30 -0700 Subject: [PATCH] alert-fix for reoccuring alerts for unfinished tasks --- apps/flowlord/handler.go | 4 ++-- apps/flowlord/sqlite/alerts.go | 2 -- apps/flowlord/sqlite/dates.go | 1 + apps/flowlord/sqlite/dbstats.go | 2 -- apps/flowlord/sqlite/files.go | 1 + apps/flowlord/sqlite/sqlite.go | 1 + apps/flowlord/sqlite/sqlite_test.go | 9 +++++---- apps/flowlord/sqlite/stats.go | 14 +++++++------- apps/flowlord/sqlite/tasks.go | 9 +++------ apps/flowlord/sqlite/workflow.go | 2 +- apps/flowlord/sqlite/workflow_test.go | 3 +-- 11 files changed, 22 insertions(+), 26 deletions(-) diff --git a/apps/flowlord/handler.go b/apps/flowlord/handler.go index 85ad3c9..605b020 100644 --- a/apps/flowlord/handler.go +++ b/apps/flowlord/handler.go @@ -436,7 +436,7 @@ func (tm *taskMaster) htmlTask(w http.ResponseWriter, r *http.Request) { // Get task summary statistics for the date summaryStart := time.Now() - taskStats, err := tm.taskCache.GetTaskSummaryByDate(dt) + taskStats, err := tm.taskCache.GetTaskRecapByDate(dt) summaryTime := time.Since(summaryStart) if err != nil { log.Printf("Error getting task summary: %v", err) @@ -825,7 +825,7 @@ func (tm *taskMaster) backload(req request) response { start = at end = at } - + phase := tm.taskCache.Search(req.Task, req.Job) if phase.FilePath != "" { msg = append(msg, "phase found in "+phase.FilePath) diff --git a/apps/flowlord/sqlite/alerts.go b/apps/flowlord/sqlite/alerts.go index f24f675..8336f33 100644 --- a/apps/flowlord/sqlite/alerts.go +++ b/apps/flowlord/sqlite/alerts.go @@ -180,5 +180,3 @@ func BuildCompactSummary(alerts []AlertRecord) []SummaryLine { return result } - - diff --git a/apps/flowlord/sqlite/dates.go b/apps/flowlord/sqlite/dates.go index acdf3f2..6c413a5 100644 --- a/apps/flowlord/sqlite/dates.go +++ b/apps/flowlord/sqlite/dates.go @@ -224,3 +224,4 @@ func (s *SQLite) RebuildDateIndex() error { } + diff --git a/apps/flowlord/sqlite/dbstats.go b/apps/flowlord/sqlite/dbstats.go index 73fbfc7..9278b4e 100644 --- a/apps/flowlord/sqlite/dbstats.go +++ b/apps/flowlord/sqlite/dbstats.go @@ -188,5 +188,3 @@ func formatBytes(bytes int64) string { } return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp]) } - - diff --git a/apps/flowlord/sqlite/files.go b/apps/flowlord/sqlite/files.go index d48344b..b61a6e1 100644 --- a/apps/flowlord/sqlite/files.go +++ b/apps/flowlord/sqlite/files.go @@ -230,3 +230,4 @@ func (s *SQLite) GetFileMessagesWithTasks(limit int, offset int) ([]FileMessageW } + diff --git a/apps/flowlord/sqlite/sqlite.go b/apps/flowlord/sqlite/sqlite.go index 73450e1..daec295 100644 --- a/apps/flowlord/sqlite/sqlite.go +++ b/apps/flowlord/sqlite/sqlite.go @@ -268,3 +268,4 @@ func (o *SQLite) Sync() error { } + diff --git a/apps/flowlord/sqlite/sqlite_test.go b/apps/flowlord/sqlite/sqlite_test.go index aeddce6..47a5a2d 100644 --- a/apps/flowlord/sqlite/sqlite_test.go +++ b/apps/flowlord/sqlite/sqlite_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/pcelvng/task" + "github.com/pcelvng/task-tools/file/stat" ) @@ -40,15 +41,15 @@ func TestDatesByType(t *testing.T) { VALUES (?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?) `, "alert1", "2024-01-15T11:00:00Z", "data-validation", "check", "Validation error", "2024-01-15T11:00:00Z", - "alert2", "2024-01-17T11:00:00Z", "data-validation", "check", "Validation error", "2024-01-17T11:00:00Z") + "alert2", "2024-01-17T11:00:00Z", "data-validation", "check", "Validation error", "2024-01-17T11:00:00Z") if err != nil { t.Fatalf("Failed to insert alerts: %v", err) } // Add sample file messages fileMsg1 := stat.Stats{ - Path: "gs://bucket/file1.json", - Size: 1024, + Path: "gs://bucket/file1.json", + Size: 1024, } db.AddFileMessage(fileMsg1, []string{}, []string{}) @@ -109,4 +110,4 @@ func TestDatesByType(t *testing.T) { if len(fileDates2) != len(fileDates) { t.Error("GetDatesWithFiles() should return same results as DatesByType('files')") } -} \ No newline at end of file +} diff --git a/apps/flowlord/sqlite/stats.go b/apps/flowlord/sqlite/stats.go index 8c69656..f372c50 100644 --- a/apps/flowlord/sqlite/stats.go +++ b/apps/flowlord/sqlite/stats.go @@ -113,7 +113,7 @@ func (s *DurationStats) String() string { func (stats *Stats) Add(tsk task.Task) { tm := tmpl.TaskTime(tsk) - + // Handle different result types switch tsk.Result { case task.ErrResult: @@ -180,7 +180,7 @@ func (ts TaskStats) UniqueTypes() []string { typeSet[key] = struct{}{} } } - + types := make([]string, 0, len(typeSet)) for t := range typeSet { types = append(types, t) @@ -192,7 +192,7 @@ func (ts TaskStats) UniqueTypes() []string { // JobsByType returns jobs organized by type func (ts TaskStats) JobsByType() map[string][]string { jobsByType := make(map[string][]string) - + for key := range ts { // Split key into type and job parts := strings.SplitN(key, ":", 2) @@ -204,19 +204,19 @@ func (ts TaskStats) JobsByType() map[string][]string { } } } - + // Sort jobs for each type for typ := range jobsByType { sort.Strings(jobsByType[typ]) } - + return jobsByType } // TotalCounts returns aggregate result counts across all tasks func (ts TaskStats) TotalCounts() TaskCounts { var counts TaskCounts - + for _, stats := range ts { counts.Total += stats.CompletedCount + stats.ErrorCount + stats.AlertCount + stats.WarnCount + stats.RunningCount counts.Completed += stats.CompletedCount @@ -225,6 +225,6 @@ func (ts TaskStats) TotalCounts() TaskCounts { counts.Warn += stats.WarnCount counts.Running += stats.RunningCount } - + return counts } diff --git a/apps/flowlord/sqlite/tasks.go b/apps/flowlord/sqlite/tasks.go index 2fe43f2..beba2c5 100644 --- a/apps/flowlord/sqlite/tasks.go +++ b/apps/flowlord/sqlite/tasks.go @@ -209,8 +209,7 @@ func (s *SQLite) CheckIncompleteTasks() int { tr.id = ar.task_id AND tr.type = ar.task_type AND tr.job = ar.job AND - ar.msg LIKE 'INCOMPLETE:%' AND - ar.created_at > datetime('now', '-1 day') + ar.msg LIKE 'INCOMPLETE:%' ) WHERE tr.created < ? AND tr.result = '' @@ -400,8 +399,8 @@ func (s *SQLite) GetTasksByDate(date time.Time, filter *TaskFilter) ([]TaskView, return tasks, totalCount, nil } -// GetTaskSummaryByDate creates a summary of tasks for a specific date -func (s *SQLite) GetTaskSummaryByDate(date time.Time) (TaskStats, error) { +// GetTaskRecapByDate creates a recap of tasks for a specific date +func (s *SQLite) GetTaskRecapByDate(date time.Time) (TaskStats, error) { s.mu.Lock() defer s.mu.Unlock() @@ -463,5 +462,3 @@ func extractJobFromTask(t task.Task) string { } return job } - - diff --git a/apps/flowlord/sqlite/workflow.go b/apps/flowlord/sqlite/workflow.go index 1423028..2cc5b9e 100644 --- a/apps/flowlord/sqlite/workflow.go +++ b/apps/flowlord/sqlite/workflow.go @@ -90,7 +90,7 @@ func (s *SQLite) IsDir() bool { // Search the all workflows within the cache and return the first // matching phase with the specific task and job (optional) func (s *SQLite) Search(taskType, job string) PhaseDB { - return s.Get(task.Task{Type: taskType, Job: job}) + return s.Get(task.Task{Type: taskType, Job: job}) } // Get the Phase associated with the task diff --git a/apps/flowlord/sqlite/workflow_test.go b/apps/flowlord/sqlite/workflow_test.go index 0ff290b..c03eb0b 100644 --- a/apps/flowlord/sqlite/workflow_test.go +++ b/apps/flowlord/sqlite/workflow_test.go @@ -78,8 +78,7 @@ func TestValidatePhase(t *testing.T) { "cron 6": { Input: Phase{Rule: "cron=1 2 3 4 5 6"}, }, - "cron complex": - { + "cron complex": { Input: Phase{Rule: "cron=20 */6 * * SUN"}, }, "parse_err": {