diff --git a/pkg/ratelimit/metrics/metrics.go b/pkg/ratelimit/metrics/metrics.go new file mode 100644 index 0000000000..1f1e6ef435 --- /dev/null +++ b/pkg/ratelimit/metrics/metrics.go @@ -0,0 +1,58 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" +) + +var register sync.Once + +const ( + rateLimitSubsystem = "rate_limit" + rateLimitLatencyKey = "rate_limit_delay_seconds" +) + +var ( + rateLimitLatencyMetricsLabels = []string{ + "key", // rate limiter key + } + + RateLimitLatency = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Subsystem: rateLimitSubsystem, + Name: rateLimitLatencyKey, + Help: "Latency of the RateLimiter Accept Operation", + // custom buckets = [0.5s, 1s, 2s, 4s, 8s, 16s, 32s, 64s, 128s, 256s(~4min), 512s(~8min), 1024s(~17min), 2048s(~34min), 4096s(~68min), +Inf] + Buckets: prometheus.ExponentialBuckets(0.5, 2, 14), + }, + rateLimitLatencyMetricsLabels, + ) +) + +func RegisterMetrics() { + register.Do(func() { + prometheus.MustRegister(RateLimitLatency) + }) +} + +func PublishRateLimiterMetrics(key string, start time.Time) { + RateLimitLatency.WithLabelValues(key).Observe(time.Since(start).Seconds()) +} diff --git a/pkg/ratelimit/ratelimit.go b/pkg/ratelimit/ratelimit.go index 95e6cab7cf..ece2310ade 100644 --- a/pkg/ratelimit/ratelimit.go +++ b/pkg/ratelimit/ratelimit.go @@ -27,6 +27,7 @@ import ( "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta" "k8s.io/client-go/util/flowcontrol" "k8s.io/ingress-gce/pkg/flags" + "k8s.io/ingress-gce/pkg/ratelimit/metrics" "k8s.io/klog/v2" ) @@ -39,6 +40,10 @@ type GCERateLimiter struct { operationPollInterval time.Duration } +func init() { + metrics.RegisterMetrics() +} + // NewGCERateLimiter parses the list of rate limiting specs passed in and // returns a properly configured cloud.RateLimiter implementation. // Expected format of specs: {"[version].[service].[operation],[type],[param1],[param2],..", "..."} @@ -99,7 +104,10 @@ func (grl *GCERateLimiter) Accept(ctx context.Context, key *cloud.RateLimitKey) } } - return rl.Accept(ctx, key) + start := time.Now() + err := rl.Accept(ctx, key) + metrics.PublishRateLimiterMetrics(fmt.Sprintf("%s.%s.%s", key.Version, key.Service, key.Operation), start) + return err } // rateLimitImpl returns the flowcontrol.RateLimiter implementation