k8s.io/apiserver@v0.31.1/plugin/pkg/authorizer/webhook/metrics/metrics.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package metrics
    18  
    19  import (
    20  	"context"
    21  	"sync"
    22  
    23  	"k8s.io/apiserver/pkg/authorization/cel"
    24  	compbasemetrics "k8s.io/component-base/metrics"
    25  	"k8s.io/component-base/metrics/legacyregistry"
    26  )
    27  
    28  // AuthorizerMetrics specifies a set of methods that are used to register various metrics for the webhook authorizer
    29  type AuthorizerMetrics interface {
    30  	// Request total and latency metrics
    31  	RequestMetrics
    32  	// Webhook count, latency, and fail open metrics
    33  	WebhookMetrics
    34  	// match condition metrics
    35  	cel.MatcherMetrics
    36  }
    37  
    38  type NoopAuthorizerMetrics struct {
    39  	NoopRequestMetrics
    40  	NoopWebhookMetrics
    41  	cel.NoopMatcherMetrics
    42  }
    43  
    44  type RequestMetrics interface {
    45  	// RecordRequestTotal increments the total number of requests for the webhook authorizer
    46  	RecordRequestTotal(ctx context.Context, code string)
    47  
    48  	// RecordRequestLatency measures request latency in seconds for webhooks. Broken down by status code.
    49  	RecordRequestLatency(ctx context.Context, code string, latency float64)
    50  }
    51  
    52  type NoopRequestMetrics struct{}
    53  
    54  func (NoopRequestMetrics) RecordRequestTotal(context.Context, string)            {}
    55  func (NoopRequestMetrics) RecordRequestLatency(context.Context, string, float64) {}
    56  
    57  type WebhookMetrics interface {
    58  	// RecordWebhookEvaluation increments with each round-trip of a webhook authorizer.
    59  	// result is one of:
    60  	// - canceled: the call invoking the webhook request was canceled
    61  	// - timeout: the webhook request timed out
    62  	// - error: the webhook response completed and was invalid
    63  	// - success: the webhook response completed and was well-formed
    64  	RecordWebhookEvaluation(ctx context.Context, name, result string)
    65  	// RecordWebhookDuration records latency for each round-trip of a webhook authorizer.
    66  	// result is one of:
    67  	// - canceled: the call invoking the webhook request was canceled
    68  	// - timeout: the webhook request timed out
    69  	// - error: the webhook response completed and was invalid
    70  	// - success: the webhook response completed and was well-formed
    71  	RecordWebhookDuration(ctx context.Context, name, result string, duration float64)
    72  	// RecordWebhookFailOpen increments when a webhook timeout or error results in a fail open
    73  	// of a request which has not been canceled.
    74  	// result is one of:
    75  	// - timeout: the webhook request timed out
    76  	// - error: the webhook response completed and was invalid
    77  	RecordWebhookFailOpen(ctx context.Context, name, result string)
    78  }
    79  
    80  type NoopWebhookMetrics struct{}
    81  
    82  func (NoopWebhookMetrics) RecordWebhookEvaluation(ctx context.Context, name, result string) {}
    83  func (NoopWebhookMetrics) RecordWebhookDuration(ctx context.Context, name, result string, duration float64) {
    84  }
    85  func (NoopWebhookMetrics) RecordWebhookFailOpen(ctx context.Context, name, result string) {}
    86  
    87  var registerWebhookMetrics sync.Once
    88  
    89  // RegisterMetrics registers authorizer metrics.
    90  func RegisterWebhookMetrics() {
    91  	registerWebhookMetrics.Do(func() {
    92  		legacyregistry.MustRegister(webhookEvaluations)
    93  		legacyregistry.MustRegister(webhookDuration)
    94  		legacyregistry.MustRegister(webhookFailOpen)
    95  	})
    96  }
    97  
    98  func ResetMetricsForTest() {
    99  	webhookEvaluations.Reset()
   100  	webhookDuration.Reset()
   101  	webhookFailOpen.Reset()
   102  }
   103  
   104  const (
   105  	namespace = "apiserver"
   106  	subsystem = "authorization"
   107  )
   108  
   109  var (
   110  	webhookEvaluations = compbasemetrics.NewCounterVec(
   111  		&compbasemetrics.CounterOpts{
   112  			Namespace:      namespace,
   113  			Subsystem:      subsystem,
   114  			Name:           "webhook_evaluations_total",
   115  			Help:           "Round-trips to authorization webhooks.",
   116  			StabilityLevel: compbasemetrics.ALPHA,
   117  		},
   118  		[]string{"name", "result"},
   119  	)
   120  
   121  	webhookDuration = compbasemetrics.NewHistogramVec(
   122  		&compbasemetrics.HistogramOpts{
   123  			Namespace:      namespace,
   124  			Subsystem:      subsystem,
   125  			Name:           "webhook_duration_seconds",
   126  			Help:           "Request latency in seconds.",
   127  			Buckets:        compbasemetrics.DefBuckets,
   128  			StabilityLevel: compbasemetrics.ALPHA,
   129  		},
   130  		[]string{"name", "result"},
   131  	)
   132  
   133  	webhookFailOpen = compbasemetrics.NewCounterVec(
   134  		&compbasemetrics.CounterOpts{
   135  			Namespace:      namespace,
   136  			Subsystem:      subsystem,
   137  			Name:           "webhook_evaluations_fail_open_total",
   138  			Help:           "NoOpinion results due to webhook timeout or error.",
   139  			StabilityLevel: compbasemetrics.ALPHA,
   140  		},
   141  		[]string{"name", "result"},
   142  	)
   143  )
   144  
   145  type webhookMetrics struct{}
   146  
   147  func NewWebhookMetrics() WebhookMetrics {
   148  	RegisterWebhookMetrics()
   149  	return webhookMetrics{}
   150  }
   151  
   152  func ResetWebhookMetricsForTest() {
   153  	webhookEvaluations.Reset()
   154  	webhookDuration.Reset()
   155  	webhookFailOpen.Reset()
   156  }
   157  
   158  func (webhookMetrics) RecordWebhookEvaluation(ctx context.Context, name, result string) {
   159  	webhookEvaluations.WithContext(ctx).WithLabelValues(name, result).Inc()
   160  }
   161  func (webhookMetrics) RecordWebhookDuration(ctx context.Context, name, result string, duration float64) {
   162  	webhookDuration.WithContext(ctx).WithLabelValues(name, result).Observe(duration)
   163  }
   164  func (webhookMetrics) RecordWebhookFailOpen(ctx context.Context, name, result string) {
   165  	webhookFailOpen.WithContext(ctx).WithLabelValues(name, result).Inc()
   166  }