feat: add /status route
This commit is contained in:
parent
7a8a229f0e
commit
aaa8640aaf
7 changed files with 122 additions and 3 deletions
10
.env.example
10
.env.example
|
|
@ -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"
|
||||||
12
internal/handler/status.go
Normal file
12
internal/handler/status.go
Normal 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
8
internal/model/status.go
Normal 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"`
|
||||||
|
}
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
72
internal/service/status.go
Normal file
72
internal/service/status.go
Normal 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
20
internal/worker/status.go
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,4 +2,5 @@ package worker
|
||||||
|
|
||||||
func StartWorkers() {
|
func StartWorkers() {
|
||||||
go StartLastFMWorker()
|
go StartLastFMWorker()
|
||||||
|
go StartStatusWorker()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue