middleman/command/healthcheck.go
2025-04-08 09:03:00 +02:00

87 lines
2.2 KiB
Go

package command
import (
"context"
"fmt"
"gitea.illuad.fr/adrien/middleman"
"gitea.illuad.fr/adrien/middleman/flag"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v3"
"golang.org/x/sync/errgroup"
"net/http"
)
// healthcheck is the structure representing the command described below.
type healthcheck struct {
group *errgroup.Group
}
// HealthcheckCmd is the command name.
const HealthcheckCmd = "healthcheck"
const (
// healthcheckURLFlagName is the flag name used to set the healthcheck URL.
healthcheckURLFlagName = "healthcheck-url"
)
const (
// defaultHealthcheckURL is the default healthcheck URL.
defaultHealthcheckURL = "http://127.0.0.1:5732/healthz"
)
var h healthcheck
// Healthcheck describes the healthcheck command.
func Healthcheck(group *errgroup.Group) *cli.Command {
h.group = group
return &cli.Command{
Name: HealthcheckCmd,
Aliases: middleman.PluckAlias(HealthcheckCmd, HealthcheckCmd),
Usage: "Runs healthcheck mode",
Description: "Perform HTTP HEAD request to the health endpoint",
Flags: []cli.Flag{
healthcheckURL(),
flag.LogFormat(HealthcheckCmd),
flag.LogLevel(HealthcheckCmd),
},
Before: before,
Action: h.action,
}
}
// action is executed when the HealthcheckCmd command is called.
func (h healthcheck) action(ctx context.Context, command *cli.Command) error {
if err := ctx.Err(); err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodHead, command.String(healthcheckURLFlagName), http.NoBody)
if err != nil {
return err
}
var res *http.Response
res, err = http.DefaultClient.Do(req)
if err != nil {
return err
}
defer func() {
if err = res.Body.Close(); err != nil {
log.Err(err).Send()
}
}()
if res.StatusCode != http.StatusOK {
return fmt.Errorf("healthcheck failed with the following HTTP code: %d (%s)", res.StatusCode, http.StatusText(res.StatusCode))
}
return nil
}
func healthcheckURL() cli.Flag {
return &cli.StringFlag{
Name: healthcheckURLFlagName,
Category: "monitoring",
Usage: "full healthcheck URL (protocol, address and path)",
Sources: middleman.PluckEnvVar(EnvVarPrefix, healthcheckURLFlagName),
Value: defaultHealthcheckURL,
Aliases: middleman.PluckAlias(HealthcheckCmd, healthcheckURLFlagName),
}
}