mirror of
https://github.com/openfaas/faas.git
synced 2025-06-10 09:16:48 +00:00
During some exploratory testing, I ran into an issue where the gateway would attempt to scale a deployment from zero replicas to min, despite there already being min replicas. Why? The scaling logic was looking for Available replicas when it should have looked for Desired replicas. So when a deployment had zero ready replicas due to readiness checks failing, the gateway was attempting to scale from zero to min. This logic has been corrected and separated from the a holding pattern where the gateway waits for a ready replica. Tested with KinD and an edited function which had a readiness probe, which was failing and no ready replicas. As desired, the gateway did not scale to min. However, when setting desired replicas to zero, the gateway did scale up as expected. This change also modifies all print statements for "seconds" and makes them use 4 decimal places instead of the default which was a longer, more verbose string for the logs. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.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] - %.4fs", method, originalURL, statusCode, duration.Seconds())
|
|
}
|
|
}
|