59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
// Package status loads and manages the service status JSON.
|
|
package status
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var mu sync.RWMutex
|
|
|
|
// Service represents a single monitored service.
|
|
type Service struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
URL string `json:"url,omitempty"`
|
|
CheckURL string `json:"check_url,omitempty"` // HTTP URL probed automatically; empty = manual
|
|
Status string `json:"status"` // "up", "degraded", "down", "unknown"
|
|
Note string `json:"note,omitempty"`
|
|
}
|
|
|
|
// Page is the full status page data loaded from JSON.
|
|
type Page struct {
|
|
LastChecked time.Time `json:"last_checked"`
|
|
Services []Service `json:"services"`
|
|
}
|
|
|
|
// Load reads and parses the status JSON from path.
|
|
func Load(path string) (*Page, error) {
|
|
mu.RLock()
|
|
defer mu.RUnlock()
|
|
return load(path)
|
|
}
|
|
|
|
func load(path string) (*Page, error) {
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var p Page
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
return nil, err
|
|
}
|
|
return &p, nil
|
|
}
|
|
|
|
// Save writes the status page data back to path.
|
|
func Save(path string, p *Page) error {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
p.LastChecked = time.Now().UTC()
|
|
raw, err := json.MarshalIndent(p, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(path, raw, 0644)
|
|
}
|