gsave/main.go

150 lines
3.9 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
"sync"
"time"
"github.com/gorilla/mux"
"github.com/hamburghammer/gsave/controller"
"github.com/hamburghammer/gsave/controller/middleware"
"github.com/hamburghammer/gsave/db"
"github.com/jessevdk/go-flags"
log "github.com/sirupsen/logrus"
)
var (
servePort int
logPackage = log.WithField("Package", "main")
)
type arguments struct {
Port int `short:"p" long:"port" default:"8080" description:"The port for the HTTP server." env:"GSAVE_PORT"`
Token string `short:"t" long:"token" required:"yes" description:"The token for the authentication through HTTP." env:"GSAVE_TOKEN"`
Verbose bool `short:"v" long:"verbose" description:"Enable trace logging level output."`
Quiet bool `short:"q" long:"quiet" description:"Disable standard logging output and only prints errors."`
JSONLogging bool `long:"json" description:"Set the logging format to json."`
}
func init() {
args := arguments{}
_, err := flags.Parse(&args)
if err != nil {
if _, ok := err.(*flags.Error); ok {
os.Exit(1)
return
}
logPackage.Fatal(err)
}
servePort = args.Port
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
})
if args.Verbose {
log.SetLevel(log.TraceLevel)
}
if args.Quiet {
log.SetLevel(log.ErrorLevel)
}
if args.JSONLogging {
log.SetFormatter(&log.JSONFormatter{})
}
}
func main() {
logPackage.Info("Initializing the DB...")
stats := []db.Stats{
{Hostname: "foo", CPU: 0, Disk: db.Memory{Total: 10, Used: 5}, Mem: db.Memory{Total: 20, Used: 10}, Processes: []db.Process{{Name: "foo", Pid: 1, CPU: 0.5}}},
{Hostname: "foo", CPU: 1},
{Hostname: "bar", CPU: 0},
}
hostDB, err := initDB(stats)
if err != nil {
logPackage.Fatal(err)
}
logPackage.Info("Initializing the routes...")
controllers := []controller.Router{
controller.NewHostsRouter(hostDB),
}
router := initRouter(hostDB, controllers)
auth := middleware.NewAuthMiddleware([]string{"foo"})
// Add default middlewares
router.Use(middleware.RequestTimeLoggingHandler)
router.Use(middleware.PanicRecoverHandler)
router.Use(auth.AuthHandler)
logPackage.Info("Starting the HTTP server...")
server := &http.Server{
Handler: router,
Addr: fmt.Sprintf(":%d", servePort),
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
IdleTimeout: 120 * time.Second,
}
var wg sync.WaitGroup
wg.Add(2)
go startHTTPServer(server, &wg)
go listenToStopHTTPServer(server, &wg)
wg.Wait()
}
func initDB(stats []db.Stats) (db.HostDB, error) {
hostDB := db.NewInMemoryDB()
for _, stat := range stats {
if err := hostDB.InsertStats(stat.Hostname, stat); err != nil {
return hostDB, fmt.Errorf("Init db throwed an error: %w", err)
}
}
return hostDB, nil
}
func initRouter(hostDB db.HostDB, controllers []controller.Router) *mux.Router {
router := mux.NewRouter()
for _, controller := range controllers {
subrouter := router.PathPrefix(controller.GetPrefix()).Name(controller.GetRouteName()).Subrouter()
controller.Register(subrouter)
}
return router
}
func startHTTPServer(server *http.Server, wg *sync.WaitGroup) {
defer wg.Done()
logPackage.Infof("The HTTP server is running: http://localhost:%d/hosts\n", servePort)
if err := server.ListenAndServe(); err != nil {
if errors.Is(err, http.ErrServerClosed) {
logPackage.Info("Shutting down the server...")
return
}
logPackage.Fatalf("An unexpected error happend while running the HTTP server: %v\n", err)
}
}
func listenToStopHTTPServer(server *http.Server, wg *sync.WaitGroup) {
defer wg.Done()
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, os.Kill)
<-stop
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
logPackage.Errorf("An error happened on the shutdown of the server: %v", err)
}
}