...

Source file src/github.com/linkerd/linkerd2/controller/api/destination/watcher/prometheus.go

Documentation: github.com/linkerd/linkerd2/controller/api/destination/watcher

     1  package watcher
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/prometheus/client_golang/prometheus"
     7  	"github.com/prometheus/client_golang/prometheus/promauto"
     8  	log "github.com/sirupsen/logrus"
     9  )
    10  
    11  type (
    12  	metricsVecs struct {
    13  		labelNames  []string
    14  		subscribers *prometheus.GaugeVec
    15  		updates     *prometheus.CounterVec
    16  	}
    17  
    18  	metrics struct {
    19  		labels      prometheus.Labels
    20  		subscribers prometheus.Gauge
    21  		updates     prometheus.Counter
    22  	}
    23  
    24  	endpointsMetricsVecs struct {
    25  		metricsVecs
    26  		pods   *prometheus.GaugeVec
    27  		exists *prometheus.GaugeVec
    28  	}
    29  
    30  	endpointsMetrics struct {
    31  		metrics
    32  		pods   prometheus.Gauge
    33  		exists prometheus.Gauge
    34  	}
    35  )
    36  
    37  var (
    38  	informer_lag_seconds_buckets = []float64{
    39  		0.5,  // 500ms
    40  		1,    // 1s
    41  		2.5,  // 2.5s
    42  		5,    // 5s
    43  		10,   // 10s
    44  		25,   // 25s
    45  		50,   // 50s
    46  		100,  // 1m 40s
    47  		250,  // 4m 10s
    48  		1000, // 16m 40s
    49  	}
    50  	endpointsInformerLag = promauto.NewHistogram(
    51  		prometheus.HistogramOpts{
    52  			Name:    "endpoints_informer_lag_seconds",
    53  			Help:    "The amount of time between when an Endpoints resource is updated and when an informer observes it",
    54  			Buckets: informer_lag_seconds_buckets,
    55  		},
    56  	)
    57  
    58  	endpointsliceInformerLag = promauto.NewHistogram(
    59  		prometheus.HistogramOpts{
    60  			Name:    "endpointslices_informer_lag_seconds",
    61  			Help:    "The amount of time between when an EndpointSlice resource is updated and when an informer observes it",
    62  			Buckets: informer_lag_seconds_buckets,
    63  		},
    64  	)
    65  
    66  	serviceInformerLag = promauto.NewHistogram(
    67  		prometheus.HistogramOpts{
    68  			Name:    "services_informer_lag_seconds",
    69  			Help:    "The amount of time between when a Service resource is updated and when an informer observes it",
    70  			Buckets: informer_lag_seconds_buckets,
    71  		},
    72  	)
    73  
    74  	serverInformerLag = promauto.NewHistogram(
    75  		prometheus.HistogramOpts{
    76  			Name:    "servers_informer_lag_seconds",
    77  			Help:    "The amount of time between when a Server resource is updated and when an informer observes it",
    78  			Buckets: informer_lag_seconds_buckets,
    79  		},
    80  	)
    81  
    82  	podInformerLag = promauto.NewHistogram(
    83  		prometheus.HistogramOpts{
    84  			Name:    "pods_informer_lag_seconds",
    85  			Help:    "The amount of time between when a Pod resource is updated and when an informer observes it",
    86  			Buckets: informer_lag_seconds_buckets,
    87  		},
    88  	)
    89  
    90  	externalWorkloadInformerLag = promauto.NewHistogram(
    91  		prometheus.HistogramOpts{
    92  			Name:    "externalworkload_informer_lag_seconds",
    93  			Help:    "The amount of time between when an ExternalWorkload resource is updated and when an informer observes it",
    94  			Buckets: informer_lag_seconds_buckets,
    95  		},
    96  	)
    97  
    98  	serviceProfileInformerLag = promauto.NewHistogram(
    99  		prometheus.HistogramOpts{
   100  			Name:    "serviceprofiles_informer_lag_seconds",
   101  			Help:    "The amount of time between when a ServiceProfile resource is updated and when an informer observes it",
   102  			Buckets: informer_lag_seconds_buckets,
   103  		},
   104  	)
   105  )
   106  
   107  func newMetricsVecs(name string, labels []string) metricsVecs {
   108  	subscribers := promauto.NewGaugeVec(
   109  		prometheus.GaugeOpts{
   110  			Name: fmt.Sprintf("%s_subscribers", name),
   111  			Help: fmt.Sprintf("A gauge for the current number of subscribers to a %s.", name),
   112  		},
   113  		labels,
   114  	)
   115  
   116  	updates := promauto.NewCounterVec(
   117  		prometheus.CounterOpts{
   118  			Name: fmt.Sprintf("%s_updates", name),
   119  			Help: fmt.Sprintf("A counter for number of updates to a %s.", name),
   120  		},
   121  		labels,
   122  	)
   123  
   124  	return metricsVecs{
   125  		labelNames:  labels,
   126  		subscribers: subscribers,
   127  		updates:     updates,
   128  	}
   129  }
   130  
   131  func endpointsLabels(cluster, namespace, service, port string, hostname string) prometheus.Labels {
   132  	return prometheus.Labels{
   133  		"cluster":   cluster,
   134  		"namespace": namespace,
   135  		"service":   service,
   136  		"port":      port,
   137  		"hostname":  hostname,
   138  	}
   139  }
   140  
   141  func labelNames(labels prometheus.Labels) []string {
   142  	names := []string{}
   143  	for label := range labels {
   144  		names = append(names, label)
   145  	}
   146  	return names
   147  }
   148  
   149  func newEndpointsMetricsVecs() endpointsMetricsVecs {
   150  	labels := labelNames(endpointsLabels("", "", "", "", ""))
   151  	vecs := newMetricsVecs("endpoints", labels)
   152  
   153  	pods := promauto.NewGaugeVec(
   154  		prometheus.GaugeOpts{
   155  			Name: "endpoints_pods",
   156  			Help: "A gauge for the current number of pods in a endpoints.",
   157  		},
   158  		labels,
   159  	)
   160  
   161  	exists := promauto.NewGaugeVec(
   162  		prometheus.GaugeOpts{
   163  			Name: "endpoints_exists",
   164  			Help: "A gauge which is 1 if the endpoints exists and 0 if it does not.",
   165  		},
   166  		labels,
   167  	)
   168  
   169  	return endpointsMetricsVecs{
   170  		metricsVecs: vecs,
   171  		pods:        pods,
   172  		exists:      exists,
   173  	}
   174  }
   175  
   176  func (mv metricsVecs) newMetrics(labels prometheus.Labels) metrics {
   177  	return metrics{
   178  		labels:      labels,
   179  		subscribers: mv.subscribers.With(labels),
   180  		updates:     mv.updates.With(labels),
   181  	}
   182  }
   183  
   184  func (emv endpointsMetricsVecs) newEndpointsMetrics(labels prometheus.Labels) endpointsMetrics {
   185  	metrics := emv.newMetrics(labels)
   186  	return endpointsMetrics{
   187  		metrics: metrics,
   188  		pods:    emv.pods.With(labels),
   189  		exists:  emv.exists.With(labels),
   190  	}
   191  }
   192  
   193  func (emv endpointsMetricsVecs) unregister(labels prometheus.Labels) {
   194  	if !emv.metricsVecs.subscribers.Delete(labels) {
   195  		log.Warnf("unable to delete endpoints_subscribers metric with labels %s", labels)
   196  	}
   197  	if !emv.metricsVecs.updates.Delete(labels) {
   198  		log.Warnf("unable to delete endpoints_updates metric with labels %s", labels)
   199  	}
   200  	if !emv.pods.Delete(labels) {
   201  		log.Warnf("unable to delete endpoints_pods metric with labels %s", labels)
   202  	}
   203  	if !emv.exists.Delete(labels) {
   204  		log.Warnf("unable to delete endpoints_exists metric with labels %s", labels)
   205  	}
   206  }
   207  
   208  func (m metrics) setSubscribers(n int) {
   209  	m.subscribers.Set(float64(n))
   210  }
   211  
   212  func (m metrics) incUpdates() {
   213  	m.updates.Inc()
   214  }
   215  
   216  func (em endpointsMetrics) setPods(n int) {
   217  	em.pods.Set(float64(n))
   218  }
   219  
   220  func (em endpointsMetrics) setExists(exists bool) {
   221  	if exists {
   222  		em.exists.Set(1.0)
   223  	} else {
   224  		em.exists.Set(0.0)
   225  	}
   226  }
   227  

View as plain text