diff --git a/README.md b/README.md index 8c8c4df..fc94587 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,10 @@ export N8N_RUNNERS_AUTH_TOKEN=... make run ``` +## Health check + +The launcher exposes a health check endpoint at `/healthz` on port `5681` for liveness checks. + ## Release 1. Create a git tag following semver: diff --git a/cmd/launcher/main.go b/cmd/launcher/main.go index 68bb09a..29f64c6 100644 --- a/cmd/launcher/main.go +++ b/cmd/launcher/main.go @@ -2,9 +2,11 @@ package main import ( "flag" + "fmt" "os" "task-runner-launcher/internal/commands" + "task-runner-launcher/internal/http" "task-runner-launcher/internal/logs" ) @@ -20,6 +22,15 @@ func main() { os.Exit(1) } + srv := http.NewHealthCheckServer() + go func() { + if err := srv.Start(); err != nil { + fmt.Printf("Health check server failed to start: %s", err) + os.Exit(1) + } + }() + logs.Logger.Printf("Started healthcheck server on port %d", srv.Port) + runnerType := os.Args[1] cmd := &commands.LaunchCommand{RunnerType: runnerType} diff --git a/internal/http/healthcheck_server.go b/internal/http/healthcheck_server.go new file mode 100644 index 0000000..c4b93c5 --- /dev/null +++ b/internal/http/healthcheck_server.go @@ -0,0 +1,47 @@ +package http + +import ( + "encoding/json" + "fmt" + "net/http" +) + +const ( + defaultPort = 5681 + healthCheckPath = "/healthz" +) + +type healthCheckResponse struct { + Status string `json:"status"` +} + +type Server struct { + Port int +} + +func NewHealthCheckServer() *Server { + return &Server{ + Port: defaultPort, + } +} + +func (s *Server) Start() error { + http.HandleFunc(healthCheckPath, s.handleHealthCheck) + + addr := fmt.Sprintf(":%d", s.Port) + + return http.ListenAndServe(addr, nil) +} + +func (s *Server) handleHealthCheck(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + res := healthCheckResponse{Status: "ok"} + json.NewEncoder(w).Encode(res) +}