From 348585d16ce1bc08f6d0447f516096e7d94a0be1 Mon Sep 17 00:00:00 2001 From: isuyyy Date: Wed, 26 Jun 2024 23:03:05 +0900 Subject: [PATCH 1/3] feat: add kube_ingress_status metric --- docs/metrics/service/ingress-metrics.md | 1 + internal/store/ingress.go | 22 +++++++++++ internal/store/ingress_test.go | 49 ++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/docs/metrics/service/ingress-metrics.md b/docs/metrics/service/ingress-metrics.md index 61faf115d3..ddbc67b820 100644 --- a/docs/metrics/service/ingress-metrics.md +++ b/docs/metrics/service/ingress-metrics.md @@ -9,3 +9,4 @@ | kube_ingress_metadata_resource_version | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | EXPERIMENTAL | | kube_ingress_path | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`host`=<ingress-host>
`path`=<ingress-path>
If path served by Service Backend
`service_name`=<service name for the path>
`service_port`=<service port for the path>
If path served by Resource Backend
`resource_api_group`=<resource backend api group>
`resource_kind`=<resource backend kind>
`resource_name`=<resource backend name> | STABLE | | kube_ingress_tls | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`tls_host`=<tls hostname>
`secret`=<tls secret name> | STABLE | +| kube_ingress_status | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`ip`=<ip>
`hostname`=<hostname>
`port`=<port>
`protocol`=<protocol> | STABLE | diff --git a/internal/store/ingress.go b/internal/store/ingress.go index ef04661689..80d2daa7ab 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -202,6 +202,28 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen } }), ), + *generator.NewFamilyGeneratorWithStability( + "kube_ingress_status", + "Ingress status.", + metric.Gauge, + basemetrics.STABLE, + "", + wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { + ms := []*metric.Metric{} + for _, ingress := range i.Status.LoadBalancer.Ingress { + for _, port := range ingress.Ports { + ms = append(ms, &metric.Metric{ + LabelKeys: []string{"ip", "hostname", "port", "protocol"}, + LabelValues: []string{ingress.IP, ingress.Hostname, strconv.Itoa(int(port.Port)), string(port.Protocol)}, + Value: 1, + }) + } + } + return &metric.Family{ + Metrics: ms, + } + }), + ), } } diff --git a/internal/store/ingress_test.go b/internal/store/ingress_test.go index c3902f7cbb..e95e9a4f1d 100644 --- a/internal/store/ingress_test.go +++ b/internal/store/ingress_test.go @@ -40,12 +40,14 @@ func TestIngressStore(t *testing.T) { # HELP kube_ingress_metadata_resource_version Resource version representing a specific version of ingress. # HELP kube_ingress_path [STABLE] Ingress host, paths and backend service information. # HELP kube_ingress_tls [STABLE] Ingress TLS host and secret information. + # HELP kube_ingress_status [STABLE] Ingress status. # TYPE kube_ingress_created gauge # TYPE kube_ingress_info gauge # TYPE kube_ingress_labels gauge # TYPE kube_ingress_metadata_resource_version gauge # TYPE kube_ingress_path gauge # TYPE kube_ingress_tls gauge + # TYPE kube_ingress_status gauge ` cases := []generateMetricsTestCase{ { @@ -97,7 +99,7 @@ func TestIngressStore(t *testing.T) { kube_ingress_created{namespace="ns2",ingress="ingress2"} 1.501569018e+09 kube_ingress_metadata_resource_version{namespace="ns2",ingress="ingress2"} 123456 `, - MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, }, { Obj: &networkingv1.Ingress{ @@ -113,7 +115,7 @@ func TestIngressStore(t *testing.T) { kube_ingress_info{namespace="ns3",ingress="ingress3",ingressclass="_default"} 1 kube_ingress_created{namespace="ns3",ingress="ingress3"} 1.501569018e+09 `, - MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, }, { Obj: &networkingv1.Ingress{ @@ -167,7 +169,7 @@ func TestIngressStore(t *testing.T) { kube_ingress_path{namespace="ns4",ingress="ingress4",host="somehost",path="/somepath",service_name="someservice",service_port="1234"} 1 kube_ingress_path{namespace="ns4",ingress="ingress4",host="somehost",path="/somepath2",resource_api_group="",resource_kind="somekind",resource_name="somename"} 1 `, - MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, }, { Obj: &networkingv1.Ingress{ @@ -193,7 +195,7 @@ func TestIngressStore(t *testing.T) { kube_ingress_tls{namespace="ns5",ingress="ingress5",tls_host="somehost1",secret="somesecret"} 1 kube_ingress_tls{namespace="ns5",ingress="ingress5",tls_host="somehost2",secret="somesecret"} 1 `, - MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, }, { Obj: &networkingv1.Ingress{ @@ -212,7 +214,7 @@ func TestIngressStore(t *testing.T) { kube_ingress_created{namespace="ns6",ingress="ingress6"} 1.501569018e+09 kube_ingress_metadata_resource_version{namespace="ns6",ingress="ingress6"} 123456 `, - MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, }, { Obj: &networkingv1.Ingress{ @@ -231,7 +233,42 @@ func TestIngressStore(t *testing.T) { kube_ingress_created{namespace="ns7",ingress="ingress7"} 1.501569018e+09 kube_ingress_metadata_resource_version{namespace="ns7",ingress="ingress7"} 123456 `, - MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, + }, + { + Obj: &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ingress8", + Namespace: "ns8", + CreationTimestamp: metav1StartTime, + ResourceVersion: "123456", + }, + Status: networkingv1.IngressStatus{ + LoadBalancer: networkingv1.IngressLoadBalancerStatus{ + Ingress: []networkingv1.IngressLoadBalancerIngress{ + { + + IP: "1.2.3.4", + Hostname: "www.example.com", + Ports: []networkingv1.IngressPortStatus{ + { + Port: 8888, + Protocol: "TCP", + Error: nil, + }, + }, + }, + }, + }, + }, + }, + Want: metadata + ` + kube_ingress_created{namespace="ns8",ingress="ingress8"} 1.501569018e+09 + kube_ingress_info{namespace="ns8",ingress="ingress8",ingressclass="_default"} 1 + kube_ingress_metadata_resource_version{namespace="ns8",ingress="ingress8"} 123456 + kube_ingress_status{namespace="ns8",ingress="ingress8",ip="1.2.3.4",hostname="www.example.com",port="8888",protocol="TCP"} 1 + `, + MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, }, } for i, c := range cases { From c88e3830358a860a0c5dd833c012d4a4ac7ee3fd Mon Sep 17 00:00:00 2001 From: isuyyy Date: Fri, 5 Jul 2024 11:25:42 +0900 Subject: [PATCH 2/3] Change metric stability level to EXPERIMENTAL --- docs/metrics/service/ingress-metrics.md | 2 +- internal/store/ingress.go | 2 +- internal/store/ingress_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/metrics/service/ingress-metrics.md b/docs/metrics/service/ingress-metrics.md index ddbc67b820..eeff8294b4 100644 --- a/docs/metrics/service/ingress-metrics.md +++ b/docs/metrics/service/ingress-metrics.md @@ -9,4 +9,4 @@ | kube_ingress_metadata_resource_version | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | EXPERIMENTAL | | kube_ingress_path | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`host`=<ingress-host>
`path`=<ingress-path>
If path served by Service Backend
`service_name`=<service name for the path>
`service_port`=<service port for the path>
If path served by Resource Backend
`resource_api_group`=<resource backend api group>
`resource_kind`=<resource backend kind>
`resource_name`=<resource backend name> | STABLE | | kube_ingress_tls | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`tls_host`=<tls hostname>
`secret`=<tls secret name> | STABLE | -| kube_ingress_status | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`ip`=<ip>
`hostname`=<hostname>
`port`=<port>
`protocol`=<protocol> | STABLE | +| kube_ingress_status | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`ip`=<ip>
`hostname`=<hostname>
`port`=<port>
`protocol`=<protocol> | EXPERIMENTAL | diff --git a/internal/store/ingress.go b/internal/store/ingress.go index 80d2daa7ab..ebc1ee300b 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -206,7 +206,7 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen "kube_ingress_status", "Ingress status.", metric.Gauge, - basemetrics.STABLE, + basemetrics.ALPHA, "", wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { ms := []*metric.Metric{} diff --git a/internal/store/ingress_test.go b/internal/store/ingress_test.go index e95e9a4f1d..84ebaea837 100644 --- a/internal/store/ingress_test.go +++ b/internal/store/ingress_test.go @@ -40,7 +40,7 @@ func TestIngressStore(t *testing.T) { # HELP kube_ingress_metadata_resource_version Resource version representing a specific version of ingress. # HELP kube_ingress_path [STABLE] Ingress host, paths and backend service information. # HELP kube_ingress_tls [STABLE] Ingress TLS host and secret information. - # HELP kube_ingress_status [STABLE] Ingress status. + # HELP kube_ingress_status Ingress status. # TYPE kube_ingress_created gauge # TYPE kube_ingress_info gauge # TYPE kube_ingress_labels gauge From 622505e6ce1e0df535e61d69e636a5962c70ce50 Mon Sep 17 00:00:00 2001 From: isuyyy Date: Fri, 5 Jul 2024 13:42:14 +0900 Subject: [PATCH 3/3] Remove the ip field --- docs/metrics/service/ingress-metrics.md | 2 +- internal/store/ingress.go | 4 ++-- internal/store/ingress_test.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/metrics/service/ingress-metrics.md b/docs/metrics/service/ingress-metrics.md index eeff8294b4..e1a1b43d94 100644 --- a/docs/metrics/service/ingress-metrics.md +++ b/docs/metrics/service/ingress-metrics.md @@ -9,4 +9,4 @@ | kube_ingress_metadata_resource_version | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | EXPERIMENTAL | | kube_ingress_path | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`host`=<ingress-host>
`path`=<ingress-path>
If path served by Service Backend
`service_name`=<service name for the path>
`service_port`=<service port for the path>
If path served by Resource Backend
`resource_api_group`=<resource backend api group>
`resource_kind`=<resource backend kind>
`resource_name`=<resource backend name> | STABLE | | kube_ingress_tls | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`tls_host`=<tls hostname>
`secret`=<tls secret name> | STABLE | -| kube_ingress_status | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`ip`=<ip>
`hostname`=<hostname>
`port`=<port>
`protocol`=<protocol> | EXPERIMENTAL | +| kube_ingress_status | Gauge | | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`hostname`=<hostname>
`port`=<port>
`protocol`=<protocol> | EXPERIMENTAL | diff --git a/internal/store/ingress.go b/internal/store/ingress.go index ebc1ee300b..ca320b13c7 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -213,8 +213,8 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen for _, ingress := range i.Status.LoadBalancer.Ingress { for _, port := range ingress.Ports { ms = append(ms, &metric.Metric{ - LabelKeys: []string{"ip", "hostname", "port", "protocol"}, - LabelValues: []string{ingress.IP, ingress.Hostname, strconv.Itoa(int(port.Port)), string(port.Protocol)}, + LabelKeys: []string{"hostname", "port", "protocol"}, + LabelValues: []string{ingress.Hostname, strconv.Itoa(int(port.Port)), string(port.Protocol)}, Value: 1, }) } diff --git a/internal/store/ingress_test.go b/internal/store/ingress_test.go index 84ebaea837..5638612992 100644 --- a/internal/store/ingress_test.go +++ b/internal/store/ingress_test.go @@ -266,7 +266,7 @@ func TestIngressStore(t *testing.T) { kube_ingress_created{namespace="ns8",ingress="ingress8"} 1.501569018e+09 kube_ingress_info{namespace="ns8",ingress="ingress8",ingressclass="_default"} 1 kube_ingress_metadata_resource_version{namespace="ns8",ingress="ingress8"} 123456 - kube_ingress_status{namespace="ns8",ingress="ingress8",ip="1.2.3.4",hostname="www.example.com",port="8888",protocol="TCP"} 1 + kube_ingress_status{namespace="ns8",ingress="ingress8",hostname="www.example.com",port="8888",protocol="TCP"} 1 `, MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls", "kube_ingress_status"}, },