mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 20:29:54 -06:00
Merge pull request #10301 from dragonchaser/basic-server-probes
Basic server probes
This commit is contained in:
@@ -17,8 +17,9 @@ type check func(ctx context.Context) error
|
||||
|
||||
// CheckHandlerConfiguration defines the configuration for the CheckHandler.
|
||||
type CheckHandlerConfiguration struct {
|
||||
Checks map[string]check
|
||||
|
||||
logger log.Logger
|
||||
checks map[string]check
|
||||
limit int
|
||||
statusFailed int
|
||||
statusSuccess int
|
||||
@@ -27,7 +28,8 @@ type CheckHandlerConfiguration struct {
|
||||
// NewCheckHandlerConfiguration initializes a new CheckHandlerConfiguration.
|
||||
func NewCheckHandlerConfiguration() CheckHandlerConfiguration {
|
||||
return CheckHandlerConfiguration{
|
||||
checks: make(map[string]check),
|
||||
Checks: make(map[string]check),
|
||||
|
||||
limit: -1,
|
||||
statusFailed: http.StatusInternalServerError,
|
||||
statusSuccess: http.StatusOK,
|
||||
@@ -42,17 +44,17 @@ func (c CheckHandlerConfiguration) WithLogger(l log.Logger) CheckHandlerConfigur
|
||||
|
||||
// WithCheck sets a check for the CheckHandlerConfiguration.
|
||||
func (c CheckHandlerConfiguration) WithCheck(name string, f check) CheckHandlerConfiguration {
|
||||
if _, ok := c.checks[name]; ok {
|
||||
if _, ok := c.Checks[name]; ok {
|
||||
c.logger.Panic().Str("check", name).Msg("check already exists")
|
||||
}
|
||||
|
||||
c.checks[name] = f
|
||||
c.Checks[name] = f
|
||||
return c
|
||||
}
|
||||
|
||||
// WithInheritedChecksFrom appends the checks from another CheckHandlerConfiguration.
|
||||
func (c CheckHandlerConfiguration) WithInheritedChecksFrom(other CheckHandlerConfiguration) CheckHandlerConfiguration {
|
||||
for name, check := range other.checks {
|
||||
for name, check := range other.Checks {
|
||||
c.WithCheck(name, check)
|
||||
}
|
||||
|
||||
@@ -79,27 +81,27 @@ func (c CheckHandlerConfiguration) WithStatusSuccess(status int) CheckHandlerCon
|
||||
|
||||
// CheckHandler is a http Handler that performs different checks.
|
||||
type CheckHandler struct {
|
||||
conf CheckHandlerConfiguration
|
||||
Conf CheckHandlerConfiguration
|
||||
}
|
||||
|
||||
// NewCheckHandler initializes a new CheckHandler.
|
||||
func NewCheckHandler(c CheckHandlerConfiguration) *CheckHandler {
|
||||
c.checks = maps.Clone(c.checks) // prevent check duplication after initialization
|
||||
c.Checks = maps.Clone(c.Checks) // prevent check duplication after initialization
|
||||
return &CheckHandler{
|
||||
conf: c,
|
||||
Conf: c,
|
||||
}
|
||||
}
|
||||
|
||||
// AddCheck adds a check to the CheckHandler.
|
||||
func (h *CheckHandler) AddCheck(name string, c check) {
|
||||
h.conf.WithCheck(name, c)
|
||||
h.Conf.WithCheck(name, c)
|
||||
}
|
||||
|
||||
func (h *CheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
g, ctx := errgroup.WithContext(r.Context())
|
||||
g.SetLimit(h.conf.limit)
|
||||
g.SetLimit(h.Conf.limit)
|
||||
|
||||
for name, check := range h.conf.checks {
|
||||
for name, check := range h.Conf.Checks {
|
||||
checker := check
|
||||
checkerName := name
|
||||
g.Go(func() error { // https://go.dev/blog/loopvar-preview per iteration scope since go 1.22
|
||||
@@ -111,16 +113,16 @@ func (h *CheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
status := h.conf.statusSuccess
|
||||
status := h.Conf.statusSuccess
|
||||
if err := g.Wait(); err != nil {
|
||||
status = h.conf.statusFailed
|
||||
h.conf.logger.Error().Err(err).Msg("check failed")
|
||||
status = h.Conf.statusFailed
|
||||
h.Conf.logger.Error().Err(err).Msg("check failed")
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(status)
|
||||
|
||||
if _, err := io.WriteString(w, http.StatusText(status)); err != nil { // io.WriteString should not fail, but if it does, we want to know.
|
||||
h.conf.logger.Panic().Err(err).Msg("failed to write response")
|
||||
h.Conf.logger.Panic().Err(err).Msg("failed to write response")
|
||||
}
|
||||
}
|
||||
|
||||
23
ocis-pkg/handlers/checkhttp.go
Normal file
23
ocis-pkg/handlers/checkhttp.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NewHttpCheck checks the reachability of a http server.
|
||||
func NewHTTPCheck(url string) func(context.Context) error {
|
||||
return func(_ context.Context) error {
|
||||
c := http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
resp, err := c.Get(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not connect to http server: %v", err)
|
||||
}
|
||||
_ = resp.Body.Close()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,15 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
healthHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("http reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
readyHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)),
|
||||
WithCheck("nats reachability", handlers.NewNatsCheck(options.Config.Events.Cluster)).
|
||||
WithInheritedChecksFrom(healthHandler.Conf),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,13 @@ import (
|
||||
func Server(opts ...Option) (*http.Server, error) {
|
||||
options := newOptions(opts...)
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
healthHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("http reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
readinessHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("tcp-check", func(ctx context.Context) error {
|
||||
@@ -28,7 +34,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
}
|
||||
|
||||
return handlers.NewTCPCheck(tcpURL)(ctx)
|
||||
}),
|
||||
}).
|
||||
WithInheritedChecksFrom(healthHandler.Conf),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
@@ -39,7 +46,7 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
debug.Token(options.Config.Debug.Token),
|
||||
debug.Pprof(options.Config.Debug.Pprof),
|
||||
debug.Zpages(options.Config.Debug.Zpages),
|
||||
debug.Health(checkHandler),
|
||||
debug.Ready(checkHandler),
|
||||
debug.Health(healthHandler),
|
||||
debug.Ready(readinessHandler),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -18,7 +18,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
var configDumpFunc http.HandlerFunc = configDump(options.Config)
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/version"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Server initializes the debug service and server.
|
||||
@@ -17,20 +13,7 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger).WithCheck("web reachability", func(ctx context.Context) error {
|
||||
conn, err := net.Dial("tcp", options.Config.HTTP.Addr)
|
||||
defer func(conn net.Conn) {
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(conn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not connect to web server: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
WithLogger(options.Logger).WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
@@ -14,7 +14,8 @@ func Server(opts ...Option) (*http.Server, error) {
|
||||
|
||||
checkHandler := handlers.NewCheckHandler(
|
||||
handlers.NewCheckHandlerConfiguration().
|
||||
WithLogger(options.Logger),
|
||||
WithLogger(options.Logger).
|
||||
WithCheck("web reachability", handlers.NewHTTPCheck(options.Config.HTTP.Addr)),
|
||||
)
|
||||
|
||||
return debug.NewService(
|
||||
|
||||
Reference in New Issue
Block a user