From 204c0c88104ce130bdeabfd73c735b7ef33e2f57 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Mon, 17 Apr 2023 23:12:04 +0300 Subject: only send one report --- state.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 16 deletions(-) (limited to 'state.go') diff --git a/state.go b/state.go index d2be1c0..25d0ca3 100644 --- a/state.go +++ b/state.go @@ -6,19 +6,27 @@ import ( "io/ioutil" "log" "os" + "strings" "sync" ) +type checkState struct { + status int + prevStatus int + output string +} + type state struct { stateFile string - Checks map[string]int - mutex sync.Mutex + checks map[string]checkState + mutex *sync.Mutex } func newState(config config) (state, error) { s := state{ stateFile: fmt.Sprintf("%s/state.json", config.StateDir), - Checks: make(map[string]int), + checks: make(map[string]checkState), + mutex: &sync.Mutex{}, } if _, err := os.Stat(s.stateFile); err != nil { @@ -39,51 +47,105 @@ func newState(config config) (state, error) { } // Parse the JSON content - if err := json.Unmarshal(bytes, &s.Checks); err != nil { + if err := json.Unmarshal(bytes, &s.checks); err != nil { return s, err } // Clean up obsolete state information var obsolete []string - for name := range s.Checks { + for name := range s.checks { if _, ok := config.Checks[name]; !ok { obsolete = append(obsolete, name) } } for _, name := range obsolete { - delete(s.Checks, name) + delete(s.checks, name) log.Printf("State of %s is obsolete (removed)", name) } return s, nil } -func (s state) update(name string, status int) bool { +func (s state) update(name, output string, status int) { s.mutex.Lock() defer s.mutex.Unlock() - oldStatus, ok := s.Checks[name] + prevState, ok := s.checks[name] if !ok { log.Printf("State of %s: %d (new)", name, status) - s.Checks[name] = status - return true + s.checks[name] = checkState{status, unknown, output} + return } - if oldStatus != status { - log.Printf("State of %s: %d -> %d (changed)", name, oldStatus, status) - s.Checks[name] = status - return true + if prevState.status != status { + log.Printf("State of %s: %d -> %d (changed)", name, prevState, status) + s.checks[name] = checkState{status, prevState.status, output} + return } log.Printf("State of %s: %d (unchanged)", name, status) - return false + s.checks[name] = checkState{status, prevState.status, output} } func (s state) persist() error { - jsonData, err := json.Marshal(s.Checks) + jsonData, err := json.Marshal(s.checks) if err != nil { return err } return ioutil.WriteFile(s.stateFile, jsonData, os.ModePerm) } + +func (s state) report() (string, string, bool) { + var sb strings.Builder + var changed bool + + f := func(filter func(i int) bool) int { + var count int + for name, checkState := range s.checks { + if filter(checkState.status) { + count++ + if checkState.status != checkState.prevStatus { + sb.WriteString(codeToString(checkState.prevStatus)) + sb.WriteString("->") + changed = true + } + sb.WriteString(codeToString(checkState.status)) + sb.WriteString(": ") + sb.WriteString(name) + sb.WriteString(" ==>> ") + sb.WriteString(checkState.output) + sb.WriteString("\n") + } + } + return count + } + + sb.WriteString("This is the recent Googios report!\n\n") + + numCriticals := f(func(i int) bool { return i == 2 }) + if numCriticals > 0 { + sb.WriteString("\n") + } + + numWarnings := f(func(i int) bool { return i == 1 }) + if numWarnings > 0 { + sb.WriteString("\n") + } + + numUnknowns := f(func(i int) bool { return i > 2 }) + if numUnknowns > 0 { + sb.WriteString("\n") + } + + numOks := f(func(i int) bool { return i == 0 }) + if numOks > 0 { + sb.WriteString("\n") + } + + sb.WriteString("Have a nice day!\n") + subject := fmt.Sprintf("GOGIOS Report [C:%d W:%d U:%d OK:%d]", + numCriticals, numWarnings, numUnknowns, numOks) + + return subject, sb.String(), changed +} -- cgit v1.2.3