forked from TrueCloudLab/frostfs-node
[#493] Refactor serving of prometheus and pprof services
Rename `util/profiler` package to `httputil` and refactor it: * simplify utility HTTP server; * make more generic server's parameters in order to remove `viper.Viper` dependency; * use single constructor for creating the pprof and prometheus servers; * replace `enabled` config value with empty-check of the network address. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
6339f1a468
commit
8d17dab86e
15 changed files with 295 additions and 304 deletions
44
pkg/util/http/calls.go
Normal file
44
pkg/util/http/calls.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package httputil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Serve listens and serves internal HTTP server.
|
||||
//
|
||||
// Returns any error returned by internal server
|
||||
// except http.ErrServerClosed.
|
||||
//
|
||||
// After Shutdown call, Serve has no effect and
|
||||
// returned error is always nil.
|
||||
func (x *Server) Serve() error {
|
||||
err := x.srv.ListenAndServe()
|
||||
|
||||
// http.ErrServerClosed is returned on server shutdown
|
||||
// so we ignore this error.
|
||||
if err != nil && errors.Is(err, http.ErrServerClosed) {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown gracefully shuts down internal HTTP server.
|
||||
//
|
||||
// Shutdown is called with context which expires after
|
||||
// configured timeout.
|
||||
//
|
||||
// Once Shutdown has been called on a server, it may not be reused;
|
||||
// future calls to Serve method will have no effect.
|
||||
func (x *Server) Shutdown() error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), x.shutdownTimeout)
|
||||
|
||||
err := x.srv.Shutdown(ctx)
|
||||
|
||||
cancel()
|
||||
|
||||
return err
|
||||
}
|
26
pkg/util/http/opts.go
Normal file
26
pkg/util/http/opts.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package httputil
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Option sets an optional parameter of Server.
|
||||
type Option func(*cfg)
|
||||
|
||||
type cfg struct {
|
||||
shutdownTimeout time.Duration
|
||||
}
|
||||
|
||||
func defaultCfg() *cfg {
|
||||
return &cfg{
|
||||
shutdownTimeout: 15 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// WithShutdownTimeout returns option to set shutdown timeout
|
||||
// of the internal HTTP server.
|
||||
func WithShutdownTimeout(dur time.Duration) Option {
|
||||
return func(c *cfg) {
|
||||
c.shutdownTimeout = dur
|
||||
}
|
||||
}
|
16
pkg/util/http/pprof.go
Normal file
16
pkg/util/http/pprof.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package httputil
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
)
|
||||
|
||||
// initializes pprof package in order to
|
||||
// register Prometheus handlers on http.DefaultServeMux.
|
||||
var _ = pprof.Handler("")
|
||||
|
||||
// Handler returns http.Handler for the
|
||||
// Prometheus metrics collector.
|
||||
func Handler() http.Handler {
|
||||
return http.DefaultServeMux
|
||||
}
|
87
pkg/util/http/server.go
Normal file
87
pkg/util/http/server.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
package httputil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Prm groups the required parameters of the Server's constructor.
|
||||
//
|
||||
// All values must comply with the requirements imposed on them.
|
||||
// Passing incorrect parameter values will result in constructor
|
||||
// failure (error or panic depending on the implementation).
|
||||
type Prm struct {
|
||||
// TCP address for the server to listen on.
|
||||
//
|
||||
// Must be a valid TCP address.
|
||||
Address string
|
||||
|
||||
// Must not be nil.
|
||||
Handler http.Handler
|
||||
}
|
||||
|
||||
// Server represents a wrapper over http.Server
|
||||
// that provides interface to start and stop
|
||||
// listening routine.
|
||||
//
|
||||
// For correct operation, Server must be created
|
||||
// using the constructor (New) based on the required parameters
|
||||
// and optional components. After successful creation,
|
||||
// Server is immediately ready to work through API.
|
||||
type Server struct {
|
||||
shutdownTimeout time.Duration
|
||||
|
||||
srv *http.Server
|
||||
}
|
||||
|
||||
const invalidValFmt = "invalid %s %s (%T): %v"
|
||||
|
||||
func panicOnPrmValue(n string, v interface{}) {
|
||||
panicOnValue("parameter", n, v)
|
||||
}
|
||||
|
||||
func panicOnOptValue(n string, v interface{}) {
|
||||
panicOnValue("option", n, v)
|
||||
}
|
||||
|
||||
func panicOnValue(t, n string, v interface{}) {
|
||||
panic(fmt.Sprintf(invalidValFmt, t, n, v, v))
|
||||
}
|
||||
|
||||
// New creates a new instance of the Server.
|
||||
//
|
||||
// Panics if at least one value of the parameters is invalid.
|
||||
//
|
||||
// Panics if at least one of next optinal parameters is invalid:
|
||||
// * shutdown timeout is non-positive.
|
||||
//
|
||||
// The created Server does not require additional
|
||||
// initialization and is completely ready for work.
|
||||
func New(prm Prm, opts ...Option) *Server {
|
||||
switch {
|
||||
case prm.Address == "":
|
||||
panicOnPrmValue("Address", prm.Address)
|
||||
case prm.Handler == nil:
|
||||
panicOnPrmValue("Handler", prm.Handler)
|
||||
}
|
||||
|
||||
c := defaultCfg()
|
||||
|
||||
for _, o := range opts {
|
||||
o(c)
|
||||
}
|
||||
|
||||
switch {
|
||||
case c.shutdownTimeout <= 0:
|
||||
panicOnOptValue("shutdown timeout", c.shutdownTimeout)
|
||||
}
|
||||
|
||||
return &Server{
|
||||
shutdownTimeout: c.shutdownTimeout,
|
||||
srv: &http.Server{
|
||||
Addr: prm.Address,
|
||||
Handler: prm.Handler,
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue