go uptime monitor
at main 1.6 kB view raw
1package web 2 3import ( 4 "database/sql" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/go-chi/chi/v5" 10) 11 12func Routes(db *sql.DB) http.Handler { 13 r := chi.NewRouter() 14 15 r.Get("/", HandleDashboard(db)) 16 17 return r 18} 19 20func HandleDashboard(db *sql.DB) http.HandlerFunc { 21 return func(w http.ResponseWriter, r *http.Request) { 22 type Result struct { 23 Name string 24 Statuses []string 25 } 26 27 rows, err := db.Query(` 28 SELECT name, status 29 FROM check_results 30 ORDER BY timestamp DESC 31 LIMIT 1000 32 `) 33 if err != nil { 34 http.Error(w, "DB error", 500) 35 return 36 } 37 defer rows.Close() 38 39 grouped := map[string][]string{} 40 41 for rows.Next() { 42 var name, status string 43 if err := rows.Scan(&name, &status); err == nil { 44 grouped[name] = append(grouped[name], status) 45 } 46 } 47 48 var html strings.Builder 49 html.WriteString(`<!DOCTYPE html><html><head><meta charset="utf-8"><title>Hestia</title></head><body style="font-family: sans-serif">`) 50 html.WriteString(`<h1>Health Checks</h1>`) 51 52 for name, statuses := range grouped { 53 html.WriteString(fmt.Sprintf("<h2>%s</h2><div style='display: flex; gap: 2px;'>", name)) 54 for _, status := range statuses { 55 color := "#4caf50" 56 if status != "ok" { 57 color = "#f44336" 58 } 59 html.WriteString(fmt.Sprintf(`<div title="%s" style="width: 10px; height: 20px; background: %s;"></div>`, status, color)) 60 } 61 html.WriteString("</div>") 62 } 63 64 html.WriteString(`</body></html>`) 65 w.Header().Set("Content-Type", "text/html") 66 w.Write([]byte(html.String())) 67 } 68}