github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/metrics/server.go (about) 1 package metrics 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 "strconv" 8 "time" 9 10 "github.com/prometheus/client_golang/prometheus/promhttp" 11 "github.com/rs/zerolog" 12 ) 13 14 // Server is the http server that will be serving the /metrics request for prometheus 15 type Server struct { 16 server *http.Server 17 log zerolog.Logger 18 } 19 20 // NewServer creates a new server that will start on the specified port, 21 // and responds to only the `/metrics` endpoint 22 func NewServer(log zerolog.Logger, port uint) *Server { 23 addr := ":" + strconv.Itoa(int(port)) 24 25 mux := http.NewServeMux() 26 endpoint := "/metrics" 27 mux.Handle(endpoint, promhttp.Handler()) 28 log.Info().Str("address", addr).Str("endpoint", endpoint).Msg("metrics server started") 29 30 m := &Server{ 31 server: &http.Server{Addr: addr, Handler: mux}, 32 log: log, 33 } 34 35 return m 36 } 37 38 // Ready returns a channel that will close when the network stack is ready. 39 func (m *Server) Ready() <-chan struct{} { 40 ready := make(chan struct{}) 41 go func() { 42 if err := m.server.ListenAndServe(); err != nil { 43 // http.ErrServerClosed is returned when Close or Shutdown is called 44 // we don't consider this an error, so print this with debug level instead 45 if errors.Is(err, http.ErrServerClosed) { 46 m.log.Debug().Err(err).Msg("metrics server shutdown") 47 } else { 48 m.log.Err(err).Msg("error shutting down metrics server") 49 } 50 } 51 }() 52 go func() { 53 close(ready) 54 }() 55 return ready 56 } 57 58 // Done returns a channel that will close when shutdown is complete. 59 func (m *Server) Done() <-chan struct{} { 60 done := make(chan struct{}) 61 go func() { 62 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 63 _ = m.server.Shutdown(ctx) 64 cancel() 65 close(done) 66 }() 67 return done 68 }