Files
webhooker/internal/healthcheck/healthcheck.go
T
clawbot 21aafbf928
check / check (push) Successful in 3m25s
Remove the no-op MAINTENANCE_MODE setting (closes #317)
MAINTENANCE_MODE did nothing but make the healthcheck JSON report maintenanceMode: true; no request was ever served differently, so an operator who set it expecting requests to be refused got nothing. It is removed from the configuration, the startup configuration log line, the healthcheck JSON, the README and the Settings page, together with the uncalled Server.MaintenanceMode method and the healthcheck's dependency on the configuration. A leftover value in an environment is ignored like any other unknown variable.

Model: opus-5-5
2026-10-02 13:27:43 +02:00

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 = &params
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)
}