Skip to content

Commit

Permalink
add service count metric to telemetry (#5408)
Browse files Browse the repository at this point in the history
* add service metric to telemetry

* add secretStore to service count tests

* add backup and grpc service counting

* fix test for ingress counts

* Add tests for mergeable and standard ingress

* Update docs/content/overview/product-telemetry.md

Co-authored-by: Venktesh Shivam Patel <[email protected]>
Signed-off-by: Jim Ryan <[email protected]>

---------

Signed-off-by: Jim Ryan <[email protected]>
Co-authored-by: Venktesh Shivam Patel <[email protected]>
  • Loading branch information
Jim Ryan and vepatel authored Apr 17, 2024
1 parent 2ad69d0 commit b6dd338
Show file tree
Hide file tree
Showing 7 changed files with 763 additions and 5 deletions.
3 changes: 2 additions & 1 deletion docs/content/overview/product-telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ These are the data points collected and reported by NGINX Ingress Controller:
- **TransportServers** The number of TransportServer resources managed by NGINX Ingress Controller.
- **Replicas** Number of Deployment replicas, or Daemonset instances.
- **Secrets** Number of Secret resources managed by NGINX Ingress Controller.
- **Ingress Count** Number of Ingresses.
- **Services** Number of Services referenced by VirtualServers, VirtualServerRoutes, TransportServers and Ingresses.
- **IngressCount** Number of Ingresses.


## Opt out
Expand Down
106 changes: 106 additions & 0 deletions internal/configs/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ type Configurator struct {
templateExecutorV2 *version2.TemplateExecutor
ingresses map[string]*IngressEx
minions map[string]map[string]bool
mergeableIngresses map[string]*MergeableIngresses
virtualServers map[string]*VirtualServerEx
transportServers map[string]*TransportServerEx
tlsPassthroughPairs map[string]tlsPassthroughPair
Expand Down Expand Up @@ -180,6 +181,7 @@ func NewConfigurator(p ConfiguratorParams) *Configurator {
templateExecutor: p.TemplateExecutor,
templateExecutorV2: p.TemplateExecutorV2,
minions: make(map[string]map[string]bool),
mergeableIngresses: make(map[string]*MergeableIngresses),
tlsPassthroughPairs: make(map[string]tlsPassthroughPair),
isPlus: p.IsPlus,
isWildcardEnabled: p.IsWildcardEnabled,
Expand Down Expand Up @@ -475,6 +477,9 @@ func (cnf *Configurator) addOrUpdateMergeableIngress(mergeableIngs *MergeableIng
minionName := objectMetaToFileName(&minion.Ingress.ObjectMeta)
cnf.minions[name][minionName] = true
}

cnf.mergeableIngresses[name] = mergeableIngs

if (cnf.isPlus && cnf.isPrometheusEnabled) || cnf.isLatencyMetricsEnabled {
cnf.updateIngressMetricsLabels(mergeableIngs.Master, nginxCfg.Upstreams)
}
Expand Down Expand Up @@ -955,6 +960,7 @@ func (cnf *Configurator) DeleteIngress(key string, skipReload bool) error {

delete(cnf.ingresses, name)
delete(cnf.minions, name)
delete(cnf.mergeableIngresses, name)

if (cnf.isPlus && cnf.isPrometheusEnabled) || cnf.isLatencyMetricsEnabled {
cnf.deleteIngressMetricsLabels(key)
Expand Down Expand Up @@ -1542,6 +1548,106 @@ func (cnf *Configurator) GetIngressCounts() map[string]int {
return counters
}

// GetServiceCount returns the total number of unique services referenced by Ingresses, VS's, VSR's, and TS's
func (cnf *Configurator) GetServiceCount() int {
setOfUniqueServices := make(map[string]bool)
cnf.addVSAndVSRServicesToSet(setOfUniqueServices)
cnf.addTSServicesToSet(setOfUniqueServices)
cnf.addIngressesServicesToSet(setOfUniqueServices)
return len(setOfUniqueServices)
}

// addVSAndVSRServicesToSet adds services from VirtualServers and VirtualServerRoutes to the set
func (cnf *Configurator) addVSAndVSRServicesToSet(set map[string]bool) {
for _, vs := range cnf.virtualServers {
ns := vs.VirtualServer.Namespace
for _, upstream := range vs.VirtualServer.Spec.Upstreams {
svc := upstream.Service
addServiceToSet(set, ns, svc)

if upstream.Backup != "" {
addServiceToSet(set, ns, upstream.Backup)
}

if upstream.HealthCheck != nil && upstream.HealthCheck.GRPCService != "" {
addServiceToSet(set, ns, upstream.HealthCheck.GRPCService)
}
}

for _, vsr := range vs.VirtualServerRoutes {
ns := vsr.Namespace
for _, upstream := range vsr.Spec.Upstreams {
svc := upstream.Service
addServiceToSet(set, ns, svc)

if upstream.Backup != "" {
addServiceToSet(set, ns, upstream.Backup)
}

if upstream.HealthCheck != nil && upstream.HealthCheck.GRPCService != "" {
addServiceToSet(set, ns, upstream.HealthCheck.GRPCService)
}
}
}
}
}

// addTSServicesToSet adds services from TransportServers to the set
func (cnf *Configurator) addTSServicesToSet(set map[string]bool) {
for _, ts := range cnf.transportServers {
ns := ts.TransportServer.Namespace
for _, upstream := range ts.TransportServer.Spec.Upstreams {
svc := upstream.Service
addServiceToSet(set, ns, svc)

if upstream.Backup != "" {
addServiceToSet(set, ns, upstream.Backup)
}

}
}
}

// addIngressesServicesToSet adds services from Ingresses to the set
func (cnf *Configurator) addIngressesServicesToSet(set map[string]bool) {
for _, ing := range cnf.ingresses {
cnf.addIngressServicesToSet(ing, set)
}
for _, mergeIngs := range cnf.mergeableIngresses {
cnf.addIngressServicesToSet(mergeIngs.Master, set)
for _, minion := range mergeIngs.Minions {
cnf.addIngressServicesToSet(minion, set)
}
}
}

// addIngressServicesToSet processes a single ingress and adds its services to the set
func (cnf *Configurator) addIngressServicesToSet(ing *IngressEx, set map[string]bool) {
if ing == nil || ing.Ingress == nil {
return
}
ns := ing.Ingress.Namespace
if ing.Ingress.Spec.DefaultBackend != nil && ing.Ingress.Spec.DefaultBackend.Service != nil {
svc := ing.Ingress.Spec.DefaultBackend.Service.Name
addServiceToSet(set, ns, svc)
}
for _, rule := range ing.Ingress.Spec.Rules {
if rule.HTTP != nil {
for _, path := range rule.HTTP.Paths {
if path.Backend.Service != nil {
svc := path.Backend.Service.Name
addServiceToSet(set, ns, svc)
}
}
}
}
}

// Helper function to add services to the set
func addServiceToSet(set map[string]bool, ns string, svc string) {
set[fmt.Sprintf("%s/%s", ns, svc)] = true
}

// GetVirtualServerCounts returns the total count of
// VirtualServer and VirtualServerRoute resources that are handled by the Ingress Controller
func (cnf *Configurator) GetVirtualServerCounts() (int, int) {
Expand Down
5 changes: 5 additions & 0 deletions internal/telemetry/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func (c *Collector) Collect(ctx context.Context) {
TransportServers: int64(report.TransportServers),
Replicas: int64(report.NICReplicaCount),
Secrets: int64(report.Secrets),
Services: int64(report.ServiceCount),
Ingresses: int64(report.IngressCount),
},
}
Expand All @@ -142,6 +143,7 @@ type Report struct {
NICReplicaCount int
VirtualServers int
VirtualServerRoutes int
ServiceCount int
TransportServers int
Secrets int
IngressCount int
Expand All @@ -152,10 +154,12 @@ func (c *Collector) BuildReport(ctx context.Context) (Report, error) {
vsCount := 0
vsrCount := 0
tsCount := 0
serviceCount := 0

if c.Config.Configurator != nil {
vsCount, vsrCount = c.Config.Configurator.GetVirtualServerCounts()
tsCount = c.Config.Configurator.GetTransportServerCounts()
serviceCount = c.Config.Configurator.GetServiceCount()
}

clusterID, err := c.ClusterID(ctx)
Expand Down Expand Up @@ -206,6 +210,7 @@ func (c *Collector) BuildReport(ctx context.Context) (Report, error) {
NICReplicaCount: replicas,
VirtualServers: vsCount,
VirtualServerRoutes: vsrCount,
ServiceCount: serviceCount,
TransportServers: tsCount,
Secrets: secrets,
IngressCount: ingressCount,
Expand Down
Loading

0 comments on commit b6dd338

Please sign in to comment.