Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add service count metric to telemetry #5408

Merged
merged 9 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/content/overview/product-telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ 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.
- **Services** Number of Services referenced by VirtualServers, VirtualServerRoutes, TransportServers and Ingresses.
- **Ingress Count** Number of Ingresses.
j1m-ryan marked this conversation as resolved.
Show resolved Hide resolved


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
Loading