statsys/src/statuses.go

82 lines
1.9 KiB
Go

package main
import (
"log"
"net/http"
"sync"
"time"
)
var client = http.Client{
Timeout: 10 * time.Second,
}
func checkStatuses() {
var wg sync.WaitGroup
for index, service := range templateData.Services {
wg.Add(1)
// run in parallel
go func(index int, service Service) {
defer wg.Done()
log.Println("(" + service.Name + ") sending request to " + service.Url)
startTime := time.Now().UTC()
res, err := client.Get(service.Url)
latency := time.Since(startTime).Milliseconds()
status := "Online"
if err != nil || res.StatusCode != 200 {
status = "Offline"
} else if latency >= service.LatencyThreshold {
status = "Degraded"
}
log.Printf("(%s) status is %s (latency: %dms)", service.Name, status, latency)
AddToTimeline(index, status)
rawTimeline := GetRawTimeline(service)
// check if status has changed from last request
if len(rawTimeline) == 0 || rawTimeline[len(rawTimeline)-1].Status != status {
if status == "Offline" || status == "Degraded" {
AddIncident(index, status, startTime)
} else if len(service.Incidents) != 0 && service.Incidents[len(service.Incidents)-1].EndTime == nil {
// if status is Online and there was an ongoing incident
ResolveIncident(index, service.Name, startTime) // startTime is actually finishTime
}
}
templateData.Services[index].Status = status
}(index, service)
}
// wait for all status checks to complete
wg.Wait()
// check if all services are operational
isOperational := true
for _, service := range templateData.Services {
if service.Status == "Offline" || service.Status == "Degraded" {
isOperational = false
break
}
}
templateData.IsOperational = isOperational
templateData.LastUpdated = time.Now().UTC().UnixMilli()
}
func StartCheckingStatuses() {
log.Println("started checking statuses...")
go func() {
checkStatuses()
for range time.Tick(1 * time.Minute) {
checkStatuses()
}
}()
}