Introduce the Go backend (netwatch-server) with an HTTP API that accepts telemetry reports and persists them as zstd-compressed JSONL files. Reports are buffered in memory and flushed to disk when the buffer reaches 10 MiB or every 60 seconds.
83 lines
1.8 KiB
Go
83 lines
1.8 KiB
Go
// Package healthcheck provides a service that reports
|
|
// application health, uptime, and version information.
|
|
package healthcheck
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"sneak.berlin/go/netwatch/internal/config"
|
|
"sneak.berlin/go/netwatch/internal/globals"
|
|
"sneak.berlin/go/netwatch/internal/logger"
|
|
|
|
"go.uber.org/fx"
|
|
)
|
|
|
|
// Params defines the dependencies for Healthcheck.
|
|
type Params struct {
|
|
fx.In
|
|
|
|
Config *config.Config
|
|
Globals *globals.Globals
|
|
Logger *logger.Logger
|
|
}
|
|
|
|
// Healthcheck tracks startup time and builds health responses.
|
|
type Healthcheck struct {
|
|
StartupTime time.Time
|
|
log *slog.Logger
|
|
params *Params
|
|
}
|
|
|
|
// Response is the JSON payload returned by the health check
|
|
// endpoint.
|
|
type Response struct {
|
|
Appname string `json:"appname"`
|
|
Now string `json:"now"`
|
|
Status string `json:"status"`
|
|
UptimeHuman string `json:"uptimeHuman"`
|
|
UptimeSeconds int64 `json:"uptimeSeconds"`
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
// New creates a Healthcheck, recording startup time via an
|
|
// fx lifecycle hook.
|
|
func New(
|
|
lc fx.Lifecycle,
|
|
params Params,
|
|
) (*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().UTC()
|
|
|
|
return nil
|
|
},
|
|
OnStop: func(_ context.Context) error {
|
|
return nil
|
|
},
|
|
})
|
|
|
|
return s, nil
|
|
}
|
|
|
|
// Check returns the current health status of the application.
|
|
func (s *Healthcheck) Check() *Response {
|
|
return &Response{
|
|
Appname: s.params.Globals.Appname,
|
|
Now: time.Now().UTC().Format(time.RFC3339Nano),
|
|
Status: "ok",
|
|
UptimeHuman: s.uptime().String(),
|
|
UptimeSeconds: int64(s.uptime().Seconds()),
|
|
Version: s.params.Globals.Version,
|
|
}
|
|
}
|
|
|
|
func (s *Healthcheck) uptime() time.Duration {
|
|
return time.Since(s.StartupTime)
|
|
}
|