in metrics/main.go [25:138]
func main() {
/*******************************
* flags and configuration *
*******************************/
var wait time.Duration
var port int
var logFormat, logLevel string
flag.DurationVar(&wait, "graceful-timeout", time.Second*10, "the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m")
flag.IntVar(&port, "port", 2112, "listening port")
flag.StringVar(&logFormat, "log-format", "text", "the log format. It can be text, json, or color")
flag.StringVar(&logLevel, "log-level", "info", "the log level. It can be panic, fatal, error, warn, info, debug, or trace")
consulHost := flag.String("consul-host", "localhost", "the consul server host to connect to")
consulPort := flag.Int("consul-port", 8500, "the consul server port to connect to")
flag.Parse()
logrus := log.New()
closer, err := log.Initialize(
log.WithLogger(logrus),
log.WithFormatter(logFormat),
log.WithLogLevel(logLevel),
log.WithOutputName("stderr"),
)
if err != nil {
fmt.Fprintf(os.Stderr, "FATAL: Logger initialization failed. %v\n", err)
os.Exit(1)
}
defer closer.Close()
logrus.WithField("revision", Revision).WithField("build_date", BuildDate).Info("Booting")
/*******************************
* Metrics *
*******************************/
metricsHandlers, err := initMetrics(logrus, *consulHost, *consulPort)
if err != nil {
logrus.WithError(err).Fatal("Metrics initialization failed")
}
/*******************************
* Webhooks *
*******************************/
webhooks, errors := initWebhooks()
if len(errors) > 0 {
for _, err := range errors {
logrus.WithError(err).Error("Can't receive webhook events")
}
}
/*******************************
* HTTP server *
*******************************/
r := buildRoutes(logrus, os.Getenv("AUTH_TOKEN"), metricsHandlers, webhooks)
srv := &http.Server{
Addr: fmt.Sprintf(":%d", port),
WriteTimeout: time.Second * 5,
ReadTimeout: time.Second * 5,
IdleTimeout: time.Second * 10,
Handler: r,
}
/*******************************
* Graceful Shutdown *
*******************************/
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Observe release-tools pipelines
err = pipelines.Observe(ctx, logrus, os.Getenv("DELIVERY_METRICS_OPS_TOKEN"))
if err != nil {
log.WithError(err).Fatal("cannot start the pipeline observer")
}
// Run our server in a goroutine so that it doesn't block.
go func() {
logrus.WithField("addr", srv.Addr).Info("Accepting incoming connections")
if err := srv.ListenAndServe(); err != nil {
logrus.WithError(err).Error("Server shutdown")
cancel()
}
}()
// We'll accept graceful shutdowns when quit via SIGINT
// or SIGTERM (Kubernets termination signal)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT)
// Block until we receive our signal or the main context is Done
select {
case sig := <-sigs:
logrus.WithField("signal", sig).Warn("Signal received")
// Create a deadline to wait for
ctxGrace, cancelGrace := context.WithTimeout(ctx, wait)
defer cancelGrace()
// Doesn't block if no connections, but will otherwise wait
// until the timeout deadline.
logrus.WithField("timeout", wait).Info("Begin graceful shutdown")
if err := srv.Shutdown(ctxGrace); err != nil {
logrus.WithError(err).Error("Graceful shutdown failed")
}
case <-ctx.Done():
logrus.WithError(ctx.Err()).Info("Main context expired")
}
logrus.Error("Bye")
}