Add (non-mandatory) configuration values to set address and port on which the web frontent will be served. If not set defaults will be applied.
96 lines
2.6 KiB
Go
96 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/TwinProduction/gatus/config"
|
|
"github.com/TwinProduction/gatus/security"
|
|
"github.com/TwinProduction/gatus/watchdog"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
const cacheTTL = 10 * time.Second
|
|
|
|
var (
|
|
cachedServiceResults []byte
|
|
cachedServiceResultsGzipped []byte
|
|
cachedServiceResultsTimestamp time.Time
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
cfg := loadConfiguration()
|
|
resultsHandler := serviceResultsHandler
|
|
if cfg.Security != nil && cfg.Security.IsValid() {
|
|
resultsHandler = security.Handler(serviceResultsHandler, cfg.Security)
|
|
}
|
|
http.HandleFunc("/api/v1/results", resultsHandler)
|
|
http.HandleFunc("/health", healthHandler)
|
|
http.Handle("/", GzipHandler(http.FileServer(http.Dir("./static"))))
|
|
if cfg.Metrics {
|
|
http.Handle("/metrics", promhttp.Handler())
|
|
}
|
|
|
|
log.Printf("[main][main] Listening on %s:%d\r\n", cfg.Web.Address, cfg.Web.Port)
|
|
go watchdog.Monitor(cfg)
|
|
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Web.Address, cfg.Web.Port), nil))
|
|
}
|
|
|
|
func loadConfiguration() *config.Config {
|
|
var err error
|
|
customConfigFile := os.Getenv("GATUS_CONFIG_FILE")
|
|
if len(customConfigFile) > 0 {
|
|
err = config.Load(customConfigFile)
|
|
} else {
|
|
err = config.LoadDefaultConfiguration()
|
|
}
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return config.Get()
|
|
}
|
|
|
|
func serviceResultsHandler(writer http.ResponseWriter, r *http.Request) {
|
|
if isExpired := cachedServiceResultsTimestamp.IsZero() || time.Now().Sub(cachedServiceResultsTimestamp) > cacheTTL; isExpired {
|
|
buffer := &bytes.Buffer{}
|
|
gzipWriter := gzip.NewWriter(buffer)
|
|
data, err := watchdog.GetJSONEncodedServiceResults()
|
|
if err != nil {
|
|
log.Printf("[main][serviceResultsHandler] Unable to marshal object to JSON: %s", err.Error())
|
|
writer.WriteHeader(http.StatusInternalServerError)
|
|
_, _ = writer.Write([]byte("Unable to marshal object to JSON"))
|
|
return
|
|
}
|
|
gzipWriter.Write(data)
|
|
gzipWriter.Close()
|
|
cachedServiceResults = data
|
|
cachedServiceResultsGzipped = buffer.Bytes()
|
|
cachedServiceResultsTimestamp = time.Now()
|
|
}
|
|
var data []byte
|
|
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
|
writer.Header().Set("Content-Encoding", "gzip")
|
|
data = cachedServiceResultsGzipped
|
|
} else {
|
|
data = cachedServiceResults
|
|
}
|
|
writer.Header().Add("Content-type", "application/json")
|
|
writer.WriteHeader(http.StatusOK)
|
|
_, _ = writer.Write(data)
|
|
}
|
|
|
|
func healthHandler(writer http.ResponseWriter, _ *http.Request) {
|
|
writer.Header().Add("Content-type", "application/json")
|
|
writer.WriteHeader(http.StatusOK)
|
|
_, _ = writer.Write([]byte("{\"status\":\"UP\"}"))
|
|
}
|