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  }