feat: add /status route

This commit is contained in:
trafficlunar 2024-10-06 13:38:26 +01:00
parent 7a8a229f0e
commit aaa8640aaf
7 changed files with 122 additions and 3 deletions

View file

@ -1,6 +1,12 @@
# Port for the server # Port for the server
PORT=8888 PORT=8888
# Your last.fm username # Your last.fm username
LASTFM_USERNAME="axolotlmaid" LASTFM_USERNAME="axolotlmaid"
# API Key for last.fm # API key for last.fm
LASTFM_API_KEY="API_KEY_GOES_HERE" LASTFM_API_KEY="API_KEY_GOES_HERE"
# URL for Uptime Kuma
UPTIME_KUMA_URL="http://localhost:3001/metrics"
# API key for Uptime Kuma
UPTIME_KUMA_API_KEY="API_KEY_GOES_HERE"

View file

@ -0,0 +1,12 @@
package handler
import (
"backend/internal/worker"
"encoding/json"
"net/http"
)
func HandleGetStatus(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(worker.StatusData)
}

8
internal/model/status.go Normal file
View file

@ -0,0 +1,8 @@
package model
type StatusData struct {
Success bool `json:"success"`
Website uint8 `json:"website"`
Api uint8 `json:"api"`
Files uint8 `json:"files"`
}

View file

@ -38,8 +38,8 @@ func NewRouter() {
r.Get("/visit-counter", handler.HandleGetVisitCounter) r.Get("/visit-counter", handler.HandleGetVisitCounter)
r.With(httprate.LimitByRealIP(1, time.Hour)).Patch("/visit-counter", handler.HandlePatchVisitCounter) r.With(httprate.LimitByRealIP(1, time.Hour)).Patch("/visit-counter", handler.HandlePatchVisitCounter)
r.Get("/currently-playing", handler.HandleGetCurrentlyPlaying) r.Get("/currently-playing", handler.HandleGetCurrentlyPlaying)
r.Get("/status", handler.HandleGetStatus)
port := os.Getenv("PORT") port := os.Getenv("PORT")
if len(port) == 0 { if len(port) == 0 {

View file

@ -0,0 +1,72 @@
package service
import (
"backend/internal/model"
"bufio"
"log/slog"
"net/http"
"os"
"regexp"
"strconv"
"strings"
)
func GetStatuses() model.StatusData {
data := model.StatusData{
Success: false,
Website: 0,
Api: 0,
Files: 0,
}
req, err := http.NewRequest("GET", os.Getenv("UPTIME_KUMA_URL"), nil)
if err != nil {
slog.Error("Error creating request for Uptime Kuma", slog.Any("error", err))
return data
}
req.SetBasicAuth("", os.Getenv("UPTIME_KUMA_API_KEY"))
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
slog.Error("Error sending request for Uptime Kuma", slog.Any("error", err))
return data
}
defer res.Body.Close()
regex := regexp.MustCompile(`monitor_name="([^"]+)"[^}]*} (\d+)`)
statusMap := map[string]*uint8{
"website": &data.Website,
"api": &data.Api,
"files": &data.Files,
}
scanner := bufio.NewScanner(res.Body)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "monitor_status{") {
matches := regex.FindStringSubmatch(line)
monitorName := matches[1]
status := matches[2]
statusCode, err := strconv.Atoi(status)
if err != nil {
slog.Error("Error parsing bool for Uptime Kuma", slog.Any("error", err))
statusCode = 0
}
if field, exists := statusMap[monitorName]; exists {
*field = uint8(statusCode)
}
}
}
if err := scanner.Err(); err != nil {
slog.Error("Error reading metrics for Uptime Kuma", slog.Any("error", err))
return data
}
data.Success = true
return data
}

20
internal/worker/status.go Normal file
View file

@ -0,0 +1,20 @@
package worker
import (
"backend/internal/model"
"backend/internal/service"
"log/slog"
"time"
)
var StatusData model.StatusData
func StartStatusWorker() {
slog.Info("Starting status worker...")
StatusData = service.GetStatuses()
for range time.Tick(5 * time.Minute) {
slog.Info("Requesting Uptime Kuma...")
StatusData = service.GetStatuses()
}
}

View file

@ -2,4 +2,5 @@ package worker
func StartWorkers() { func StartWorkers() {
go StartLastFMWorker() go StartLastFMWorker()
go StartStatusWorker()
} }