sermoni

"Service monitor" / cronjob status service
Log | Files | Refs

commit 405158aecf35441493944cfcdb62b4d2765c6c48
parent a1b412c80ef2e6f3b00c6ac9fd45b9b1fa175d95
Author: Vetle Haflan <vetle@haflan.dev>
Date:   Thu, 30 Apr 2020 15:44:21 +0200

Unmet expectation / 'late' event generation MVP

Diffstat:
Minternal/http/events.go | 51++++++++++++++++++++++++++++++++++++++++-----------
Mui/src/Events.vue | 13+++++++------
2 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/internal/http/events.go b/internal/http/events.go @@ -16,22 +16,38 @@ import ( const headerServiceToken = "Service-Token" +func now() uint64 { + return uint64(time.Now().UnixNano() / 1e6) +} + +// getEvents fetches all events in the database and checks timestamp for the last report +// from each service. If the time since last report is more than the expected report interval, +// a "live" event is generated to inform that no report has been received func getEvents(w http.ResponseWriter, r *http.Request) { - // Create a mapping from service id to name - /* Eventually? - serviceIdName := make(map[int]string) - services := services.GetAll() - for _, service := range { - serviceIdName[service.ID] = service.Name + // Create mappings from service id to the actual service and to the last service report + serviceIDMap := make(map[uint64]*services.Service) + serviceIsLate := make(map[uint64]bool) + servs := services.GetAll() + for _, service := range servs { + serviceIDMap[service.ID] = service + serviceIsLate[service.ID] = service.ExpectationPeriod != 0 } - */ - events := events.GetAll() var s *services.Service + events := events.GetAll() for _, e := range events { - // Could optimize by writing a single db.View, but this is more readable, so meh.. - s = services.GetByID(e.Service) + sid := e.Service + s = serviceIDMap[sid] e.ServiceName = s.Name + if serviceIsLate[sid] && now()-e.Timestamp < s.ExpectationPeriod { + serviceIsLate[sid] = false + } + } + for sid, late := range serviceIsLate { + if late { + s := serviceIDMap[sid] + events = append(events, generateLateEvent(s)) + } } b, _ := json.Marshal(events) w.Write(b) @@ -70,7 +86,7 @@ func reportEvent(w http.ResponseWriter, r *http.Request) { err = json.Unmarshal(content, event) check(err) event.Service = service.ID - event.Timestamp = uint64(time.Now().UnixNano() / 1e6) + event.Timestamp = now() err = events.Add(event) check(err) log.Printf("New event registered, id = %v\n", event.ID) @@ -95,6 +111,19 @@ func reportEvent(w http.ResponseWriter, r *http.Request) { } } +func generateLateEvent(s *services.Service) *events.Event { + return &events.Event{ + ID: 0, + Service: s.ID, + Timestamp: now(), + Status: "late", + Title: "Expectation not met", + Details: s.Name + " has failed to report within the expected internal." + + "Something is probably wrong.", + ServiceName: s.Name, + } +} + // For later reference: // Instead of anonymous structs for each JSON object to be written, // a simple map can be used instead, something like (untested!): diff --git a/ui/src/Events.vue b/ui/src/Events.vue @@ -9,7 +9,7 @@ <!--<mq-layout mq="md+">--> <div class="event-field">{{ e.title }}</div> <!--</mq-layout>--> - <button @click="deleteEvent(e.id)">&times;</button> + <button v-show="e.id" @click="deleteEvent(e.id)">&times;</button> </div> <div v-show="false"> more info here </div> </div> @@ -24,10 +24,11 @@ return { loadedEvents: [], statusStyling: { - "ok": { color: "#000", backgroundColor: "#c3e6cb" }, - "warning": { color: "#000", backgroundColor: "#ffeeba" }, - "error": { color: "#000", backgroundColor: "#f5c6cb" }, - "info": { color: "#000", backgroundColor: "#fff" } + "ok": { color: "black", backgroundColor: "#c3e6cb" }, + "warning": { color: "black", backgroundColor: "#ffeeba" }, + "error": { color: "black", backgroundColor: "#f5c6cb" }, + "info": { color: "black", backgroundColor: "#fff" }, + "late":{ color: "black", backgroundColor: "#d6d8d9" }, } }; }, @@ -67,7 +68,7 @@ mounted() { api.getEvents( successData => { - this.loadedEvents = successData; + this.loadedEvents = successData.reverse(); }, error => { console.error(error);