check / check (push) Successful in 3m34s
fx wrote its own steps of starting and stopping as plain text to stderr. It now logs them with its slog event logger through the backend's logger, so off a terminal every line the backend's own logger and fx write is JSON. A malformed config file now makes config.New return the error instead of panicking. A test runs the server as a child process and checks that all it writes is JSON, on a normal start and stop and with such a config file. The backend logs its name, version and architecture once at start. The health check's uptime keys are now uptime_seconds and uptime_human; its type and method take the names GO_HTTP_SERVER_CONVENTIONS.md gives. Model: opus-5-5
90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
// Package main is the entry point for netwatch-server.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/user"
|
|
|
|
"sneak.berlin/go/netwatch/internal/config"
|
|
"sneak.berlin/go/netwatch/internal/globals"
|
|
"sneak.berlin/go/netwatch/internal/handlers"
|
|
"sneak.berlin/go/netwatch/internal/healthcheck"
|
|
"sneak.berlin/go/netwatch/internal/logger"
|
|
"sneak.berlin/go/netwatch/internal/middleware"
|
|
"sneak.berlin/go/netwatch/internal/reportbuf"
|
|
"sneak.berlin/go/netwatch/internal/server"
|
|
|
|
"go.uber.org/fx"
|
|
"go.uber.org/fx/fxevent"
|
|
)
|
|
|
|
//nolint:gochecknoglobals // set via ldflags at build time
|
|
var (
|
|
Appname = "netwatch-server"
|
|
Version string
|
|
)
|
|
|
|
func main() {
|
|
// "netwatch-server check-cidr CIDR" exits 1, with the error, if
|
|
// this server would refuse CIDR in its TRUSTED_PROXIES.
|
|
// bin/entrypoint.sh runs it on each entry it gives nginx.
|
|
if len(os.Args) == 3 && os.Args[1] == "check-cidr" {
|
|
_, err := middleware.ParseTrustedProxies(os.Args[2:])
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// "netwatch-server prepare-data-dir DATA_DIR" gets DATA_DIR ready
|
|
// for the netwatch user, or exits 1 with the error; see
|
|
// reportbuf.PrepareDataDir. bin/entrypoint.sh runs it as root
|
|
// before it starts this server as that user.
|
|
if len(os.Args) == 3 && os.Args[1] == "prepare-data-dir" {
|
|
netwatch, err := user.Lookup("netwatch")
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
err = reportbuf.PrepareDataDir("/data", os.Args[2], netwatch)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "DATA_DIR '%s': %v\n", os.Args[2], err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
globals.Appname = Appname
|
|
globals.Version = Version
|
|
|
|
fx.New(
|
|
// fx logs each step of starting and stopping through the
|
|
// server's own logger, so off a terminal those lines are
|
|
// JSON like every other line.
|
|
fx.WithLogger(func(log *logger.Logger) fxevent.Logger {
|
|
return &fxevent.SlogLogger{Logger: log.Get()}
|
|
}),
|
|
fx.Provide(
|
|
config.New,
|
|
globals.New,
|
|
handlers.New,
|
|
healthcheck.New,
|
|
logger.New,
|
|
middleware.New,
|
|
reportbuf.New,
|
|
server.New,
|
|
),
|
|
fx.Invoke(
|
|
// First, so the name and version are logged even when
|
|
// a setting stops the start.
|
|
func(log *logger.Logger) { log.Identify() },
|
|
func(*server.Server) {},
|
|
),
|
|
).Run()
|
|
}
|