From a8648fd1851ff80a52a0c2fa1b2f03623ec46f67 Mon Sep 17 00:00:00 2001 From: qiang_liu Date: Mon, 23 Sep 2024 20:17:18 +0800 Subject: [PATCH 1/3] #2501 Count volumes attached to a node --- internal/store/node.go | 40 +++++++++++++++++++++++++++++++++++++ internal/store/node_test.go | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/internal/store/node.go b/internal/store/node.go index d059e20df..01300ca18 100644 --- a/internal/store/node.go +++ b/internal/store/node.go @@ -56,6 +56,8 @@ func nodeMetricFamilies(allowAnnotationsList, allowLabelsList []string) []genera createNodeStatusCapacityFamilyGenerator(), createNodeStatusConditionFamilyGenerator(), createNodeStateAddressFamilyGenerator(), + createNodeVolumeCountGenerator(), + createNodeVolumeInUseGenerator(), } } @@ -506,6 +508,44 @@ func createNodeStatusConditionFamilyGenerator() generator.FamilyGenerator { ) } +func createNodeVolumeCountGenerator() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_node_volumes_attached_count", + "Number of volumes attached to the node", + metric.Gauge, + basemetrics.STABLE, + "", + wrapNodeFunc(func(n *v1.Node) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(len(n.Status.VolumesAttached)), + }, + }, + } + }), + ) +} + +func createNodeVolumeInUseGenerator() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_node_volumes_in_use_count", + "Number of volumes in use on the node", + metric.Gauge, + basemetrics.STABLE, + "", + wrapNodeFunc(func(n *v1.Node) *metric.Family { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + Value: float64(len(n.Status.VolumesInUse)), + }, + }, + } + }), + ) +} + func wrapNodeFunc(f func(*v1.Node) *metric.Family) func(interface{}) *metric.Family { return func(obj interface{}) *metric.Family { node := obj.(*v1.Node) diff --git a/internal/store/node_test.go b/internal/store/node_test.go index 6457aef20..462fc67b1 100644 --- a/internal/store/node_test.go +++ b/internal/store/node_test.go @@ -298,6 +298,43 @@ func TestNodeStore(t *testing.T) { `, MetricNames: []string{"kube_node_status_addresses"}, }, + { + Obj: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "127.0.0.1", + }, + Status: v1.NodeStatus{ + VolumesAttached: []v1.AttachedVolume{ + {Name: "volume1", DevicePath: "/dev/sda1"}, + {Name: "volume2", DevicePath: "/dev/sda2"}, + }, + }, + }, + Want: ` + # HELP kube_node_volumes_attached_count [STABLE] Number of volumes attached to the node + # TYPE kube_node_volumes_attached_count gauge + kube_node_volumes_attached_count{node="127.0.0.1"} 2 + `, + MetricNames: []string{"kube_node_volumes_attached_count"}, + }, + { + Obj: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "127.0.0.1", + }, + Status: v1.NodeStatus{ + VolumesInUse: []v1.UniqueVolumeName{ + "volume1", + }, + }, + }, + Want: ` + # HELP kube_node_volumes_in_use_count [STABLE] Number of volumes in use on the node + # TYPE kube_node_volumes_in_use_count gauge + kube_node_volumes_in_use_count{node="127.0.0.1"} 1 + `, + MetricNames: []string{"kube_node_volumes_in_use_count"}, + }, } for i, c := range cases { c.Func = generator.ComposeMetricGenFuncs(nodeMetricFamilies(nil, nil)) From 08c753e50ba27038517498f9748f64becad6553e Mon Sep 17 00:00:00 2001 From: qiang_liu Date: Mon, 23 Sep 2024 20:28:00 +0800 Subject: [PATCH 2/3] #2501 add documented --- docs/metrics/cluster/node-metrics.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/metrics/cluster/node-metrics.md b/docs/metrics/cluster/node-metrics.md index ac1085bf8..e37d3bbd0 100644 --- a/docs/metrics/cluster/node-metrics.md +++ b/docs/metrics/cluster/node-metrics.md @@ -14,3 +14,5 @@ | kube_node_status_condition | Gauge | The condition of a cluster node | | `node`=<node-address>
`condition`=<node-condition>
`status`=<true\|false\|unknown> | STABLE | | kube_node_created | Gauge | Unix creation timestamp | seconds | `node`=<node-address> | STABLE | | kube_node_deletion_timestamp | Gauge | Unix deletion timestamp | seconds | `node`=<node-address> | EXPERIMENTAL | +| kube_node_volumes_in_use_count | Gauge | Number of volumes in use on the node | | `node`=<node-address> | STABLE | +| kube_node_volumes_attached_count | Gauge | Number of volumes attached to the node | | `node`=<node-address> | STABLE | From e4b6971688e413d226622ed8c09564e2ce764042 Mon Sep 17 00:00:00 2001 From: qiang_liu Date: Wed, 15 Oct 2025 15:43:18 +0800 Subject: [PATCH 3/3] fix: rename volume metrics to comply with Prometheus naming conventions --- docs/metrics/cluster/node-metrics.md | 4 ++-- internal/store/node.go | 4 ++-- internal/store/node_test.go | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/metrics/cluster/node-metrics.md b/docs/metrics/cluster/node-metrics.md index b70d5f1ae..cd2be1173 100644 --- a/docs/metrics/cluster/node-metrics.md +++ b/docs/metrics/cluster/node-metrics.md @@ -14,5 +14,5 @@ | kube_node_status_condition | Gauge | The condition of a cluster node | | `node`=<node-address>
`condition`=<node-condition>
`status`=<true\|false\|unknown> | STABLE | | kube_node_created | Gauge | Unix creation timestamp | seconds | `node`=<node-address> | STABLE | | kube_node_deletion_timestamp | Gauge | Unix deletion timestamp | seconds | `node`=<node-address> | EXPERIMENTAL | -| kube_node_volumes_in_use_count | Gauge | Number of volumes in use on the node | | `node`=<node-address> | STABLE | -| kube_node_volumes_attached_count | Gauge | Number of volumes attached to the node | | `node`=<node-address> | STABLE | +| kube_node_volumes_in_use | Gauge | Number of volumes in use on the node | | `node`=<node-address> | STABLE | +| kube_node_volumes_attached | Gauge | Number of volumes attached to the node | | `node`=<node-address> | STABLE | diff --git a/internal/store/node.go b/internal/store/node.go index 501984220..4d2a81cf4 100644 --- a/internal/store/node.go +++ b/internal/store/node.go @@ -510,7 +510,7 @@ func createNodeStatusConditionFamilyGenerator() generator.FamilyGenerator { func createNodeVolumeCountGenerator() generator.FamilyGenerator { return *generator.NewFamilyGeneratorWithStability( - "kube_node_volumes_attached_count", + "kube_node_volumes_attached", "Number of volumes attached to the node", metric.Gauge, basemetrics.STABLE, @@ -529,7 +529,7 @@ func createNodeVolumeCountGenerator() generator.FamilyGenerator { func createNodeVolumeInUseGenerator() generator.FamilyGenerator { return *generator.NewFamilyGeneratorWithStability( - "kube_node_volumes_in_use_count", + "kube_node_volumes_in_use", "Number of volumes in use on the node", metric.Gauge, basemetrics.STABLE, diff --git a/internal/store/node_test.go b/internal/store/node_test.go index 608b3704a..60c688a5a 100644 --- a/internal/store/node_test.go +++ b/internal/store/node_test.go @@ -399,11 +399,11 @@ func TestNodeStore(t *testing.T) { }, }, Want: ` - # HELP kube_node_volumes_attached_count [STABLE] Number of volumes attached to the node - # TYPE kube_node_volumes_attached_count gauge - kube_node_volumes_attached_count{node="127.0.0.1"} 2 + # HELP kube_node_volumes_attached [STABLE] Number of volumes attached to the node + # TYPE kube_node_volumes_attached gauge + kube_node_volumes_attached{node="127.0.0.1"} 2 `, - MetricNames: []string{"kube_node_volumes_attached_count"}, + MetricNames: []string{"kube_node_volumes_attached"}, }, { Obj: &v1.Node{ @@ -417,11 +417,11 @@ func TestNodeStore(t *testing.T) { }, }, Want: ` - # HELP kube_node_volumes_in_use_count [STABLE] Number of volumes in use on the node - # TYPE kube_node_volumes_in_use_count gauge - kube_node_volumes_in_use_count{node="127.0.0.1"} 1 + # HELP kube_node_volumes_in_use [STABLE] Number of volumes in use on the node + # TYPE kube_node_volumes_in_use gauge + kube_node_volumes_in_use{node="127.0.0.1"} 1 `, - MetricNames: []string{"kube_node_volumes_in_use_count"}, + MetricNames: []string{"kube_node_volumes_in_use"}, }, } for i, c := range cases {