chore: add concurrent route check Requests

This commit is contained in:
Jonas Kaninda
2024-10-31 07:02:51 +01:00
committed by Jonas Kaninda
parent ffa128f637
commit 778a098bdc
3 changed files with 25 additions and 20 deletions

View File

@@ -52,7 +52,7 @@ func Warn(msg string, args ...interface{}) {
// Error error message // Error error message
func Error(msg string, args ...interface{}) { func Error(msg string, args ...interface{}) {
log.SetOutput(getStd(util.GetStringEnv("GOMA_ERROR_LOG", "/dev/stdout"))) log.SetOutput(getStd(util.GetStringEnv("GOMA_ERROR_LOG", "/dev/stderr")))
formattedMessage := fmt.Sprintf(msg, args...) formattedMessage := fmt.Sprintf(msg, args...)
if len(args) == 0 { if len(args) == 0 {
log.Printf("ERROR: %s\n", msg) log.Printf("ERROR: %s\n", msg)

View File

@@ -20,6 +20,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/jkaninda/goma-gateway/internal/logger" "github.com/jkaninda/goma-gateway/internal/logger"
"net/http" "net/http"
"sync"
) )
// CORSHandler handles CORS headers for incoming requests // CORSHandler handles CORS headers for incoming requests
@@ -69,33 +70,34 @@ func ProxyErrorHandler(w http.ResponseWriter, r *http.Request, err error) {
// HealthCheckHandler handles health check of routes // HealthCheckHandler handles health check of routes
func (heathRoute HealthCheckRoute) HealthCheckHandler(w http.ResponseWriter, r *http.Request) { func (heathRoute HealthCheckRoute) HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
logger.Info("%s %s %s %s", r.Method, r.RemoteAddr, r.URL, r.UserAgent()) logger.Info("%s %s %s %s", r.Method, r.RemoteAddr, r.URL, r.UserAgent())
wg := sync.WaitGroup{}
wg.Add(len(heathRoute.Routes))
var routes []HealthCheckRouteResponse var routes []HealthCheckRouteResponse
for _, route := range heathRoute.Routes { for _, route := range heathRoute.Routes {
if route.HealthCheck != "" { go func() {
err := HealthCheck(route.Destination + route.HealthCheck) if route.HealthCheck != "" {
if err != nil { err := HealthCheck(route.Destination + route.HealthCheck)
logger.Error("Route %s: %v", route.Name, err) if err != nil {
if heathRoute.DisableRouteHealthCheckError { if heathRoute.DisableRouteHealthCheckError {
routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "unhealthy", Error: "Route healthcheck errors disabled"}) routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "unhealthy", Error: "Route healthcheck errors disabled"})
continue }
routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "unhealthy", Error: "Error: " + err.Error()})
} else {
logger.Info("Route %s is healthy", route.Name)
routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "healthy", Error: ""})
} }
routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "unhealthy", Error: err.Error()})
continue
} else { } else {
logger.Info("Route %s is healthy", route.Name) logger.Warn("Route %s's healthCheck is undefined", route.Name)
routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "healthy", Error: ""}) routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "undefined", Error: ""})
continue
} }
} else { defer wg.Done()
logger.Warn("Route %s's healthCheck is undefined", route.Name) }()
routes = append(routes, HealthCheckRouteResponse{Name: route.Name, Status: "undefined", Error: ""})
continue
}
} }
wg.Wait() // Wait for all requests to complete
response := HealthCheckResponse{ response := HealthCheckResponse{
Status: "healthy", Status: "healthy", //Goma proxy
Routes: routes, Routes: routes, // Routes health check
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)

View File

@@ -17,6 +17,7 @@ limitations under the License.
*/ */
import ( import (
"fmt" "fmt"
"github.com/jkaninda/goma-gateway/internal/logger"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@@ -52,6 +53,7 @@ func HealthCheck(healthURL string) error {
client := &http.Client{} client := &http.Client{}
healthResp, err := client.Do(healthReq) healthResp, err := client.Do(healthReq)
if err != nil { if err != nil {
logger.Error("Error performing HealthCheck request: %v ", err)
return fmt.Errorf("error performing HealthCheck request: %v ", err) return fmt.Errorf("error performing HealthCheck request: %v ", err)
} }
defer func(Body io.ReadCloser) { defer func(Body io.ReadCloser) {
@@ -61,6 +63,7 @@ func HealthCheck(healthURL string) error {
}(healthResp.Body) }(healthResp.Body)
if healthResp.StatusCode >= 400 { if healthResp.StatusCode >= 400 {
logger.Debug("Error performing HealthCheck request: %v ", err)
return fmt.Errorf("health check failed with status code %v", healthResp.StatusCode) return fmt.Errorf("health check failed with status code %v", healthResp.StatusCode)
} }
return nil return nil