Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic server probes #10301

Merged
merged 9 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions ocis-pkg/handlers/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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)
}

Expand All @@ -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
Expand All @@ -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 changes: 23 additions & 0 deletions ocis-pkg/handlers/checkhttp.go
Original file line number Diff line number Diff line change
@@ -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
}
}
6 changes: 4 additions & 2 deletions services/activitylog/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/graph/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
15 changes: 11 additions & 4 deletions services/idp/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -28,7 +34,8 @@ func Server(opts ...Option) (*http.Server, error) {
}

return handlers.NewTCPCheck(tcpURL)(ctx)
}),
}).
WithInheritedChecksFrom(healthHandler.Conf),
)

return debug.NewService(
Expand All @@ -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
}
3 changes: 2 additions & 1 deletion services/invitations/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/ocs/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/proxy/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion services/settings/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/sse/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/thumbnails/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/userlog/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
21 changes: 2 additions & 19 deletions services/web/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/webdav/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion services/webfinger/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down