pkg/metricstore/metricstore.go (132 lines of code) (raw):

// ------------------------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // -------------------------------------------------------------------------------------------- package metricstore import ( "fmt" "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/Azure/application-gateway-kubernetes-ingress/pkg/controllererrors" "github.com/Azure/application-gateway-kubernetes-ingress/pkg/environment" "github.com/Azure/application-gateway-kubernetes-ingress/pkg/version" ) const ( // PrometheusNamespace is the namespace for appgw ingress controller PrometheusNamespace = "appgw_ingress_controller" // ErrorCode is a sub-label for keeping track of error for a specific error code ErrorCode = "error_code" ) // MetricStore is store maintaining all metrics type MetricStore interface { Start() Stop() Handler() http.Handler SetUpdateLatencySec(time.Duration) IncArmAPIUpdateCallFailureCounter() IncArmAPIUpdateCallSuccessCounter() IncArmAPICallCounter() IncK8sAPIEventCounter() IncErrorCount(controllererrors.ErrorCode) } // AGICMetricStore is store type AGICMetricStore struct { constLabels prometheus.Labels updateLatency prometheus.Gauge k8sAPIEventCounter prometheus.Counter armAPICallCounter prometheus.Counter armAPIUpdateCallFailureCounter prometheus.Counter armAPIUpdateCallSuccessCounter prometheus.Counter errorCounterVec *prometheus.CounterVec registry *prometheus.Registry } // NewMetricStore returns a new metric store func NewMetricStore(envVariable environment.EnvVariables) MetricStore { constLabels := prometheus.Labels{ "controller_class": envVariable.IngressClassControllerName, "controller_namespace": envVariable.AGICPodNamespace, "controller_pod": envVariable.AGICPodName, "controller_appgw_subscription": envVariable.SubscriptionID, "controller_appgw_resource_group": envVariable.ResourceGroupName, "controller_appgw_name": envVariable.AppGwName, "controller_version": fmt.Sprintf("%s/%s/%s", version.Version, version.GitCommit, version.BuildDate), } return &AGICMetricStore{ constLabels: constLabels, updateLatency: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: PrometheusNamespace, ConstLabels: constLabels, Name: "update_latency_seconds", Help: "The time spent in updating Application Gateway", }), k8sAPIEventCounter: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: PrometheusNamespace, ConstLabels: constLabels, Name: "k8s_api_event_counter", Help: "This counter represents the number of events received from k8s API Server", }), armAPICallCounter: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: PrometheusNamespace, ConstLabels: constLabels, Name: "arm_api_call_counter", Help: "This counter represents the number of API calls to ARM", }), armAPIUpdateCallFailureCounter: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: PrometheusNamespace, ConstLabels: constLabels, Name: "arm_api_update_call_failure_counter", Help: "This counter represents the number of update API calls that failed to update Application Gateway", }), armAPIUpdateCallSuccessCounter: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: PrometheusNamespace, ConstLabels: constLabels, Name: "arm_api_update_call_success_counter", Help: "This counter represents the number of update API calls that successfully updated Application Gateway", }), errorCounterVec: prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: PrometheusNamespace, ConstLabels: constLabels, Name: "error_counter", Help: "This gauge changes represents an error on AGIC", }, []string{ErrorCode}, ), registry: prometheus.NewRegistry(), } } // Start store func (ms *AGICMetricStore) Start() { ms.registry.MustRegister(ms.updateLatency) ms.registry.MustRegister(ms.k8sAPIEventCounter) ms.registry.MustRegister(ms.armAPIUpdateCallSuccessCounter) ms.registry.MustRegister(ms.armAPIUpdateCallFailureCounter) ms.registry.MustRegister(ms.armAPICallCounter) ms.registry.MustRegister(ms.errorCounterVec) } // Stop store func (ms *AGICMetricStore) Stop() { ms.registry.Unregister(ms.updateLatency) ms.registry.Unregister(ms.k8sAPIEventCounter) ms.registry.Unregister(ms.armAPIUpdateCallSuccessCounter) ms.registry.Unregister(ms.armAPIUpdateCallFailureCounter) ms.registry.Unregister(ms.armAPICallCounter) ms.registry.Unregister(ms.errorCounterVec) } // SetUpdateLatencySec updates latency func (ms *AGICMetricStore) SetUpdateLatencySec(duration time.Duration) { ms.updateLatency.Set(duration.Seconds()) } // IncK8sAPIEventCounter increases the counter after receiving a k8s Event func (ms *AGICMetricStore) IncK8sAPIEventCounter() { ms.k8sAPIEventCounter.Inc() } // IncArmAPIUpdateCallFailureCounter increases the counter for failure on ARM func (ms *AGICMetricStore) IncArmAPIUpdateCallFailureCounter() { ms.armAPIUpdateCallFailureCounter.Inc() ms.armAPICallCounter.Inc() } // IncArmAPIUpdateCallSuccessCounter increases the counter for success on ARM func (ms *AGICMetricStore) IncArmAPIUpdateCallSuccessCounter() { ms.armAPIUpdateCallSuccessCounter.Inc() ms.armAPICallCounter.Inc() } // IncArmAPICallCounter increases the counter for success on ARM func (ms *AGICMetricStore) IncArmAPICallCounter() { ms.armAPICallCounter.Inc() } // IncErrorCount increases the counter for a particular error code error encountered by AGIC func (ms *AGICMetricStore) IncErrorCount(errorCode controllererrors.ErrorCode) { ms.errorCounterVec.With(prometheus.Labels{ErrorCode: string(errorCode)}).Inc() } // Handler return the registry func (ms *AGICMetricStore) Handler() http.Handler { return promhttp.InstrumentMetricHandler( ms.registry, promhttp.HandlerFor(ms.registry, promhttp.HandlerOpts{}), ) }