Foundation Doctor
Foundation Doctor is an opt-in startup check for foundation-based services. It is compiled into the application only when the run_foundation_doctor build tag is set.
go build -tags run_foundation_doctor -o api ./cmd/api
FOUNDATION_DOCTOR=fail ./api
Without the tag, startup keeps the normal path.
Modes
FOUNDATION_DOCTOR controls what happens at startup:
| Value | Behavior |
|---|---|
off |
Skip checks. |
print or empty |
Print a text report and continue. |
json |
Print a JSON report and continue. |
fail |
Print a text report and stop startup when a failure is found. |
Unknown values are treated like print.
Checks
The first version checks the HTTP route table exposed by web.Server:
- At least one route is registered.
- No duplicate
METHOD pathpair exists.
- A liveness route exists at
GET /healthorGET /health/live.
- A readiness route exists at
GET /health/ready.
Missing routes are failures. Missing health routes are warnings, because some services are not HTTP-first.
Automatic Integration
The build tag activates startup hooks in app and app/web.
a := app.New()
a.RegisterHTTP(&GetUser{})
if err := a.Listen(":8080"); err != nil {
log.Fatal(err)
}
With run_foundation_doctor, app.Listen runs the doctor after Build has registered handlers and before the HTTP host starts.
The same tag also runs the doctor when a project starts web.Server directly:
server := web.New()
server.MapGet("/health/live", live)
server.MapGet("/health/ready", ready)
log.Fatal(server.ListenAndServe(":8080"))
hosting.ConfigureWeb uses web.Server, so that path is covered too.
Direct Use
Projects that bypass Foundation startup and pass a handler to net/http directly can call the package themselves.
report := doctor.CheckSource(doctor.Source{
Routes: []doctor.Route{
{Method: "GET", Path: "/health/live"},
{Method: "GET", Path: "/health/ready"},
},
})
if report.Failures() > 0 {
os.Exit(1)
}