diff --git a/cmd/server.go b/cmd/server.go index 9a945d7..59b80ed 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -14,6 +14,7 @@ package cmd import ( + "context" "fmt" "github.com/hipages/php-fpm_exporter/phpfpm" "github.com/prometheus/client_golang/prometheus" @@ -21,15 +22,15 @@ import ( "github.com/spf13/cobra" "net/http" "os" + "os/signal" + "time" ) // Configuration variables var ( - listeningAddress string - metricsEndpoint string - scrapeURIs []string - customLabelNames []string - customLabelValues []string + listeningAddress string + metricsEndpoint string + scrapeURIs []string ) // serverCmd represents the server command @@ -54,17 +55,52 @@ to quickly create a Cobra application.`, exporter := phpfpm.NewExporter(pm) prometheus.MustRegister(exporter) + srv := &http.Server{ + Addr: listeningAddress, + // Good practice to set timeouts to avoid Slowloris attacks. + WriteTimeout: time.Second * 15, + ReadTimeout: time.Second * 15, + IdleTimeout: time.Second * 60, + } + http.Handle(metricsEndpoint, promhttp.Handler()) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(` - Apache Exporter + php-fpm_exporter -

Apache Exporter

+

php-fpm_exporter

Metrics

`)) }) - log.Fatal(http.ListenAndServe(listeningAddress, nil)) + + // Run our server in a goroutine so that it doesn't block. + go func() { + if err := srv.ListenAndServe(); err != nil { + log.Error(err) + } + }() + + c := make(chan os.Signal, 1) + // We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C) + // SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught. + signal.Notify(c, os.Interrupt) + + // Block until we receive our signal. + <-c + + // Create a deadline to wait for. + var wait time.Duration + ctx, cancel := context.WithTimeout(context.Background(), wait) + defer cancel() + // Doesn't block if no connections, but will otherwise wait + // until the timeout deadline. + srv.Shutdown(ctx) + // Optionally, you could run srv.Shutdown in a goroutine and block on + // <-ctx.Done() if your application should wait for other services + // to finalize based on context cancellation. + log.Info("Shutting down") + os.Exit(0) }, }