mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-06-10 23:57:45 +02:00
119 lines
3.6 KiB
Go
119 lines
3.6 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
_ "net/http/pprof"
|
||
|
"os"
|
||
|
"os/signal"
|
||
|
"syscall"
|
||
|
"time"
|
||
|
|
||
|
"geeks-accelerator/oss/saas-starter-kit/example-project/cmd/sidecar/tracer/handlers"
|
||
|
"github.com/kelseyhightower/envconfig"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
|
||
|
// =========================================================================
|
||
|
// Logging
|
||
|
|
||
|
log := log.New(os.Stdout, "TRACER : ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)
|
||
|
defer log.Println("main : Completed")
|
||
|
|
||
|
// =========================================================================
|
||
|
// Configuration
|
||
|
|
||
|
var cfg struct {
|
||
|
Web struct {
|
||
|
APIHost string `default:"0.0.0.0:3002" envconfig:"API_HOST"`
|
||
|
DebugHost string `default:"0.0.0.0:4002" envconfig:"DEBUG_HOST"`
|
||
|
ReadTimeout time.Duration `default:"5s" envconfig:"READ_TIMEOUT"`
|
||
|
WriteTimeout time.Duration `default:"5s" envconfig:"WRITE_TIMEOUT"`
|
||
|
ShutdownTimeout time.Duration `default:"5s" envconfig:"SHUTDOWN_TIMEOUT"`
|
||
|
}
|
||
|
Zipkin struct {
|
||
|
Host string `default:"http://zipkin:9411/api/v2/spans" envconfig:"HOST"`
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := envconfig.Process("TRACER", &cfg); err != nil {
|
||
|
log.Fatalf("main : Parsing Config : %v", err)
|
||
|
}
|
||
|
|
||
|
cfgJSON, err := json.MarshalIndent(cfg, "", " ")
|
||
|
if err != nil {
|
||
|
log.Fatalf("main : Marshalling Config to JSON : %v", err)
|
||
|
}
|
||
|
log.Printf("config : %v\n", string(cfgJSON))
|
||
|
|
||
|
// =========================================================================
|
||
|
// Start Debug Service. Not concerned with shutting this down when the
|
||
|
// application is being shutdown.
|
||
|
//
|
||
|
// /debug/pprof - Added to the default mux by the net/http/pprof package.
|
||
|
go func() {
|
||
|
log.Printf("main : Debug Listening %s", cfg.Web.DebugHost)
|
||
|
log.Printf("main : Debug Listener closed : %v", http.ListenAndServe(cfg.Web.DebugHost, http.DefaultServeMux))
|
||
|
}()
|
||
|
|
||
|
// =========================================================================
|
||
|
// Start API Service
|
||
|
|
||
|
// Make a channel to listen for an interrupt or terminate signal from the OS.
|
||
|
// Use a buffered channel because the signal package requires it.
|
||
|
shutdown := make(chan os.Signal, 1)
|
||
|
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
|
||
|
|
||
|
api := http.Server{
|
||
|
Addr: cfg.Web.APIHost,
|
||
|
Handler: handlers.API(shutdown, log, cfg.Zipkin.Host, cfg.Web.APIHost),
|
||
|
ReadTimeout: cfg.Web.ReadTimeout,
|
||
|
WriteTimeout: cfg.Web.WriteTimeout,
|
||
|
MaxHeaderBytes: 1 << 20,
|
||
|
}
|
||
|
|
||
|
// Make a channel to listen for errors coming from the listener. Use a
|
||
|
// buffered channel so the goroutine can exit if we don't collect this error.
|
||
|
serverErrors := make(chan error, 1)
|
||
|
|
||
|
// Start the service listening for requests.
|
||
|
go func() {
|
||
|
log.Printf("main : API Listening %s", cfg.Web.APIHost)
|
||
|
serverErrors <- api.ListenAndServe()
|
||
|
}()
|
||
|
|
||
|
// =========================================================================
|
||
|
// Shutdown
|
||
|
|
||
|
// Blocking main and waiting for shutdown.
|
||
|
select {
|
||
|
case err := <-serverErrors:
|
||
|
log.Fatalf("main : Error starting server: %v", err)
|
||
|
|
||
|
case sig := <-shutdown:
|
||
|
log.Printf("main : %v : Start shutdown..", sig)
|
||
|
|
||
|
// Create context for Shutdown call.
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), cfg.Web.ShutdownTimeout)
|
||
|
defer cancel()
|
||
|
|
||
|
// Asking listener to shutdown and load shed.
|
||
|
err := api.Shutdown(ctx)
|
||
|
if err != nil {
|
||
|
log.Printf("main : Graceful shutdown did not complete in %v : %v", cfg.Web.ShutdownTimeout, err)
|
||
|
err = api.Close()
|
||
|
}
|
||
|
|
||
|
// Log the status of this shutdown.
|
||
|
switch {
|
||
|
case sig == syscall.SIGSTOP:
|
||
|
log.Fatal("main : Integrity issue caused shutdown")
|
||
|
case err != nil:
|
||
|
log.Fatalf("main : Could not stop server gracefully : %v", err)
|
||
|
}
|
||
|
}
|
||
|
}
|