mirror of
https://github.com/mentos1386/zdravko.git
synced 2024-11-22 15:53:45 +00:00
172 lines
4 KiB
Go
172 lines
4 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
"code.tjo.space/mentos1386/zdravko/internal/models"
|
|
"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
|
|
HealthChecks []*HealthCheck
|
|
HealthchecksLength int
|
|
TimeRange string
|
|
Status string
|
|
}
|
|
|
|
type HealthCheck struct {
|
|
Name string
|
|
Status string
|
|
HistoryDaily *History
|
|
HistoryHourly *History
|
|
}
|
|
|
|
type History struct {
|
|
History []string
|
|
Uptime int
|
|
}
|
|
|
|
func getDay(date time.Time) string {
|
|
return date.Format("2006-01-02")
|
|
}
|
|
|
|
func getHour(date time.Time) string {
|
|
return date.Format("2006-01-02T15:04")
|
|
}
|
|
|
|
func getDailyHistory(history []models.HealthcheckHistory) *History {
|
|
numDays := 90
|
|
historyDailyMap := map[string]string{}
|
|
numOfSuccess := 0
|
|
numTotal := 1
|
|
|
|
for i := 0; i < numDays; i++ {
|
|
day := getDay(time.Now().AddDate(0, 0, -i).Truncate(time.Hour * 24))
|
|
historyDailyMap[day] = models.HealthcheckUnknown
|
|
}
|
|
|
|
for _, _history := range history {
|
|
day := getDay(_history.CreatedAt.Truncate(time.Hour * 24))
|
|
|
|
// skip if day is not in the last 90 days
|
|
if _, ok := historyDailyMap[day]; !ok {
|
|
continue
|
|
}
|
|
|
|
numTotal++
|
|
if _history.Status == models.HealthcheckSuccess {
|
|
numOfSuccess++
|
|
}
|
|
|
|
// skip if day is already set to failure
|
|
if historyDailyMap[day] == models.HealthcheckFailure {
|
|
continue
|
|
}
|
|
|
|
historyDailyMap[day] = _history.Status
|
|
}
|
|
|
|
historyDaily := make([]string, numDays)
|
|
for i := 0; i < numDays; i++ {
|
|
day := getDay(time.Now().AddDate(0, 0, -numDays+i+1).Truncate(time.Hour * 24))
|
|
historyDaily[i] = historyDailyMap[day]
|
|
}
|
|
|
|
return &History{
|
|
History: historyDaily,
|
|
Uptime: 100 * numOfSuccess / numTotal,
|
|
}
|
|
}
|
|
|
|
func getHourlyHistory(history []models.HealthcheckHistory) *History {
|
|
numHours := 48
|
|
historyHourlyMap := map[string]string{}
|
|
numOfSuccess := 0
|
|
numTotal := 1
|
|
|
|
for i := 0; i < numHours; i++ {
|
|
hour := getHour(time.Now().Add(time.Hour * time.Duration(-i)).Truncate(time.Hour))
|
|
historyHourlyMap[hour] = models.HealthcheckUnknown
|
|
}
|
|
|
|
for _, _history := range history {
|
|
hour := getHour(_history.CreatedAt.Truncate(time.Hour))
|
|
|
|
// skip if day is not in the last 90 days
|
|
if _, ok := historyHourlyMap[hour]; !ok {
|
|
continue
|
|
}
|
|
|
|
numTotal++
|
|
if _history.Status == models.HealthcheckSuccess {
|
|
numOfSuccess++
|
|
}
|
|
|
|
// skip if day is already set to failure
|
|
if historyHourlyMap[hour] == models.HealthcheckFailure {
|
|
continue
|
|
}
|
|
|
|
historyHourlyMap[hour] = _history.Status
|
|
}
|
|
|
|
historyHourly := make([]string, numHours)
|
|
for i := 0; i < numHours; i++ {
|
|
hour := getHour(time.Now().Add(time.Hour * time.Duration(-numHours+i+1)).Truncate(time.Hour))
|
|
historyHourly[i] = historyHourlyMap[hour]
|
|
}
|
|
|
|
return &History{
|
|
History: historyHourly,
|
|
Uptime: 100 * numOfSuccess / numTotal,
|
|
}
|
|
}
|
|
|
|
func (h *BaseHandler) Index(c echo.Context) error {
|
|
ctx := context.Background()
|
|
healthchecks, err := services.GetHealthchecksWithHistory(ctx, h.query)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
timeRange := c.QueryParam("time-range")
|
|
if timeRange != "48hours" && timeRange != "90days" {
|
|
timeRange = "90days"
|
|
}
|
|
|
|
overallStatus := "SUCCESS"
|
|
|
|
healthchecksWithHistory := make([]*HealthCheck, len(healthchecks))
|
|
for i, healthcheck := range healthchecks {
|
|
historyDaily := getDailyHistory(healthcheck.History)
|
|
historyHourly := getHourlyHistory(healthcheck.History)
|
|
|
|
status := historyDaily.History[89]
|
|
if status != models.HealthcheckSuccess {
|
|
overallStatus = status
|
|
}
|
|
|
|
healthchecksWithHistory[i] = &HealthCheck{
|
|
Name: healthcheck.Name,
|
|
Status: status,
|
|
HistoryDaily: historyDaily,
|
|
HistoryHourly: historyHourly,
|
|
}
|
|
}
|
|
|
|
return c.Render(http.StatusOK, "index.tmpl", &IndexData{
|
|
Base: &components.Base{
|
|
NavbarActive: GetPageByTitle(Pages, "Status"),
|
|
Navbar: Pages,
|
|
},
|
|
HealthChecks: healthchecksWithHistory,
|
|
HealthchecksLength: len(healthchecks),
|
|
TimeRange: timeRange,
|
|
Status: overallStatus,
|
|
})
|
|
}
|