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  }