mirror of
https://github.com/shizunge/endlessh-go.git
synced 2026-08-07 07:15:02 +00:00
healthcheck: json response
This commit is contained in:
+41
-17
@@ -17,7 +17,9 @@
|
||||
package health
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -27,36 +29,58 @@ import (
|
||||
const (
|
||||
DefaultHost = "127.0.0.1"
|
||||
DefaultPort = "51000"
|
||||
DefaultPath = "/health"
|
||||
DefaultTimeout = 3 * time.Second
|
||||
)
|
||||
|
||||
type response struct {
|
||||
Status string `json:"status"` // always "ok"
|
||||
Uptime float64 `json:"uptime"` // in seconds
|
||||
}
|
||||
|
||||
var startTime time.Time
|
||||
|
||||
func StartListener(host, port string) {
|
||||
addr := host + ":" + port
|
||||
startTime = time.Now()
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc(DefaultPath, handleHealth)
|
||||
addr := net.JoinHostPort(host, port)
|
||||
go func() {
|
||||
l, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
glog.Infof("Starting healthcheck on http://%v%v", addr, DefaultPath)
|
||||
if err := http.ListenAndServe(addr, mux); err != nil {
|
||||
glog.Errorf("Error listening for healthcheck on %v: %v", addr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer l.Close()
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
glog.Errorf("Error accepting healthcheck connection: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
conn.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(response{
|
||||
Status: "ok",
|
||||
Uptime: time.Since(startTime).Seconds(),
|
||||
})
|
||||
}
|
||||
|
||||
func Probe(host, port string) bool {
|
||||
addr := host + ":" + port
|
||||
timeout := DefaultTimeout
|
||||
conn, err := net.DialTimeout("tcp", addr, timeout)
|
||||
addr := net.JoinHostPort(host, port)
|
||||
url := "http://" + addr + DefaultPath
|
||||
client := &http.Client{Timeout: DefaultTimeout}
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
conn.Close()
|
||||
return true
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return false
|
||||
}
|
||||
var body response
|
||||
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
|
||||
return false
|
||||
}
|
||||
return body.Status == "ok"
|
||||
}
|
||||
|
||||
@@ -147,8 +147,8 @@ func main() {
|
||||
proxyProtocolEnabled := flag.Bool("proxy_protocol_enabled", false, "Enable PROXY protocol support. This causes the server to expect PROXY protocol headers on incoming connections.")
|
||||
proxyProtocolReadHeaderTimeout := flag.Int("proxy_protocol_read_header_timeout_ms", 200, "Timeout for reading the PROXY protocol header in milliseconds. If the connection does not send a valid PROXY protocol header in this time, the header is ignored.")
|
||||
healthcheckHost := flag.String("healthcheck_host", health.DefaultHost, "The address for container healthcheck")
|
||||
healthcheckPort := flag.String("healthcheck_port", health.DefaultPort, "TCP port for container healthcheck; accepts connection and closes without logging or updating metrics")
|
||||
healthcheck := flag.Bool("healthcheck", false, "Dial healthcheck_host:healthcheck_port and exit 0 if reachable (for container healthcheck)")
|
||||
healthcheckPort := flag.String("healthcheck_port", health.DefaultPort, "HTTP port for container healthcheck; serves JSON with status and uptime at /health")
|
||||
healthcheck := flag.Bool("healthcheck", false, "GET healthcheck_host:healthcheck_port/health and exit 1 if status is not ok or timeout is exceeded (for container healthcheck)")
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Usage of %v \n", os.Args[0])
|
||||
|
||||
Reference in New Issue
Block a user