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 `, }, }