github.com/argoproj/argo-cd/v3@v3.2.1/server/metrics/metrics.go (about)

     1  package metrics
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/prometheus/client_golang/prometheus"
    10  	"github.com/prometheus/client_golang/prometheus/promhttp"
    11  
    12  	"github.com/argoproj/argo-cd/v3/common"
    13  	"github.com/argoproj/argo-cd/v3/util/metrics/kubectl"
    14  	"github.com/argoproj/argo-cd/v3/util/profile"
    15  )
    16  
    17  type MetricsServer struct {
    18  	*http.Server
    19  	redisRequestCounter      *prometheus.CounterVec
    20  	redisRequestHistogram    *prometheus.HistogramVec
    21  	extensionRequestCounter  *prometheus.CounterVec
    22  	extensionRequestDuration *prometheus.HistogramVec
    23  	loginRequestCounter      *prometheus.CounterVec
    24  	PrometheusRegistry       *prometheus.Registry
    25  }
    26  
    27  var (
    28  	redisRequestCounter = prometheus.NewCounterVec(
    29  		prometheus.CounterOpts{
    30  			Name: "argocd_redis_request_total",
    31  			Help: "Number of kubernetes requests executed during application reconciliation.",
    32  		},
    33  		[]string{"initiator", "failed"},
    34  	)
    35  	redisRequestHistogram = prometheus.NewHistogramVec(
    36  		prometheus.HistogramOpts{
    37  			Name:    "argocd_redis_request_duration",
    38  			Help:    "Redis requests duration.",
    39  			Buckets: []float64{0.1, 0.25, .5, 1, 2},
    40  		},
    41  		[]string{"initiator"},
    42  	)
    43  	extensionRequestCounter = prometheus.NewCounterVec(
    44  		prometheus.CounterOpts{
    45  			Name: "argocd_proxy_extension_request_total",
    46  			Help: "Number of requests sent to configured proxy extensions.",
    47  		},
    48  		[]string{"extension", "status"},
    49  	)
    50  	extensionRequestDuration = prometheus.NewHistogramVec(
    51  		prometheus.HistogramOpts{
    52  			Name:    "argocd_proxy_extension_request_duration_seconds",
    53  			Help:    "Request duration in seconds between the Argo CD API server and the extension backend.",
    54  			Buckets: []float64{0.1, 0.25, .5, 1, 2, 5, 10},
    55  		},
    56  		[]string{"extension"},
    57  	)
    58  	loginRequestCounter = prometheus.NewCounterVec(
    59  		prometheus.CounterOpts{
    60  			Name: "argocd_login_request_total",
    61  			Help: "Number of login requests to the Argo CD API server.",
    62  		},
    63  		[]string{"status"},
    64  	)
    65  	argoVersion = prometheus.NewGaugeVec(
    66  		prometheus.GaugeOpts{
    67  			Name: "argocd_info",
    68  			Help: "ArgoCD version information",
    69  		},
    70  		[]string{"version"},
    71  	)
    72  )
    73  
    74  // NewMetricsServer returns a new prometheus server which collects api server metrics
    75  func NewMetricsServer(host string, port int) *MetricsServer {
    76  	mux := http.NewServeMux()
    77  	registry := prometheus.NewRegistry()
    78  	mux.Handle("/metrics", promhttp.HandlerFor(prometheus.Gatherers{
    79  		registry,
    80  		prometheus.DefaultGatherer,
    81  	}, promhttp.HandlerOpts{}))
    82  	argoVersion.WithLabelValues(common.GetVersion().Version).Set(1)
    83  
    84  	profile.RegisterProfiler(mux)
    85  
    86  	registry.MustRegister(redisRequestCounter)
    87  	registry.MustRegister(redisRequestHistogram)
    88  	registry.MustRegister(extensionRequestCounter)
    89  	registry.MustRegister(extensionRequestDuration)
    90  	registry.MustRegister(loginRequestCounter)
    91  	registry.MustRegister(argoVersion)
    92  
    93  	kubectl.RegisterWithClientGo()
    94  	kubectl.RegisterWithPrometheus(registry)
    95  
    96  	return &MetricsServer{
    97  		Server: &http.Server{
    98  			Addr:    fmt.Sprintf("%s:%d", host, port),
    99  			Handler: mux,
   100  		},
   101  		redisRequestCounter:      redisRequestCounter,
   102  		redisRequestHistogram:    redisRequestHistogram,
   103  		extensionRequestCounter:  extensionRequestCounter,
   104  		extensionRequestDuration: extensionRequestDuration,
   105  		loginRequestCounter:      loginRequestCounter,
   106  		PrometheusRegistry:       registry,
   107  	}
   108  }
   109  
   110  func (m *MetricsServer) IncRedisRequest(failed bool) {
   111  	m.redisRequestCounter.WithLabelValues("argocd-server", strconv.FormatBool(failed)).Inc()
   112  }
   113  
   114  // ObserveRedisRequestDuration observes redis request duration
   115  func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
   116  	m.redisRequestHistogram.WithLabelValues("argocd-server").Observe(duration.Seconds())
   117  }
   118  
   119  func (m *MetricsServer) IncExtensionRequestCounter(extension string, status int) {
   120  	m.extensionRequestCounter.WithLabelValues(extension, strconv.Itoa(status)).Inc()
   121  }
   122  
   123  func (m *MetricsServer) ObserveExtensionRequestDuration(extension string, duration time.Duration) {
   124  	m.extensionRequestDuration.WithLabelValues(extension).Observe(duration.Seconds())
   125  }
   126  
   127  // IncLoginRequestCounter increments the login request counter with the given status
   128  // status can be "success" or "failure"
   129  func (m *MetricsServer) IncLoginRequestCounter(status string) {
   130  	m.loginRequestCounter.WithLabelValues(status).Inc()
   131  }