github.com/cilium/cilium@v1.16.2/pkg/endpoint/metrics.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package endpoint 5 6 import ( 7 "github.com/cilium/cilium/api/v1/models" 8 loaderMetrics "github.com/cilium/cilium/pkg/datapath/loader/metrics" 9 "github.com/cilium/cilium/pkg/lock" 10 "github.com/cilium/cilium/pkg/metrics" 11 "github.com/cilium/cilium/pkg/metrics/metric" 12 "github.com/cilium/cilium/pkg/spanstat" 13 "github.com/cilium/cilium/pkg/time" 14 ) 15 16 var endpointPolicyStatus endpointPolicyStatusMap 17 18 func init() { 19 endpointPolicyStatus = newEndpointPolicyStatusMap() 20 } 21 22 type statistics interface { 23 GetMap() map[string]*spanstat.SpanStat 24 } 25 26 func sendMetrics(stats statistics, metric metric.Vec[metric.Observer]) { 27 for scope, stat := range stats.GetMap() { 28 // Skip scopes that have not been hit (zero duration), so the count in 29 // the histogram accurately reflects the number of times each scope is 30 // hit, and the distribution is not incorrectly skewed towards zero. 31 if stat.SuccessTotal() != time.Duration(0) { 32 metric.WithLabelValues(scope, "success").Observe(stat.SuccessTotal().Seconds()) 33 } 34 if stat.FailureTotal() != time.Duration(0) { 35 metric.WithLabelValues(scope, "failure").Observe(stat.FailureTotal().Seconds()) 36 } 37 } 38 } 39 40 type regenerationStatistics struct { 41 success bool 42 endpointID uint16 43 policyStatus models.EndpointPolicyEnabled 44 totalTime spanstat.SpanStat 45 waitingForLock spanstat.SpanStat 46 waitingForPolicyRepository spanstat.SpanStat 47 waitingForCTClean spanstat.SpanStat 48 policyCalculation spanstat.SpanStat 49 proxyConfiguration spanstat.SpanStat 50 proxyPolicyCalculation spanstat.SpanStat 51 proxyWaitForAck spanstat.SpanStat 52 datapathRealization loaderMetrics.SpanStat 53 mapSync spanstat.SpanStat 54 prepareBuild spanstat.SpanStat 55 } 56 57 // SendMetrics sends the regeneration statistics for this endpoint to 58 // Prometheus. 59 func (s *regenerationStatistics) SendMetrics() { 60 endpointPolicyStatus.Update(s.endpointID, s.policyStatus) 61 62 if !s.success { 63 // Endpoint regeneration failed, increase on failed metrics 64 metrics.EndpointRegenerationTotal.WithLabelValues(metrics.LabelValueOutcomeFail).Inc() 65 return 66 } 67 68 metrics.EndpointRegenerationTotal.WithLabelValues(metrics.LabelValueOutcomeSuccess).Inc() 69 70 sendMetrics(s, metrics.EndpointRegenerationTimeStats) 71 } 72 73 // GetMap returns a map which key is the stat name and the value is the stat 74 func (s *regenerationStatistics) GetMap() map[string]*spanstat.SpanStat { 75 result := map[string]*spanstat.SpanStat{ 76 "waitingForLock": &s.waitingForLock, 77 "waitingForPolicyRepository": &s.waitingForPolicyRepository, 78 "waitingForCTClean": &s.waitingForCTClean, 79 "policyCalculation": &s.policyCalculation, 80 "proxyConfiguration": &s.proxyConfiguration, 81 "proxyPolicyCalculation": &s.proxyPolicyCalculation, 82 "proxyWaitForAck": &s.proxyWaitForAck, 83 "mapSync": &s.mapSync, 84 "prepareBuild": &s.prepareBuild, 85 "total": &s.totalTime, 86 } 87 for k, v := range s.datapathRealization.GetMap() { 88 result[k] = v 89 } 90 return result 91 } 92 93 // endpointPolicyStatusMap is a map to store the endpoint id and the policy 94 // enforcement status. It is used only to send metrics to prometheus. 95 type endpointPolicyStatusMap struct { 96 mutex lock.Mutex 97 m map[uint16]models.EndpointPolicyEnabled 98 } 99 100 func newEndpointPolicyStatusMap() endpointPolicyStatusMap { 101 return endpointPolicyStatusMap{m: make(map[uint16]models.EndpointPolicyEnabled)} 102 } 103 104 // Update adds or updates a new endpoint to the map and update the metrics 105 // related 106 func (epPolicyMaps *endpointPolicyStatusMap) Update(endpointID uint16, policyStatus models.EndpointPolicyEnabled) { 107 epPolicyMaps.mutex.Lock() 108 epPolicyMaps.m[endpointID] = policyStatus 109 epPolicyMaps.mutex.Unlock() 110 endpointPolicyStatus.UpdateMetrics() 111 } 112 113 // Remove deletes the given endpoint from the map and update the metrics 114 func (epPolicyMaps *endpointPolicyStatusMap) Remove(endpointID uint16) { 115 epPolicyMaps.mutex.Lock() 116 delete(epPolicyMaps.m, endpointID) 117 epPolicyMaps.mutex.Unlock() 118 epPolicyMaps.UpdateMetrics() 119 } 120 121 // UpdateMetrics update the policy enforcement metrics statistics for the endpoints. 122 func (epPolicyMaps *endpointPolicyStatusMap) UpdateMetrics() { 123 policyStatus := map[models.EndpointPolicyEnabled]float64{ 124 models.EndpointPolicyEnabledNone: 0, 125 models.EndpointPolicyEnabledEgress: 0, 126 models.EndpointPolicyEnabledIngress: 0, 127 models.EndpointPolicyEnabledBoth: 0, 128 models.EndpointPolicyEnabledAuditDashEgress: 0, 129 models.EndpointPolicyEnabledAuditDashIngress: 0, 130 models.EndpointPolicyEnabledAuditDashBoth: 0, 131 } 132 133 epPolicyMaps.mutex.Lock() 134 for _, value := range epPolicyMaps.m { 135 policyStatus[value]++ 136 } 137 epPolicyMaps.mutex.Unlock() 138 139 for k, v := range policyStatus { 140 metrics.PolicyEndpointStatus.WithLabelValues(string(k)).Set(v) 141 } 142 }