Update template
This commit is contained in:
107
main.go
Normal file
107
main.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.clustercockpit.org/moebiusband/go-http-skeleton/internal/handlers"
|
||||
"git.clustercockpit.org/moebiusband/go-http-skeleton/internal/middleware"
|
||||
)
|
||||
|
||||
//go:embed web/static/*
|
||||
var static embed.FS
|
||||
|
||||
func init() {
|
||||
_, jsonLogger := os.LookupEnv("JSON_LOGGER")
|
||||
_, debug := os.LookupEnv("DEBUG")
|
||||
|
||||
var programLevel slog.Level
|
||||
if debug {
|
||||
programLevel = slog.LevelDebug
|
||||
}
|
||||
|
||||
if jsonLogger {
|
||||
jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: programLevel,
|
||||
})
|
||||
slog.SetDefault(slog.New(jsonHandler))
|
||||
} else {
|
||||
textHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: programLevel,
|
||||
})
|
||||
slog.SetDefault(slog.New(textHandler))
|
||||
}
|
||||
|
||||
slog.Info("Logger initialized", slog.Bool("debug", debug))
|
||||
}
|
||||
|
||||
func main() {
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
addr := ":" + port
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Use an embedded filesystem rooted at "web/static"
|
||||
fs, err := fs.Sub(static, "web/static")
|
||||
if err != nil {
|
||||
slog.Error("Failed to create sub filesystem", "error", err)
|
||||
return
|
||||
}
|
||||
// Serve files from the embedded /web/static directory at /static
|
||||
fileServer := http.FileServer(http.FS(fs))
|
||||
mux.Handle("GET /static/", http.StripPrefix("/static/", fileServer))
|
||||
|
||||
mux.HandleFunc("GET /favicon.ico", func(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := static.ReadFile("web/static/img/favicon.ico")
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.Write(data)
|
||||
})
|
||||
mux.HandleFunc("GET /robots.txt", func(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := static.ReadFile("web/static/robots.txt")
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.Write(data)
|
||||
})
|
||||
|
||||
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.Write([]byte(`OK`))
|
||||
})
|
||||
|
||||
mux.HandleFunc("GET /", handlers.RootHandler())
|
||||
|
||||
chain := &middleware.Chain{}
|
||||
chain.Use(middleware.RecoverMiddleware)
|
||||
wrappedMux := chain.Then(mux)
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%s", port),
|
||||
Handler: wrappedMux,
|
||||
// Recommended timeouts from
|
||||
// https://blog.cloudflare.com/exposing-go-on-the-internet/
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
IdleTimeout: 120 * time.Second,
|
||||
}
|
||||
|
||||
slog.Info("Server listening", "addr", addr)
|
||||
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
slog.Error("Server failed to start", "error", err)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user