github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/metrics/metrics.go (about) 1 package metrics 2 3 import ( 4 "time" 5 6 "github.com/prometheus/client_golang/prometheus" 7 "k8s.io/apimachinery/pkg/labels" 8 "sigs.k8s.io/controller-runtime/pkg/metrics" 9 10 argoappv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 11 applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1" 12 metricsutil "github.com/argoproj/argo-cd/v3/util/metrics" 13 "github.com/argoproj/argo-cd/v3/util/metrics/kubectl" 14 ) 15 16 var ( 17 descAppsetLabels *prometheus.Desc 18 descAppsetDefaultLabels = []string{"namespace", "name"} 19 descAppsetInfo = prometheus.NewDesc( 20 "argocd_appset_info", 21 "Information about applicationset", 22 append(descAppsetDefaultLabels, "resource_update_status"), 23 nil, 24 ) 25 26 descAppsetGeneratedApps = prometheus.NewDesc( 27 "argocd_appset_owned_applications", 28 "Number of applications owned by the applicationset", 29 descAppsetDefaultLabels, 30 nil, 31 ) 32 ) 33 34 type ApplicationsetMetrics struct { 35 reconcileHistogram *prometheus.HistogramVec 36 } 37 38 type appsetCollector struct { 39 lister applisters.ApplicationSetLister 40 // appsClientSet appclientset.Interface 41 labels []string 42 filter func(appset *argoappv1.ApplicationSet) bool 43 } 44 45 func NewApplicationsetMetrics(appsetLister applisters.ApplicationSetLister, appsetLabels []string, appsetFilter func(appset *argoappv1.ApplicationSet) bool) ApplicationsetMetrics { 46 reconcileHistogram := prometheus.NewHistogramVec( 47 prometheus.HistogramOpts{ 48 Name: "argocd_appset_reconcile", 49 Help: "Application reconciliation performance in seconds.", 50 // Buckets can be set later on after observing median time 51 }, 52 descAppsetDefaultLabels, 53 ) 54 55 appsetCollector := newAppsetCollector(appsetLister, appsetLabels, appsetFilter) 56 57 // Register collectors and metrics 58 metrics.Registry.MustRegister(reconcileHistogram) 59 metrics.Registry.MustRegister(appsetCollector) 60 61 kubectl.RegisterWithClientGo() 62 kubectl.RegisterWithPrometheus(metrics.Registry) 63 64 return ApplicationsetMetrics{ 65 reconcileHistogram: reconcileHistogram, 66 } 67 } 68 69 func (m *ApplicationsetMetrics) ObserveReconcile(appset *argoappv1.ApplicationSet, duration time.Duration) { 70 m.reconcileHistogram.WithLabelValues(appset.Namespace, appset.Name).Observe(duration.Seconds()) 71 } 72 73 func newAppsetCollector(lister applisters.ApplicationSetLister, labels []string, filter func(appset *argoappv1.ApplicationSet) bool) *appsetCollector { 74 descAppsetDefaultLabels = []string{"namespace", "name"} 75 76 if len(labels) > 0 { 77 descAppsetLabels = prometheus.NewDesc( 78 "argocd_appset_labels", 79 "Applicationset labels translated to Prometheus labels", 80 append(descAppsetDefaultLabels, metricsutil.NormalizeLabels("label", labels)...), 81 nil, 82 ) 83 } 84 85 return &appsetCollector{ 86 lister: lister, 87 labels: labels, 88 filter: filter, 89 } 90 } 91 92 // Describe implements the prometheus.Collector interface 93 func (c *appsetCollector) Describe(ch chan<- *prometheus.Desc) { 94 ch <- descAppsetInfo 95 ch <- descAppsetGeneratedApps 96 97 if len(c.labels) > 0 { 98 ch <- descAppsetLabels 99 } 100 } 101 102 // Collect implements the prometheus.Collector interface 103 func (c *appsetCollector) Collect(ch chan<- prometheus.Metric) { 104 appsets, _ := c.lister.List(labels.NewSelector()) 105 106 for _, appset := range appsets { 107 if c.filter(appset) { 108 collectAppset(appset, c.labels, ch) 109 } 110 } 111 } 112 113 func collectAppset(appset *argoappv1.ApplicationSet, labelsToCollect []string, ch chan<- prometheus.Metric) { 114 labelValues := make([]string, 0) 115 commonLabelValues := []string{appset.Namespace, appset.Name} 116 117 for _, label := range labelsToCollect { 118 labelValues = append(labelValues, appset.GetLabels()[label]) 119 } 120 121 resourceUpdateStatus := "Unknown" 122 123 for _, condition := range appset.Status.Conditions { 124 if condition.Type == argoappv1.ApplicationSetConditionResourcesUpToDate { 125 resourceUpdateStatus = condition.Reason 126 } 127 } 128 129 if len(labelsToCollect) > 0 { 130 ch <- prometheus.MustNewConstMetric(descAppsetLabels, prometheus.GaugeValue, 1, append(commonLabelValues, labelValues...)...) 131 } 132 133 ch <- prometheus.MustNewConstMetric(descAppsetInfo, prometheus.GaugeValue, 1, appset.Namespace, appset.Name, resourceUpdateStatus) 134 ch <- prometheus.MustNewConstMetric(descAppsetGeneratedApps, prometheus.GaugeValue, float64(len(appset.Status.Resources)), appset.Namespace, appset.Name) 135 }