package process import "fmt" import "net/http" import "os" import "strconv" import "time" import "github.com/rs/zerolog/log" import "github.com/gin-gonic/gin" import "github.com/dn365/gin-zerolog" // Server is the HTTP webserver object type Server struct { feta *Feta port uint router *gin.Engine server *http.Server debug bool } // SetFeta tells the http Server where to find the Process object so that it // can pull stats and other information for serving via http func (a *Server) SetFeta(feta *Feta) { a.feta = feta } // Serve is the entrypoint for the Server, which should run in its own // goroutine (started by the Process) func (a *Server) Serve() { if a.feta == nil { panic("must have feta app from which to serve stats") } if os.Getenv("DEBUG") != "" { a.debug = true } a.port = 8080 if os.Getenv("PORT") != "" { s, err := strconv.ParseUint(os.Getenv("PORT"), 10, 64) if err != nil { a.port = uint(s) } } a.initRouter() a.initServer() err := a.server.ListenAndServe() if err != nil { log.Fatal().Err(err).Msg("webserver failure") return } } func (a *Server) initRouter() { // empty router r := gin.New() // wrap panics: r.Use(gin.Recovery()) // attach logger middleware r.Use(ginzerolog.Logger("gin")) r.GET("/.well-known/healthcheck.json", gin.WrapF(a.getHealthCheckHandler())) r.GET("/", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "/feta") }) r.GET("/feta", gin.WrapF(a.getIndexHandler())) r.GET("/feta/list/instances", gin.WrapF(a.getInstanceListHandler())) a.router = r } func (a *Server) initServer() { if !a.debug { gin.SetMode(gin.ReleaseMode) } log.Info().Uint("port", a.port).Msg("starting webserver") a.server = &http.Server{ Addr: fmt.Sprintf(":%d", a.port), Handler: a.router, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } }