diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | api/api.go | 37 | ||||
| -rw-r--r-- | dashboard/dashboard.go | 48 | ||||
| -rw-r--r-- | nonsense-time.go | 6 | ||||
| -rw-r--r-- | static/styles.css | 10 | ||||
| -rw-r--r-- | templates/base.html | 12 | ||||
| -rw-r--r-- | templates/dashboard/dashboard.html | 7 | ||||
| -rw-r--r-- | templates/dashboard/server_logs.html | 0 | ||||
| -rw-r--r-- | templates/dashboard/server_status.html | 15 |
9 files changed, 120 insertions, 17 deletions
@@ -20,5 +20,5 @@ info: @echo "BIN: $(BIN)" @echo "SERVICE: $(SERVICE)" -nonsense-time: nonsense-time.go +nonsense-time: nonsense-time.go $(wildcard api/*.go) $(wildcard dashboard/*.go) go build . @@ -6,13 +6,21 @@ import ( "log/slog" "net/http" "os" + "time" ) +type ServerStatus struct { + Online bool `json:"online"` + Site string `json:"url"` + Timestamp time.Time `json:"timestamp"` +} + var Logger *slog.Logger const VTT_URL string = "http://73.188.175.49:30000" -func remoteOnline(ctx context.Context, url string) bool { +func remoteOnline(ctx context.Context, url string) ServerStatus { + status := ServerStatus{Site: url, Timestamp: time.Now()} req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { panic(err) @@ -20,19 +28,16 @@ func remoteOnline(ctx context.Context, url string) bool { _, err = http.DefaultClient.Do(req) if err != nil { - return false + status.Online = false + } else { + status.Online = true } - return true + return status } -func respondOnline(w http.ResponseWriter, url string, isOnline bool) { - data := struct { - Online bool `json:"online"` - Site string `json:"url"` - }{isOnline, url} - - jsonData, err := json.Marshal(data) +func respondOnline(w http.ResponseWriter, status ServerStatus) { + jsonData, err := json.Marshal(status) if err != nil { http.Error(w, "Error constructing response", http.StatusInternalServerError) Logger.Error("Error marshalling site status data") @@ -44,12 +49,12 @@ func respondOnline(w http.ResponseWriter, url string, isOnline bool) { } func VttOnline(w http.ResponseWriter, req *http.Request) { - isOnline := remoteOnline(req.Context(), VTT_URL) + status := remoteOnline(req.Context(), VTT_URL) - if !isOnline { + if !status.Online { Logger.DebugContext(req.Context(), "Foundry VTT is offline") } - respondOnline(w, VTT_URL, isOnline) + respondOnline(w, status) } func VttRedirect(w http.ResponseWriter, req *http.Request) { @@ -59,12 +64,12 @@ func VttRedirect(w http.ResponseWriter, req *http.Request) { func SiteOnline(w http.ResponseWriter, req *http.Request) { const URL string = "https://dnd.jpappel.xyz" - isOnline := remoteOnline(req.Context(), URL) - if !isOnline { + status := remoteOnline(req.Context(), URL) + if !status.Online { Logger.DebugContext(req.Context(), "Campaign Website is offline") } - respondOnline(w, URL, isOnline) + respondOnline(w, status) } func init() { diff --git a/dashboard/dashboard.go b/dashboard/dashboard.go new file mode 100644 index 0000000..c3839f2 --- /dev/null +++ b/dashboard/dashboard.go @@ -0,0 +1,48 @@ +package dashboard + +import ( + "html/template" + "log/slog" + "net/http" + "nonsense-time/api" + "path/filepath" +) + +var Logger *slog.Logger +var templates map[string]*template.Template + +func Index(w http.ResponseWriter, req *http.Request) { + t, ok := templates["dashboard"] + + if !ok { + panic(t) + } + + // TODO: poll database + data := struct { + ServerStatus api.ServerStatus + }{ + ServerStatus: api.ServerStatus{}, + } + + err := t.Execute(w, data) + if err != nil { + Logger.Error("Unable to execute template", slog.Any("err", err)) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } +} + +func StaticHandler(w http.ResponseWriter, req *http.Request) { + http.StripPrefix("/static", http.FileServer(http.Dir("static"))).ServeHTTP(w, req) +} + +func init() { + Logger = slog.Default() + templates = make(map[string]*template.Template) + templates["dashboard"] = template.Must(template.New("base.html").ParseFiles( + filepath.Join("templates", "base.html"), + filepath.Join("templates", "dashboard", "dashboard.html"), + filepath.Join("templates", "dashboard", "server_status.html"), + )) +} diff --git a/nonsense-time.go b/nonsense-time.go index f9901e6..94c0a30 100644 --- a/nonsense-time.go +++ b/nonsense-time.go @@ -7,6 +7,7 @@ import ( "log/slog" "net/http" "nonsense-time/api" + "nonsense-time/dashboard" "os" "time" ) @@ -51,12 +52,15 @@ func main() { loggerOpts.Level = slog.LevelDebug case "error": loggerOpts.Level = slog.LevelError + default: + panic(fmt.Sprintf("Unkown log level %s", *logLevel)) } addr := fmt.Sprintf("%s:%d", *bindAddr, *port) logger = slog.New(slog.NewTextHandler(os.Stdout, loggerOpts)) api.Logger = logger + dashboard.Logger = logger vtt := timeoutMiddleware(http.HandlerFunc(api.VttOnline), *waitTime) site := timeoutMiddleware(http.HandlerFunc(api.SiteOnline), *waitTime) @@ -64,6 +68,8 @@ func main() { mux.Handle("GET /vtt/status", vtt) mux.HandleFunc("GET /vtt", api.VttRedirect) mux.Handle("GET /site/status", site) + mux.HandleFunc("GET /", dashboard.Index) + mux.HandleFunc("GET /static/", dashboard.StaticHandler) logger.Info(fmt.Sprint("Listening on ", addr)) logger.Info(http.ListenAndServe(addr, mux).Error()) diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..497cf2c --- /dev/null +++ b/static/styles.css @@ -0,0 +1,10 @@ +main { + display: flex; + margin: 1em; + flex-direction: column; +} + +section.server-status { + padding: 0 1em 0.75em; + border: 0.25em solid black; +} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..768d7eb --- /dev/null +++ b/templates/base.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html lang=en> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + {{ block "head" . }}<title>Nonsense Time Dashboard</title>{{ end }} + <link rel="stylesheet" href="/static/styles.css"> +</head> +<body> + {{ block "body" . }}{{ end }} +</body> +</html> diff --git a/templates/dashboard/dashboard.html b/templates/dashboard/dashboard.html new file mode 100644 index 0000000..29a852e --- /dev/null +++ b/templates/dashboard/dashboard.html @@ -0,0 +1,7 @@ +{{ define "body" }} +<h1>Dashboard Home</h1> +<p>Welcome to the Dashboard! It is still under construction so please be patient :) </p> +<main> + {{template "server_status" . }} +</main> +{{ end }} diff --git a/templates/dashboard/server_logs.html b/templates/dashboard/server_logs.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/templates/dashboard/server_logs.html diff --git a/templates/dashboard/server_status.html b/templates/dashboard/server_status.html new file mode 100644 index 0000000..8019659 --- /dev/null +++ b/templates/dashboard/server_status.html @@ -0,0 +1,15 @@ +{{define "server_status"}} +<section class="server-status"> + <h2>Server Status</h2> + <div id=uptime> + <dl> + <dt>Url</dt> + <dd>{{ .ServerStatus.Site }}</dd> + <dt>Online</dt> + <dd>{{ .ServerStatus.Online }}</dd> + <dt>Timestamp</dt> + <dd>{{ .ServerStatus.Timestamp }}</dd> + </dl> + </div> +</section> +{{end}} |
