check / check (push) Waiting to run
MAINTENANCE_MODE only made the healthcheck report maintenanceMode: true; no request was ever served differently. It is removed from the configuration, the healthcheck JSON, the README and the Settings page, together with the unused Server.MaintenanceMode method and the healthcheck's Config dependency, which existed only to read it. A leftover MAINTENANCE_MODE in the environment is not read, so it is ignored rather than refused. Model: opus-5-5
83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
// Package healthcheck provides application health status reporting.
|
|
package healthcheck
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"go.uber.org/fx"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
"sneak.berlin/go/webhooker/internal/globals"
|
|
"sneak.berlin/go/webhooker/internal/logger"
|
|
)
|
|
|
|
//nolint:revive // HealthcheckParams is a standard fx naming convention.
|
|
type HealthcheckParams struct {
|
|
fx.In
|
|
|
|
Globals *globals.Globals
|
|
Logger *logger.Logger
|
|
Database *database.Database
|
|
}
|
|
|
|
// Healthcheck tracks application uptime and reports health status.
|
|
type Healthcheck struct {
|
|
StartupTime time.Time
|
|
log *slog.Logger
|
|
params *HealthcheckParams
|
|
}
|
|
|
|
// New creates a Healthcheck that records the startup time on fx
|
|
// start.
|
|
func New(
|
|
lc fx.Lifecycle,
|
|
params HealthcheckParams,
|
|
) (*Healthcheck, error) {
|
|
s := new(Healthcheck)
|
|
s.params = ¶ms
|
|
s.log = params.Logger.Get()
|
|
|
|
lc.Append(fx.Hook{
|
|
OnStart: func(_ context.Context) error {
|
|
s.StartupTime = time.Now()
|
|
|
|
return nil
|
|
},
|
|
OnStop: func(_ context.Context) error {
|
|
return nil
|
|
},
|
|
})
|
|
|
|
return s, nil
|
|
}
|
|
|
|
// Healthcheck returns the current health status of the
|
|
// application.
|
|
func (s *Healthcheck) Healthcheck() *Response {
|
|
resp := &Response{
|
|
Status: "ok",
|
|
Now: time.Now().UTC().Format(time.RFC3339Nano),
|
|
UptimeSeconds: int64(s.uptime().Seconds()),
|
|
UptimeHuman: s.uptime().String(),
|
|
Appname: s.params.Globals.Appname,
|
|
Version: s.params.Globals.Version,
|
|
}
|
|
|
|
return resp
|
|
}
|
|
|
|
// Response contains the JSON-serialised health status.
|
|
type Response struct {
|
|
Status string `json:"status"`
|
|
Now string `json:"now"`
|
|
UptimeSeconds int64 `json:"uptimeSeconds"`
|
|
UptimeHuman string `json:"uptimeHuman"`
|
|
Version string `json:"version"`
|
|
Appname string `json:"appname"`
|
|
}
|
|
|
|
func (s *Healthcheck) uptime() time.Duration {
|
|
return time.Since(s.StartupTime)
|
|
}
|