mirror of
https://github.com/openfaas/faas.git
synced 2025-06-15 19:56:47 +00:00
Introduces a single-flight call to a function's health endpoint to verify that it is registered with an Istio sidecar (Envoy) before letting the invocation through. Results are cached for 5 seconds, before a probe is required again. Tested without Istio, with probe_functions environment variable set to true, I saw a probe execute in the logs. Fixes: #1721 for Istio users. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alex@openfaas.com>
88 lines
2.5 KiB
Go
88 lines
2.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/openfaas/faas/gateway/metrics"
|
|
"github.com/openfaas/faas/gateway/pkg/middleware"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
// HTTPNotifier notify about HTTP request/response
|
|
type HTTPNotifier interface {
|
|
Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration)
|
|
}
|
|
|
|
// PrometheusServiceNotifier notifier for core service endpoints
|
|
type PrometheusServiceNotifier struct {
|
|
ServiceMetrics *metrics.ServiceMetricOptions
|
|
}
|
|
|
|
// Notify about service metrics
|
|
func (psn PrometheusServiceNotifier) Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration) {
|
|
code := fmt.Sprintf("%d", statusCode)
|
|
path := urlToLabel(URL)
|
|
|
|
psn.ServiceMetrics.Counter.WithLabelValues(method, path, code).Inc()
|
|
psn.ServiceMetrics.Histogram.WithLabelValues(method, path, code).Observe(duration.Seconds())
|
|
}
|
|
|
|
func urlToLabel(path string) string {
|
|
if len(path) > 0 {
|
|
path = strings.TrimRight(path, "/")
|
|
}
|
|
if path == "" {
|
|
path = "/"
|
|
}
|
|
return path
|
|
}
|
|
|
|
// PrometheusFunctionNotifier records metrics to Prometheus
|
|
type PrometheusFunctionNotifier struct {
|
|
Metrics *metrics.MetricOptions
|
|
//FunctionNamespace default namespace of the function
|
|
FunctionNamespace string
|
|
}
|
|
|
|
// Notify records metrics in Prometheus
|
|
func (p PrometheusFunctionNotifier) Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration) {
|
|
serviceName := middleware.GetServiceName(originalURL)
|
|
if len(p.FunctionNamespace) > 0 {
|
|
if !strings.Contains(serviceName, ".") {
|
|
serviceName = fmt.Sprintf("%s.%s", serviceName, p.FunctionNamespace)
|
|
}
|
|
}
|
|
|
|
code := strconv.Itoa(statusCode)
|
|
labels := prometheus.Labels{"function_name": serviceName, "code": code}
|
|
|
|
if event == "completed" {
|
|
seconds := duration.Seconds()
|
|
p.Metrics.GatewayFunctionsHistogram.
|
|
With(labels).
|
|
Observe(seconds)
|
|
|
|
p.Metrics.GatewayFunctionInvocation.
|
|
With(labels).
|
|
Inc()
|
|
} else if event == "started" {
|
|
p.Metrics.GatewayFunctionInvocationStarted.WithLabelValues(serviceName).Inc()
|
|
}
|
|
|
|
}
|
|
|
|
// LoggingNotifier notifies a log about a request
|
|
type LoggingNotifier struct {
|
|
}
|
|
|
|
// Notify the LoggingNotifier about a request
|
|
func (LoggingNotifier) Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration) {
|
|
if event == "completed" {
|
|
log.Printf("Forwarded [%s] to %s - [%d] - %fs seconds", method, originalURL, statusCode, duration.Seconds())
|
|
}
|
|
}
|