1// +build !providerless 2 3/* 4Copyright 2018 The Kubernetes Authors. 5 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17*/ 18 19package metrics 20 21import ( 22 "strings" 23 "time" 24 25 "k8s.io/component-base/metrics" 26 "k8s.io/component-base/metrics/legacyregistry" 27) 28 29const ( 30 azureMetricsNamespace = "cloudprovider_azure" 31) 32 33var ( 34 metricLabels = []string{ 35 "request", // API function that is being invoked 36 "resource_group", // Resource group of the resource being monitored 37 "subscription_id", // Subscription ID of the resource being monitored 38 "source", // Operation source(optional) 39 } 40 41 apiMetrics = registerAPIMetrics(metricLabels...) 42 operationMetrics = registerOperationMetrics(metricLabels...) 43) 44 45// apiCallMetrics is the metrics measuring the performance of a single API call 46// e.g., GET, POST ... 47type apiCallMetrics struct { 48 latency *metrics.HistogramVec 49 errors *metrics.CounterVec 50 rateLimitedCount *metrics.CounterVec 51 throttledCount *metrics.CounterVec 52} 53 54// operationCallMetrics is the metrics measuring the performance of a whole operation 55// e.g., the create / update / delete process of a loadbalancer or route. 56type operationCallMetrics struct { 57 operationLatency *metrics.HistogramVec 58 operationFailureCount *metrics.CounterVec 59} 60 61// MetricContext indicates the context for Azure client metrics. 62type MetricContext struct { 63 start time.Time 64 attributes []string 65} 66 67// NewMetricContext creates a new MetricContext. 68func NewMetricContext(prefix, request, resourceGroup, subscriptionID, source string) *MetricContext { 69 return &MetricContext{ 70 start: time.Now(), 71 attributes: []string{prefix + "_" + request, strings.ToLower(resourceGroup), subscriptionID, source}, 72 } 73} 74 75// RateLimitedCount records the metrics for rate limited request count. 76func (mc *MetricContext) RateLimitedCount() { 77 apiMetrics.rateLimitedCount.WithLabelValues(mc.attributes...).Inc() 78} 79 80// ThrottledCount records the metrics for throttled request count. 81func (mc *MetricContext) ThrottledCount() { 82 apiMetrics.throttledCount.WithLabelValues(mc.attributes...).Inc() 83} 84 85// Observe observes the request latency and failed requests. 86func (mc *MetricContext) Observe(err error) error { 87 apiMetrics.latency.WithLabelValues(mc.attributes...).Observe( 88 time.Since(mc.start).Seconds()) 89 if err != nil { 90 apiMetrics.errors.WithLabelValues(mc.attributes...).Inc() 91 } 92 93 return err 94} 95 96// ObserveOperationWithResult observes the request latency and failed requests of an operation. 97func (mc *MetricContext) ObserveOperationWithResult(isOperationSucceeded bool) { 98 operationMetrics.operationLatency.WithLabelValues(mc.attributes...).Observe( 99 time.Since(mc.start).Seconds()) 100 if !isOperationSucceeded { 101 mc.CountFailedOperation() 102 } 103} 104 105// CountFailedOperation increase the number of failed operations 106func (mc *MetricContext) CountFailedOperation() { 107 operationMetrics.operationFailureCount.WithLabelValues(mc.attributes...).Inc() 108} 109 110// registerAPIMetrics registers the API metrics. 111func registerAPIMetrics(attributes ...string) *apiCallMetrics { 112 metrics := &apiCallMetrics{ 113 latency: metrics.NewHistogramVec( 114 &metrics.HistogramOpts{ 115 Namespace: azureMetricsNamespace, 116 Name: "api_request_duration_seconds", 117 Help: "Latency of an Azure API call", 118 Buckets: []float64{.1, .25, .5, 1, 2.5, 5, 10, 15, 25, 50, 120, 300, 600, 1200}, 119 StabilityLevel: metrics.ALPHA, 120 }, 121 attributes, 122 ), 123 errors: metrics.NewCounterVec( 124 &metrics.CounterOpts{ 125 Namespace: azureMetricsNamespace, 126 Name: "api_request_errors", 127 Help: "Number of errors for an Azure API call", 128 StabilityLevel: metrics.ALPHA, 129 }, 130 attributes, 131 ), 132 rateLimitedCount: metrics.NewCounterVec( 133 &metrics.CounterOpts{ 134 Namespace: azureMetricsNamespace, 135 Name: "api_request_ratelimited_count", 136 Help: "Number of rate limited Azure API calls", 137 StabilityLevel: metrics.ALPHA, 138 }, 139 attributes, 140 ), 141 throttledCount: metrics.NewCounterVec( 142 &metrics.CounterOpts{ 143 Namespace: azureMetricsNamespace, 144 Name: "api_request_throttled_count", 145 Help: "Number of throttled Azure API calls", 146 StabilityLevel: metrics.ALPHA, 147 }, 148 attributes, 149 ), 150 } 151 152 legacyregistry.MustRegister(metrics.latency) 153 legacyregistry.MustRegister(metrics.errors) 154 legacyregistry.MustRegister(metrics.rateLimitedCount) 155 legacyregistry.MustRegister(metrics.throttledCount) 156 157 return metrics 158} 159 160// registerOperationMetrics registers the operation metrics. 161func registerOperationMetrics(attributes ...string) *operationCallMetrics { 162 metrics := &operationCallMetrics{ 163 operationLatency: metrics.NewHistogramVec( 164 &metrics.HistogramOpts{ 165 Namespace: azureMetricsNamespace, 166 Name: "op_duration_seconds", 167 Help: "Latency of an Azure service operation", 168 StabilityLevel: metrics.ALPHA, 169 Buckets: []float64{0.1, 0.2, 0.5, 1, 10, 20, 30, 40, 50, 60, 100, 200, 300}, 170 }, 171 attributes, 172 ), 173 operationFailureCount: metrics.NewCounterVec( 174 &metrics.CounterOpts{ 175 Namespace: azureMetricsNamespace, 176 Name: "op_failure_count", 177 Help: "Number of failed Azure service operations", 178 StabilityLevel: metrics.ALPHA, 179 }, 180 attributes, 181 ), 182 } 183 184 legacyregistry.MustRegister(metrics.operationLatency) 185 legacyregistry.MustRegister(metrics.operationFailureCount) 186 187 return metrics 188} 189