Created
April 27, 2022 16:08
-
-
Save bowei/9ff54e863fab1ab7439b023c0ad642e8 to your computer and use it in GitHub Desktop.
Simple file to HTTP healthcheck proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Serves the resultFile as a response to queries. This is useful for | |
// assembling a custom healthcheck as a sidecar. | |
// | |
// resultFile is of format <status code> SPACE <response text> | |
// | |
// You should have a script that does the custom set of healthchecking | |
// on your apps and write a resulting status file. | |
// | |
// Example | |
// | |
// #!/bin/bash | |
// while true; do | |
// healthy=0 | |
// if curl localhost:9000 1>/dev/null 2>/dev/null; then | |
// healthy=1 | |
// fi | |
// # other checks. | |
// if [[ ${healthy} = "1" ]]; then | |
// echo "200 ok" > /result | |
// else | |
// echo "500 unhealthy" > /result | |
// fi | |
// done | |
package main | |
import ( | |
"flag" | |
"fmt" | |
"log" | |
"net/http" | |
"os" | |
"strconv" | |
"strings" | |
) | |
var f = struct { | |
bindAddr string | |
resultFile string | |
}{ | |
bindAddr: ":8080", | |
resultFile: "/result", | |
} | |
func handle(w http.ResponseWriter, r *http.Request) { | |
resultText, err := os.ReadFile(f.resultFile) | |
if err != nil { | |
log.Fatalf("os.ReadFile(%q) = _, %v", err) | |
} | |
result := strings.SplitN(string(resultText), " ", 2) | |
if len(result) != 2 { | |
w.WriteHeader(500) | |
err := fmt.Errorf("Invalid resultsText format (%q)", resultText) | |
fmt.Fprintf(w, "%v\n", err) | |
log.Print(err) | |
return | |
} | |
code, err := strconv.Atoi(result[0]) | |
if err != nil { | |
w.WriteHeader(500) | |
err := fmt.Errorf("Invalid resultText %q: invalid status code", resultText) | |
fmt.Fprintf(w, "%v\n", err) | |
log.Print(err) | |
return | |
} | |
if code < 200 || code >= 600 { | |
w.WriteHeader(500) | |
err := fmt.Errorf("Invalid resultText %q: invalid status code value", resultText) | |
fmt.Fprintf(w, "%v\n", err) | |
log.Print(err) | |
return | |
} | |
w.WriteHeader(int(code)) | |
w.Write([]byte(result[1])) | |
} | |
func main() { | |
flag.StringVar(&f.bindAddr, "bindAddr", f.bindAddr, "Address to bind healthcheck response from") | |
flag.StringVar(&f.resultFile, "resultFile", f.resultFile, `Location of the result file. File should be a single line of the format <status code> SPACE <response>; example: "500 server is unhealthy"`) | |
flag.Parse() | |
http.HandleFunc("/", handle) | |
log.Printf("Listening on %q", f.bindAddr) | |
log.Fatal(http.ListenAndServe(f.bindAddr, nil)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment