zdravko/internal/handlers/index.go

145 lines
3.3 KiB
Go
Raw Normal View History

package handlers
import (
2024-02-22 16:29:17 +00:00
"context"
"net/http"
2024-02-22 16:29:17 +00:00
"time"
2024-02-27 11:04:05 +00:00
"code.tjo.space/mentos1386/zdravko/database/models"
2024-02-22 16:29:17 +00:00
"code.tjo.space/mentos1386/zdravko/internal/services"
"code.tjo.space/mentos1386/zdravko/web/templates/components"
"github.com/labstack/echo/v4"
)
type IndexData struct {
*components.Base
2024-03-03 14:28:25 +00:00
Monitors map[string][]*Monitor
MonitorsLength int
2024-02-27 11:04:05 +00:00
TimeRange string
2024-02-29 22:42:56 +00:00
Status models.MonitorStatus
}
2024-03-03 14:28:25 +00:00
type Monitor struct {
2024-02-29 22:42:56 +00:00
Name string
2024-03-03 14:28:25 +00:00
Group string
2024-02-29 22:42:56 +00:00
Status models.MonitorStatus
History *History
}
2024-02-22 16:29:17 +00:00
type History struct {
2024-02-29 22:42:56 +00:00
List []models.MonitorStatus
Uptime int
2024-02-22 16:29:17 +00:00
}
func getHour(date time.Time) string {
2024-02-29 22:57:23 +00:00
return date.UTC().Format("2006-01-02T15:04:05")
2024-02-22 16:29:17 +00:00
}
2024-02-29 22:42:56 +00:00
func getHistory(history []*models.MonitorHistory, period time.Duration, buckets int) *History {
historyMap := map[string]models.MonitorStatus{}
2024-02-22 16:29:17 +00:00
numOfSuccess := 0
2024-02-22 19:20:34 +00:00
numTotal := 0
2024-02-22 16:29:17 +00:00
2024-02-29 22:42:56 +00:00
for i := 0; i < buckets; i++ {
datetime := getHour(time.Now().Add(period * time.Duration(-i)).Truncate(period))
historyMap[datetime] = models.MonitorUnknown
2024-02-22 16:29:17 +00:00
}
for _, _history := range history {
2024-02-29 22:57:23 +00:00
hour := getHour(_history.CreatedAt.Time.Truncate(period))
2024-02-22 16:29:17 +00:00
2024-02-29 22:42:56 +00:00
// Skip if not part of the "buckets"
if _, ok := historyMap[hour]; !ok {
2024-02-22 16:29:17 +00:00
continue
}
numTotal++
if _history.Status == models.MonitorSuccess {
2024-02-22 16:29:17 +00:00
numOfSuccess++
}
2024-02-29 22:42:56 +00:00
// skip if it is already set to failure
if historyMap[hour] == models.MonitorFailure {
2024-02-22 16:29:17 +00:00
continue
}
2024-02-29 22:42:56 +00:00
historyMap[hour] = _history.Status
2024-02-22 16:29:17 +00:00
}
2024-02-29 22:42:56 +00:00
historyHourly := make([]models.MonitorStatus, buckets)
for i := 0; i < buckets; i++ {
datetime := getHour(time.Now().Add(period * time.Duration(-buckets+i+1)).Truncate(period))
historyHourly[i] = historyMap[datetime]
2024-02-22 16:29:17 +00:00
}
2024-02-22 19:20:34 +00:00
uptime := 0
if numTotal > 0 {
uptime = 100 * numOfSuccess / numTotal
}
2024-02-22 16:29:17 +00:00
return &History{
2024-02-29 22:42:56 +00:00
List: historyHourly,
Uptime: uptime,
}
}
func (h *BaseHandler) Index(c echo.Context) error {
2024-02-22 16:29:17 +00:00
ctx := context.Background()
2024-02-27 11:04:05 +00:00
monitors, err := services.GetMonitors(ctx, h.db)
2024-02-22 16:29:17 +00:00
if err != nil {
return err
}
timeRange := c.QueryParam("time-range")
2024-02-29 22:42:56 +00:00
if timeRange != "48hours" && timeRange != "90days" && timeRange != "90minutes" {
2024-02-22 16:29:17 +00:00
timeRange = "90days"
}
2024-02-29 22:42:56 +00:00
overallStatus := models.MonitorSuccess
2024-02-22 16:29:17 +00:00
2024-03-03 14:28:25 +00:00
monitorsWithHistory := make([]*Monitor, len(monitors))
for i, monitor := range monitors {
2024-02-29 22:42:56 +00:00
history, err := services.GetMonitorHistoryForMonitor(ctx, h.db, monitor.Id)
2024-02-27 11:04:05 +00:00
if err != nil {
return err
}
2024-02-29 22:42:56 +00:00
var historyResult *History
switch timeRange {
case "48hours":
historyResult = getHistory(history, time.Hour, 48)
case "90days":
historyResult = getHistory(history, time.Hour*24, 90)
case "90minutes":
historyResult = getHistory(history, time.Minute, 90)
}
2024-02-22 16:29:17 +00:00
2024-02-29 22:42:56 +00:00
status := historyResult.List[len(historyResult.List)-1]
if status != models.MonitorSuccess {
2024-02-22 16:29:17 +00:00
overallStatus = status
}
2024-03-03 14:28:25 +00:00
monitorsWithHistory[i] = &Monitor{
2024-02-29 22:42:56 +00:00
Name: monitor.Name,
2024-03-03 14:28:25 +00:00
Group: monitor.Group,
2024-02-29 22:42:56 +00:00
Status: status,
History: historyResult,
2024-02-22 16:29:17 +00:00
}
}
2024-03-03 14:28:25 +00:00
monitorsByGroup := map[string][]*Monitor{}
for _, monitor := range monitorsWithHistory {
monitorsByGroup[monitor.Group] = append(monitorsByGroup[monitor.Group], monitor)
}
return c.Render(http.StatusOK, "index.tmpl", &IndexData{
Base: &components.Base{
NavbarActive: GetPageByTitle(Pages, "Status"),
Navbar: Pages,
},
2024-03-03 14:28:25 +00:00
Monitors: monitorsByGroup,
TimeRange: timeRange,
Status: overallStatus,
})
}