From b1f1bd7f11b769c49f658f43e9f9be7cb3fe686f Mon Sep 17 00:00:00 2001 From: Sarthak Agrawal Date: Fri, 9 Aug 2024 11:11:59 -0600 Subject: [PATCH 1/3] Add NGF telemetry data for TLSRoute Problem: NGF did not support telemetry for TLSRoute Solution: I counted the number of TLSRoutes in the graph and added it to the telemetry data --- internal/mode/static/telemetry/collector.go | 29 +++++++++++++++++-- .../mode/static/telemetry/collector_test.go | 11 +++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/internal/mode/static/telemetry/collector.go b/internal/mode/static/telemetry/collector.go index 6dccd0562e..64973da90e 100644 --- a/internal/mode/static/telemetry/collector.go +++ b/internal/mode/static/telemetry/collector.go @@ -62,6 +62,8 @@ type NGFResourceCounts struct { GatewayClassCount int64 // HTTPRouteCount is the number of relevant HTTPRoutes. HTTPRouteCount int64 + // TLSRouteCount is the number of relevant TLSRoutes. + TLSRouteCount int64 // SecretCount is the number of relevant Secrets. SecretCount int64 // ServiceCount is the number of relevant Services. @@ -188,7 +190,11 @@ func collectGraphResourceCount( ngfResourceCounts.GatewayCount++ } - ngfResourceCounts.HTTPRouteCount, ngfResourceCounts.GRPCRouteCount = computeRouteCount(g.Routes) + routeCounts := computeRouteCount(g.Routes, g.L4Routes) + ngfResourceCounts.HTTPRouteCount = routeCounts.HTTPRouteCount + ngfResourceCounts.GRPCRouteCount = routeCounts.GRPCRouteCount + ngfResourceCounts.TLSRouteCount = routeCounts.TLSRouteCount + ngfResourceCounts.SecretCount = int64(len(g.ReferencedSecrets)) ngfResourceCounts.ServiceCount = int64(len(g.ReferencedServices)) @@ -224,7 +230,19 @@ func collectGraphResourceCount( return ngfResourceCounts, nil } -func computeRouteCount(routes map[graph.RouteKey]*graph.L7Route) (httpRouteCount, grpcRouteCount int64) { +type RouteCounts struct { + HTTPRouteCount int64 + GRPCRouteCount int64 + TLSRouteCount int64 +} + +func computeRouteCount( + routes map[graph.RouteKey]*graph.L7Route, + l4routes map[graph.L4RouteKey]*graph.L4Route, +) RouteCounts { + httpRouteCount := int64(0) + grpcRouteCount := int64(0) + for _, r := range routes { if r.RouteType == graph.RouteTypeHTTP { httpRouteCount = httpRouteCount + 1 @@ -233,7 +251,12 @@ func computeRouteCount(routes map[graph.RouteKey]*graph.L7Route) (httpRouteCount grpcRouteCount = grpcRouteCount + 1 } } - return httpRouteCount, grpcRouteCount + + return RouteCounts{ + HTTPRouteCount: httpRouteCount, + GRPCRouteCount: grpcRouteCount, + TLSRouteCount: int64(len(l4routes)), + } } func getPodReplicaSet( diff --git a/internal/mode/static/telemetry/collector_test.go b/internal/mode/static/telemetry/collector_test.go index 09b14b0c54..4aa1ab99bd 100644 --- a/internal/mode/static/telemetry/collector_test.go +++ b/internal/mode/static/telemetry/collector_test.go @@ -287,6 +287,11 @@ var _ = Describe("Collector", Ordered, func() { {NamespacedName: types.NamespacedName{Namespace: "test", Name: "gr-1"}}: {RouteType: graph.RouteTypeGRPC}, {NamespacedName: types.NamespacedName{Namespace: "test", Name: "gr-2"}}: {RouteType: graph.RouteTypeGRPC}, }, + L4Routes: map[graph.L4RouteKey]*graph.L4Route{ + {NamespacedName: types.NamespacedName{Namespace: "test", Name: "tr-1"}}: {}, + {NamespacedName: types.NamespacedName{Namespace: "test", Name: "tr-2"}}: {}, + {NamespacedName: types.NamespacedName{Namespace: "test", Name: "tr-3"}}: {}, + }, ReferencedSecrets: map[types.NamespacedName]*graph.Secret{ client.ObjectKeyFromObject(secret1): { Source: secret1, @@ -366,6 +371,7 @@ var _ = Describe("Collector", Ordered, func() { GatewayCount: 3, GatewayClassCount: 3, HTTPRouteCount: 3, + TLSRouteCount: 3, SecretCount: 3, ServiceCount: 3, EndpointCount: 4, @@ -512,6 +518,9 @@ var _ = Describe("Collector", Ordered, func() { Routes: map[graph.RouteKey]*graph.L7Route{ {NamespacedName: types.NamespacedName{Namespace: "test", Name: "hr-1"}}: {RouteType: graph.RouteTypeHTTP}, }, + L4Routes: map[graph.L4RouteKey]*graph.L4Route{ + {NamespacedName: types.NamespacedName{Namespace: "test", Name: "tr-1"}}: {}, + }, ReferencedSecrets: map[types.NamespacedName]*graph.Secret{ client.ObjectKeyFromObject(secret): { Source: secret, @@ -604,6 +613,7 @@ var _ = Describe("Collector", Ordered, func() { GatewayCount: 1, GatewayClassCount: 1, HTTPRouteCount: 1, + TLSRouteCount: 1, SecretCount: 1, ServiceCount: 1, EndpointCount: 1, @@ -626,6 +636,7 @@ var _ = Describe("Collector", Ordered, func() { GatewayCount: 0, GatewayClassCount: 0, HTTPRouteCount: 0, + TLSRouteCount: 0, SecretCount: 0, ServiceCount: 0, EndpointCount: 0, From 120f78e648b850a243fbed419927097cab1168b2 Mon Sep 17 00:00:00 2001 From: Sarthak Agrawal Date: Fri, 9 Aug 2024 11:31:54 -0600 Subject: [PATCH 2/3] finish update to data schema and site --- internal/mode/static/telemetry/data.avdl | 53 ++++++++++--------- internal/mode/static/telemetry/data_test.go | 3 ++ .../ngfresourcecounts_attributes_generated.go | 6 +-- site/content/overview/product-telemetry.md | 2 +- tests/suite/telemetry_test.go | 1 + 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/internal/mode/static/telemetry/data.avdl b/internal/mode/static/telemetry/data.avdl index 7d32720600..be77067c6e 100644 --- a/internal/mode/static/telemetry/data.avdl +++ b/internal/mode/static/telemetry/data.avdl @@ -7,82 +7,85 @@ /** The time our edge ingested the event */ long ingestTime; - + /** ImageSource tells whether the image was built by GitHub or locally (values are 'gha', 'local', or 'unknown') */ string? ImageSource = null; - + /** ProjectName is the name of the project. */ string? ProjectName = null; - + /** ProjectVersion is the version of the project. */ string? ProjectVersion = null; - + /** ProjectArchitecture is the architecture of the project. For example, "amd64". */ string? ProjectArchitecture = null; - + /** ClusterID is the unique id of the Kubernetes cluster where the project is installed. It is the UID of the `kube-system` Namespace. */ string? ClusterID = null; - + /** ClusterVersion is the Kubernetes version of the cluster. */ string? ClusterVersion = null; - + /** ClusterPlatform is the Kubernetes platform of the cluster. */ string? ClusterPlatform = null; - + /** InstallationID is the unique id of the project installation in the cluster. */ string? InstallationID = null; - + /** ClusterNodeCount is the number of nodes in the cluster. */ long? ClusterNodeCount = null; - + /** FlagNames contains the command-line flag names. */ union {null, array} FlagNames = null; - + /** FlagValues contains the values of the command-line flags, where each value corresponds to the flag from FlagNames at the same index. Each value is either 'true' or 'false' for boolean flags and 'default' or 'user-defined' for non-boolean flags. */ union {null, array} FlagValues = null; - + /** GatewayCount is the number of relevant Gateways. */ long? GatewayCount = null; - + /** GatewayClassCount is the number of relevant GatewayClasses. */ long? GatewayClassCount = null; - + /** HTTPRouteCount is the number of relevant HTTPRoutes. */ long? HTTPRouteCount = null; - + + /** TLSRouteCount is the number of relevant TLSRoutes. */ + long? TLSRouteCount = null; + /** SecretCount is the number of relevant Secrets. */ long? SecretCount = null; - + /** ServiceCount is the number of relevant Services. */ long? ServiceCount = null; - + /** EndpointCount include the total count of Endpoints(IP:port) across all referenced services. */ long? EndpointCount = null; - + /** GRPCRouteCount is the number of relevant GRPCRoutes. */ long? GRPCRouteCount = null; - + /** BackendTLSPolicyCount is the number of relevant BackendTLSPolicies. */ long? BackendTLSPolicyCount = null; - + /** GatewayAttachedClientSettingsPolicyCount is the number of relevant ClientSettingsPolicies attached at the Gateway level. */ long? GatewayAttachedClientSettingsPolicyCount = null; - + /** RouteAttachedClientSettingsPolicyCount is the number of relevant ClientSettingsPolicies attached at the Route level. */ long? RouteAttachedClientSettingsPolicyCount = null; - + /** ObservabilityPolicyCount is the number of relevant ObservabilityPolicies. */ long? ObservabilityPolicyCount = null; - + /** NginxProxyCount is the number of NginxProxies. */ long? NginxProxyCount = null; - + /** NGFReplicaCount is the number of replicas of the NGF Pod. */ long? NGFReplicaCount = null; - + } } diff --git a/internal/mode/static/telemetry/data_test.go b/internal/mode/static/telemetry/data_test.go index cb4b09df86..62bb54f6c8 100644 --- a/internal/mode/static/telemetry/data_test.go +++ b/internal/mode/static/telemetry/data_test.go @@ -31,6 +31,7 @@ func TestDataAttributes(t *testing.T) { ServiceCount: 5, EndpointCount: 6, GRPCRouteCount: 7, + TLSRouteCount: 5, BackendTLSPolicyCount: 8, GatewayAttachedClientSettingsPolicyCount: 9, RouteAttachedClientSettingsPolicyCount: 10, @@ -56,6 +57,7 @@ func TestDataAttributes(t *testing.T) { attribute.Int64("GatewayCount", 1), attribute.Int64("GatewayClassCount", 2), attribute.Int64("HTTPRouteCount", 3), + attribute.Int64("TLSRouteCount", 5), attribute.Int64("SecretCount", 4), attribute.Int64("ServiceCount", 5), attribute.Int64("EndpointCount", 6), @@ -93,6 +95,7 @@ func TestDataAttributesWithEmptyData(t *testing.T) { attribute.Int64("GatewayCount", 0), attribute.Int64("GatewayClassCount", 0), attribute.Int64("HTTPRouteCount", 0), + attribute.Int64("TLSRouteCount", 0), attribute.Int64("SecretCount", 0), attribute.Int64("ServiceCount", 0), attribute.Int64("EndpointCount", 0), diff --git a/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go b/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go index 1224cb096a..613469e2df 100644 --- a/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go +++ b/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go @@ -1,5 +1,5 @@ - package telemetry + /* This is a generated file. DO NOT EDIT. */ @@ -7,9 +7,7 @@ This is a generated file. DO NOT EDIT. import ( "go.opentelemetry.io/otel/attribute" - ngxTelemetry "github.com/nginxinc/telemetry-exporter/pkg/telemetry" - ) func (d *NGFResourceCounts) Attributes() []attribute.KeyValue { @@ -18,6 +16,7 @@ func (d *NGFResourceCounts) Attributes() []attribute.KeyValue { attrs = append(attrs, attribute.Int64("GatewayCount", d.GatewayCount)) attrs = append(attrs, attribute.Int64("GatewayClassCount", d.GatewayClassCount)) attrs = append(attrs, attribute.Int64("HTTPRouteCount", d.HTTPRouteCount)) + attrs = append(attrs, attribute.Int64("TLSRouteCount", d.TLSRouteCount)) attrs = append(attrs, attribute.Int64("SecretCount", d.SecretCount)) attrs = append(attrs, attribute.Int64("ServiceCount", d.ServiceCount)) attrs = append(attrs, attribute.Int64("EndpointCount", d.EndpointCount)) @@ -27,7 +26,6 @@ func (d *NGFResourceCounts) Attributes() []attribute.KeyValue { attrs = append(attrs, attribute.Int64("RouteAttachedClientSettingsPolicyCount", d.RouteAttachedClientSettingsPolicyCount)) attrs = append(attrs, attribute.Int64("ObservabilityPolicyCount", d.ObservabilityPolicyCount)) attrs = append(attrs, attribute.Int64("NginxProxyCount", d.NginxProxyCount)) - return attrs } diff --git a/site/content/overview/product-telemetry.md b/site/content/overview/product-telemetry.md index 4b222c5b6b..cb13b6997a 100644 --- a/site/content/overview/product-telemetry.md +++ b/site/content/overview/product-telemetry.md @@ -27,7 +27,7 @@ Telemetry data is collected once every 24 hours and sent to a service managed by - **Deployment Replica Count:** the count of NGINX Gateway Fabric Pods. - **Image Build Source:** whether the image was built by GitHub or locally (values are `gha`, `local`, or `unknown`). The source repository of the images is **not** collected. - **Deployment Flags:** a list of NGINX Gateway Fabric Deployment flags that are specified by a user. The actual values of non-boolean flags are **not** collected; we only record that they are either `true` or `false` for boolean flags and `default` or `user-defined` for the rest. -- **Count of Resources:** the total count of resources related to NGINX Gateway Fabric. This includes `GatewayClasses`, `Gateways`, `HTTPRoutes`,`GRPCRoutes`, `Secrets`, `Services`, `BackendTLSPolicies`, `ClientSettingsPolicies`, `NginxProxies`, `ObservabilityPolicies`, and `Endpoints`. The data within these resources is **not** collected. +- **Count of Resources:** the total count of resources related to NGINX Gateway Fabric. This includes `GatewayClasses`, `Gateways`, `HTTPRoutes`,`GRPCRoutes`, `TLSRoutes`, `Secrets`, `Services`, `BackendTLSPolicies`, `ClientSettingsPolicies`, `NginxProxies`, `ObservabilityPolicies`, and `Endpoints`. The data within these resources is **not** collected. This data is used to identify the following information: diff --git a/tests/suite/telemetry_test.go b/tests/suite/telemetry_test.go index 3ce1ec6669..a88cfd3ee0 100644 --- a/tests/suite/telemetry_test.go +++ b/tests/suite/telemetry_test.go @@ -75,6 +75,7 @@ var _ = Describe("Telemetry test with OTel collector", Label("telemetry"), func( "GatewayCount: Int(0)", "GatewayClassCount: Int(1)", "HTTPRouteCount: Int(0)", + "TLSRouteCount: Int(0)", "SecretCount: Int(0)", "ServiceCount: Int(0)", "EndpointCount: Int(0)", From cb9195c227c9252db3add5a38f2a265eb0b8ef72 Mon Sep 17 00:00:00 2001 From: Sarthak Agrawal Date: Fri, 9 Aug 2024 11:59:04 -0600 Subject: [PATCH 3/3] ran make generate --- internal/mode/static/telemetry/data.avdl | 54 +++++++++---------- .../ngfresourcecounts_attributes_generated.go | 5 +- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/internal/mode/static/telemetry/data.avdl b/internal/mode/static/telemetry/data.avdl index be77067c6e..ab56a4280a 100644 --- a/internal/mode/static/telemetry/data.avdl +++ b/internal/mode/static/telemetry/data.avdl @@ -7,85 +7,85 @@ /** The time our edge ingested the event */ long ingestTime; - + /** ImageSource tells whether the image was built by GitHub or locally (values are 'gha', 'local', or 'unknown') */ string? ImageSource = null; - + /** ProjectName is the name of the project. */ string? ProjectName = null; - + /** ProjectVersion is the version of the project. */ string? ProjectVersion = null; - + /** ProjectArchitecture is the architecture of the project. For example, "amd64". */ string? ProjectArchitecture = null; - + /** ClusterID is the unique id of the Kubernetes cluster where the project is installed. It is the UID of the `kube-system` Namespace. */ string? ClusterID = null; - + /** ClusterVersion is the Kubernetes version of the cluster. */ string? ClusterVersion = null; - + /** ClusterPlatform is the Kubernetes platform of the cluster. */ string? ClusterPlatform = null; - + /** InstallationID is the unique id of the project installation in the cluster. */ string? InstallationID = null; - + /** ClusterNodeCount is the number of nodes in the cluster. */ long? ClusterNodeCount = null; - + /** FlagNames contains the command-line flag names. */ union {null, array} FlagNames = null; - + /** FlagValues contains the values of the command-line flags, where each value corresponds to the flag from FlagNames at the same index. Each value is either 'true' or 'false' for boolean flags and 'default' or 'user-defined' for non-boolean flags. */ union {null, array} FlagValues = null; - + /** GatewayCount is the number of relevant Gateways. */ long? GatewayCount = null; - + /** GatewayClassCount is the number of relevant GatewayClasses. */ long? GatewayClassCount = null; - + /** HTTPRouteCount is the number of relevant HTTPRoutes. */ long? HTTPRouteCount = null; - + /** TLSRouteCount is the number of relevant TLSRoutes. */ - long? TLSRouteCount = null; - + long? TLSRouteCount = null; + /** SecretCount is the number of relevant Secrets. */ long? SecretCount = null; - + /** ServiceCount is the number of relevant Services. */ long? ServiceCount = null; - + /** EndpointCount include the total count of Endpoints(IP:port) across all referenced services. */ long? EndpointCount = null; - + /** GRPCRouteCount is the number of relevant GRPCRoutes. */ long? GRPCRouteCount = null; - + /** BackendTLSPolicyCount is the number of relevant BackendTLSPolicies. */ long? BackendTLSPolicyCount = null; - + /** GatewayAttachedClientSettingsPolicyCount is the number of relevant ClientSettingsPolicies attached at the Gateway level. */ long? GatewayAttachedClientSettingsPolicyCount = null; - + /** RouteAttachedClientSettingsPolicyCount is the number of relevant ClientSettingsPolicies attached at the Route level. */ long? RouteAttachedClientSettingsPolicyCount = null; - + /** ObservabilityPolicyCount is the number of relevant ObservabilityPolicies. */ long? ObservabilityPolicyCount = null; - + /** NginxProxyCount is the number of NginxProxies. */ long? NginxProxyCount = null; - + /** NGFReplicaCount is the number of replicas of the NGF Pod. */ long? NGFReplicaCount = null; - + } } diff --git a/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go b/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go index 613469e2df..ea8e793a91 100644 --- a/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go +++ b/internal/mode/static/telemetry/ngfresourcecounts_attributes_generated.go @@ -1,5 +1,5 @@ -package telemetry +package telemetry /* This is a generated file. DO NOT EDIT. */ @@ -7,7 +7,9 @@ This is a generated file. DO NOT EDIT. import ( "go.opentelemetry.io/otel/attribute" + ngxTelemetry "github.com/nginxinc/telemetry-exporter/pkg/telemetry" + ) func (d *NGFResourceCounts) Attributes() []attribute.KeyValue { @@ -26,6 +28,7 @@ func (d *NGFResourceCounts) Attributes() []attribute.KeyValue { attrs = append(attrs, attribute.Int64("RouteAttachedClientSettingsPolicyCount", d.RouteAttachedClientSettingsPolicyCount)) attrs = append(attrs, attribute.Int64("ObservabilityPolicyCount", d.ObservabilityPolicyCount)) attrs = append(attrs, attribute.Int64("NginxProxyCount", d.NginxProxyCount)) + return attrs }