diff --git a/docs/prometheus.md b/docs/prometheus.md index 88ab0ff629..dc2c5339a1 100644 --- a/docs/prometheus.md +++ b/docs/prometheus.md @@ -15,6 +15,8 @@ The Ingress Controller exports the following metrics: * `controller_nginx_reload_errors_total`. Number of unsuccessful NGINX reloads. * `controller_nginx_last_reload_status`. Status of the last NGINX reload, 0 meaning down and 1 up. * `controller_nginx_last_reload_milliseconds`. Duration in milliseconds of the last NGINX reload. - * `controller_ingress_resources_total`. Number of handled Ingress resources. This metric includes the label type, that groups the Ingress resources by their type (regular, [minion or master](./../examples/mergeable-ingress-types)) + * `controller_ingress_resources_total`. Number of handled Ingress resources. This metric includes the label type, that groups the Ingress resources by their type (regular, [minion or master](./../examples/mergeable-ingress-types)). **Note**: The metric doesn't count minions without a master. + * `controller_virtualserver_resources_total`. Number of handled VirtualServer resources. + * `controller_virtualserverroute_resources_total`. Number of handled VirtualServerRoute resources. **Note**: The metric counts only VirtualServerRoutes that have a reference from a VirtualServer. **Note**: all metrics have the namespace nginx_ingress. For example, nginx_ingress_controller_nginx_reloads_total. diff --git a/internal/configs/configurator.go b/internal/configs/configurator.go index 8c9ffea389..8151b8118f 100644 --- a/internal/configs/configurator.go +++ b/internal/configs/configurator.go @@ -37,6 +37,7 @@ type Configurator struct { templateExecutorV2 *version2.TemplateExecutor ingresses map[string]*IngressEx minions map[string]map[string]bool + virtualServers map[string]*VirtualServerEx isWildcardEnabled bool isPlus bool } @@ -49,6 +50,7 @@ func NewConfigurator(nginxManager nginx.Manager, staticCfgParams *StaticConfigPa staticCfgParams: staticCfgParams, cfgParams: config, ingresses: make(map[string]*IngressEx), + virtualServers: make(map[string]*VirtualServerEx), templateExecutor: templateExecutor, templateExecutorV2: templateExecutorV2, minions: make(map[string]map[string]bool), @@ -170,6 +172,8 @@ func (cnf *Configurator) addOrUpdateVirtualServer(virtualServerEx *VirtualServer } cnf.nginxManager.CreateConfig(name, content) + cnf.virtualServers[name] = virtualServerEx + return warnings, nil } @@ -339,6 +343,8 @@ func (cnf *Configurator) DeleteVirtualServer(key string) error { name := getFileNameForVirtualServerFromKey(key) cnf.nginxManager.DeleteConfig(name) + delete(cnf.virtualServers, name) + if err := cnf.nginxManager.Reload(); err != nil { return fmt.Errorf("Error when removing VirtualServer %v: %v", key, err) } @@ -637,3 +643,13 @@ func (cnf *Configurator) GetIngressCounts() map[string]int { return counters } + +// GetVirtualServerCounts returns the total count of VS/VSR resources that are handled by the Ingress Controller +func (cnf *Configurator) GetVirtualServerCounts() (vsCount int, vsrCount int) { + vsCount = len(cnf.virtualServers) + for _, vs := range cnf.virtualServers { + vsrCount += len(vs.VirtualServerRoutes) + } + + return vsCount, vsrCount +} diff --git a/internal/k8s/controller.go b/internal/k8s/controller.go index 11ecc43c70..82c3ae36d0 100644 --- a/internal/k8s/controller.go +++ b/internal/k8s/controller.go @@ -605,8 +605,10 @@ func (lbc *LoadBalancerController) sync(task task) { lbc.syncExternalService(task) case virtualserver: lbc.syncVirtualServer(task) + lbc.updateVirtualServerMetrics() case virtualServerRoute: lbc.syncVirtualServerRoute(task) + lbc.updateVirtualServerMetrics() } } @@ -847,10 +849,16 @@ func (lbc *LoadBalancerController) syncIng(task task) { func (lbc *LoadBalancerController) updateIngressMetrics() { counters := lbc.configurator.GetIngressCounts() for nType, count := range counters { - lbc.metricsCollector.SetIngressResources(nType, count) + lbc.metricsCollector.SetIngresses(nType, count) } } +func (lbc *LoadBalancerController) updateVirtualServerMetrics() { + vsCount, vsrCount := lbc.configurator.GetVirtualServerCounts() + lbc.metricsCollector.SetVirtualServers(vsCount) + lbc.metricsCollector.SetVirtualServerRoutes(vsrCount) +} + // syncExternalService does not sync all services. // We only watch the Service specified by the external-service flag. func (lbc *LoadBalancerController) syncExternalService(task task) { diff --git a/internal/metrics/collectors/controller.go b/internal/metrics/collectors/controller.go index 52a68da448..d94688be97 100644 --- a/internal/metrics/collectors/controller.go +++ b/internal/metrics/collectors/controller.go @@ -6,44 +6,80 @@ var labelNamesController = []string{"type"} // ControllerCollector is an interface for the metrics of the Controller type ControllerCollector interface { - SetIngressResources(ingressType string, count int) + SetIngresses(ingressType string, count int) + SetVirtualServers(count int) + SetVirtualServerRoutes(count int) Register(registry *prometheus.Registry) error } // ControllerMetricsCollector implements the ControllerCollector interface and prometheus.Collector interface type ControllerMetricsCollector struct { - ingressResourcesTotal *prometheus.GaugeVec + ingressesTotal *prometheus.GaugeVec + virtualServersTotal prometheus.Gauge + virtualServerRoutesTotal prometheus.Gauge } // NewControllerMetricsCollector creates a new ControllerMetricsCollector func NewControllerMetricsCollector() *ControllerMetricsCollector { - cc := &ControllerMetricsCollector{ - ingressResourcesTotal: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "ingress_resources_total", - Namespace: metricsNamespace, - Help: "Number of handled ingress resources", - }, - labelNamesController, - ), + ingResTotal := prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "ingress_resources_total", + Namespace: metricsNamespace, + Help: "Number of handled ingress resources", + }, + labelNamesController, + ) + + vsResTotal := prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "virtualserver_resources_total", + Namespace: metricsNamespace, + Help: "Number of handled VirtualServer resources", + }, + ) + + vsrResTotal := prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "virtualserverroute_resources_total", + Namespace: metricsNamespace, + Help: "Number of handled VirtualServerRoute resources", + }, + ) + + return &ControllerMetricsCollector{ + ingressesTotal: ingResTotal, + virtualServersTotal: vsResTotal, + virtualServerRoutesTotal: vsrResTotal, } +} - return cc +// SetIngresses sets the value of the ingress resources gauge for a given type +func (cc *ControllerMetricsCollector) SetIngresses(ingressType string, count int) { + cc.ingressesTotal.WithLabelValues(ingressType).Set(float64(count)) } -// SetIngressResources sets the value of the ingress resources gauge for a given type -func (cc *ControllerMetricsCollector) SetIngressResources(ingressType string, count int) { - cc.ingressResourcesTotal.WithLabelValues(ingressType).Set(float64(count)) +// SetVirtualServers sets the value of the VirtualServer resources gauge +func (cc *ControllerMetricsCollector) SetVirtualServers(count int) { + cc.virtualServersTotal.Set(float64(count)) +} + +// SetVirtualServerRoutes sets the value of the VirtualServerRoute resources gauge +func (cc *ControllerMetricsCollector) SetVirtualServerRoutes(count int) { + cc.virtualServerRoutesTotal.Set(float64(count)) } // Describe implements prometheus.Collector interface Describe method func (cc *ControllerMetricsCollector) Describe(ch chan<- *prometheus.Desc) { - cc.ingressResourcesTotal.Describe(ch) + cc.ingressesTotal.Describe(ch) + cc.virtualServersTotal.Describe(ch) + cc.virtualServerRoutesTotal.Describe(ch) } // Collect implements the prometheus.Collector interface Collect method func (cc *ControllerMetricsCollector) Collect(ch chan<- prometheus.Metric) { - cc.ingressResourcesTotal.Collect(ch) + cc.ingressesTotal.Collect(ch) + cc.virtualServersTotal.Collect(ch) + cc.virtualServerRoutesTotal.Collect(ch) } // Register registers all the metrics of the collector @@ -62,5 +98,11 @@ func NewControllerFakeCollector() *ControllerFakeCollector { // Register implements a fake Register func (cc *ControllerFakeCollector) Register(registry *prometheus.Registry) error { return nil } -// SetIngressResources implements a fake SetIngressResources -func (cc *ControllerFakeCollector) SetIngressResources(ingressType string, count int) {} +// SetIngresses implements a fake SetIngresses +func (cc *ControllerFakeCollector) SetIngresses(ingressType string, count int) {} + +// SetVirtualServers implements a fake SetVirtualServers +func (cc *ControllerFakeCollector) SetVirtualServers(count int) {} + +// SetVirtualServerRoutes implements a fake SetVirtualServerRoutes +func (cc *ControllerFakeCollector) SetVirtualServerRoutes(count int) {}