diff --git a/docs/metrics/service/endpoint-metrics.md b/docs/metrics/service/endpoint-metrics.md
index 6cf0823f3..da4152d9c 100644
--- a/docs/metrics/service/endpoint-metrics.md
+++ b/docs/metrics/service/endpoint-metrics.md
@@ -6,5 +6,5 @@
| kube_endpoint_info | Gauge | | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE |
| kube_endpoint_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`label_ENDPOINT_LABEL`=<ENDPOINT_LABEL> | STABLE |
| kube_endpoint_created | Gauge | | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE |
-| kube_endpoint_ports | Gauge | | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`port_name`=<endpoint-port-name>
`port_protocol`=<endpoint-port-protocol>
`port_number`=<endpoint-port-number> | STABLE |
-| kube_endpoint_address | Gauge | | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`ip`=<endpoint-ip>
`ready`=<true if available, false if unavailalbe> | STABLE |
+| kube_endpoint_ports | Gauge | | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`port_name`=<endpoint-port-name>
`port_protocol`=<endpoint-port-protocol>
`port_number`=<endpoint-port-number> | STABLE (Deprecated from 2.14.0) |
+| kube_endpoint_address | Gauge | | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`ip`=<endpoint-ip>
`port_name`=<endpoint-port-name>
`port_protocol`=<endpoint-port-protocol>
`port_number`=<endpoint-port-number>`ready`=<true if available, false if unavailalbe> | STABLE |
diff --git a/internal/store/endpoint.go b/internal/store/endpoint.go
index 5694cdfc1..bdb8f43f7 100644
--- a/internal/store/endpoint.go
+++ b/internal/store/endpoint.go
@@ -132,19 +132,37 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge
wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family {
ms := []*metric.Metric{}
for _, s := range e.Subsets {
- for _, available := range s.Addresses {
- ms = append(ms, &metric.Metric{
- LabelValues: []string{available.IP, "true"},
- LabelKeys: []string{"ip", "ready"},
- Value: 1,
- })
- }
- for _, notReadyAddresses := range s.NotReadyAddresses {
- ms = append(ms, &metric.Metric{
- LabelValues: []string{notReadyAddresses.IP, "false"},
- LabelKeys: []string{"ip", "ready"},
- Value: 1,
- })
+ for _, port := range s.Ports {
+ for _, available := range s.Addresses {
+ labelValues := []string{string(port.Protocol), strconv.FormatInt(int64(port.Port), 10)}
+ labelKeys := []string{"port_protocol", "port_number"}
+
+ if port.Name != "" {
+ labelKeys = append(labelKeys, "port_name")
+ labelValues = append(labelValues, port.Name)
+ }
+
+ ms = append(ms, &metric.Metric{
+ LabelValues: append(labelValues, available.IP, "true"),
+ LabelKeys: append(labelKeys, "ip", "ready"),
+ Value: 1,
+ })
+ }
+ for _, notReadyAddresses := range s.NotReadyAddresses {
+ labelValues := []string{string(port.Protocol), strconv.FormatInt(int64(port.Port), 10)}
+ labelKeys := []string{"port_protocol", "port_number"}
+
+ if port.Name != "" {
+ labelKeys = append(labelKeys, "port_name")
+ labelValues = append(labelValues, port.Name)
+ }
+
+ ms = append(ms, &metric.Metric{
+ LabelValues: append(labelValues, notReadyAddresses.IP, "false"),
+ LabelKeys: append(labelKeys, "ip", "ready"),
+ Value: 1,
+ })
+ }
}
}
return &metric.Family{
@@ -157,7 +175,7 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge
"Information about the Endpoint ports.",
metric.Gauge,
basemetrics.STABLE,
- "",
+ "v2.14.0",
wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family {
ms := []*metric.Metric{}
for _, s := range e.Subsets {
diff --git a/internal/store/endpoint_test.go b/internal/store/endpoint_test.go
index 87205f4d5..984b13e72 100644
--- a/internal/store/endpoint_test.go
+++ b/internal/store/endpoint_test.go
@@ -38,7 +38,7 @@ func TestEndpointStore(t *testing.T) {
# TYPE kube_endpoint_info gauge
# HELP kube_endpoint_labels [STABLE] Kubernetes labels converted to Prometheus labels.
# TYPE kube_endpoint_labels gauge
- # HELP kube_endpoint_ports [STABLE] Information about the Endpoint ports.
+ # HELP kube_endpoint_ports [STABLE] (Deprecated since v2.14.0) Information about the Endpoint ports.
# TYPE kube_endpoint_ports gauge
# HELP kube_endpoint_address [STABLE] Information about Endpoint available and non available addresses.
# TYPE kube_endpoint_address gauge
@@ -87,18 +87,24 @@ func TestEndpointStore(t *testing.T) {
Want: metadata + `
kube_endpoint_created{endpoint="test-endpoint",namespace="default"} 1.5e+09
kube_endpoint_info{endpoint="test-endpoint",namespace="default"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.1",namespace="default",port_name="app",port_number="8081",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.1",namespace="default",port_name="http",port_number="8080",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.10",namespace="default",port_name="app",port_number="8081",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.10",namespace="default",port_name="http",port_number="8080",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="127.0.0.1",namespace="default",port_name="app",port_number="8081",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="127.0.0.1",namespace="default",port_name="http",port_number="8080",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="172.22.23.202",namespace="default",port_name="https",port_number="8443",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="172.22.23.202",namespace="default",port_name="prometheus",port_number="9090",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.1.3",namespace="default",port_name="syslog",port_number="1234",port_protocol="UDP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.1.3",namespace="default",port_name="syslog-tcp",port_number="5678",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.2.2",namespace="default",port_name="syslog",port_number="1234",port_protocol="UDP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.2.2",namespace="default",port_name="syslog-tcp",port_number="5678",port_protocol="TCP",ready="false"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="http",port_protocol="TCP",port_number="8080"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="app",port_protocol="TCP",port_number="8081"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="https",port_protocol="TCP",port_number="8443"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="prometheus",port_protocol="TCP",port_number="9090"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="syslog",port_protocol="UDP",port_number="1234"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="syslog-tcp",port_protocol="TCP",port_number="5678"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="127.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="10.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="172.22.23.202",ready="true"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="192.168.1.3",ready="false"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="192.168.2.2",ready="false"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="10.0.0.10",ready="false"} 1
`,
},
{
@@ -129,9 +135,9 @@ func TestEndpointStore(t *testing.T) {
kube_endpoint_created{endpoint="single-port-endpoint",namespace="default"} 1.5e+09
kube_endpoint_info{endpoint="single-port-endpoint",namespace="default"} 1
kube_endpoint_ports{endpoint="single-port-endpoint",namespace="default",port_name="",port_number="8080",port_protocol="TCP"} 1
- kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="127.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="10.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="10.0.0.10",ready="false"} 1
+ kube_endpoint_address{endpoint="single-port-endpoint",ip="10.0.0.1",namespace="default",port_number="8080",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="single-port-endpoint",ip="10.0.0.10",namespace="default",port_number="8080",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="single-port-endpoint",ip="127.0.0.1",namespace="default",port_number="8080",port_protocol="TCP",ready="true"} 1
`,
},
}
@@ -156,7 +162,7 @@ func TestEndpointStoreWithLabels(t *testing.T) {
# TYPE kube_endpoint_info gauge
# HELP kube_endpoint_labels [STABLE] Kubernetes labels converted to Prometheus labels.
# TYPE kube_endpoint_labels gauge
- # HELP kube_endpoint_ports [STABLE] Information about the Endpoint ports.
+ # HELP kube_endpoint_ports [STABLE] (Deprecated since v2.14.0) Information about the Endpoint ports.
# TYPE kube_endpoint_ports gauge
# HELP kube_endpoint_address [STABLE] Information about Endpoint available and non available addresses.
# TYPE kube_endpoint_address gauge
@@ -216,12 +222,18 @@ func TestEndpointStoreWithLabels(t *testing.T) {
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="prometheus",port_protocol="TCP",port_number="9090"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="syslog",port_protocol="UDP",port_number="1234"} 1
kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="syslog-tcp",port_protocol="TCP",port_number="5678"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="127.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="10.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="172.22.23.202",ready="true"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="192.168.1.3",ready="false"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="192.168.2.2",ready="false"} 1
- kube_endpoint_address{endpoint="test-endpoint",namespace="default",ip="10.0.0.10",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.1",namespace="default",port_name="app",port_number="8081",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.1",namespace="default",port_name="http",port_number="8080",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.10",namespace="default",port_name="app",port_number="8081",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="10.0.0.10",namespace="default",port_name="http",port_number="8080",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="127.0.0.1",namespace="default",port_name="app",port_number="8081",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="127.0.0.1",namespace="default",port_name="http",port_number="8080",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="172.22.23.202",namespace="default",port_name="https",port_number="8443",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="172.22.23.202",namespace="default",port_name="prometheus",port_number="9090",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.1.3",namespace="default",port_name="syslog",port_number="1234",port_protocol="UDP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.1.3",namespace="default",port_name="syslog-tcp",port_number="5678",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.2.2",namespace="default",port_name="syslog",port_number="1234",port_protocol="UDP",ready="false"} 1
+ kube_endpoint_address{endpoint="test-endpoint",ip="192.168.2.2",namespace="default",port_name="syslog-tcp",port_number="5678",port_protocol="TCP",ready="false"} 1
`,
},
{
@@ -257,9 +269,9 @@ func TestEndpointStoreWithLabels(t *testing.T) {
kube_endpoint_info{endpoint="single-port-endpoint",namespace="default"} 1
kube_endpoint_labels{endpoint="single-port-endpoint",label_app="single-foobar",namespace="default"} 1
kube_endpoint_ports{endpoint="single-port-endpoint",namespace="default",port_name="",port_number="8080",port_protocol="TCP"} 1
- kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="127.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="10.0.0.1",ready="true"} 1
- kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="10.0.0.10",ready="false"} 1
+ kube_endpoint_address{endpoint="single-port-endpoint",ip="10.0.0.1",namespace="default",port_number="8080",port_protocol="TCP",ready="true"} 1
+ kube_endpoint_address{endpoint="single-port-endpoint",ip="10.0.0.10",namespace="default",port_number="8080",port_protocol="TCP",ready="false"} 1
+ kube_endpoint_address{endpoint="single-port-endpoint",ip="127.0.0.1",namespace="default",port_number="8080",port_protocol="TCP",ready="true"} 1
`,
},
}