Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/metrics/workload/deployment-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
| kube_deployment_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `deployment`=&lt;deployment-name&gt; <br> `namespace`=&lt;deployment-namespace&gt; <br> `label_DEPLOYMENT_LABEL`=&lt;DEPLOYMENT_LABEL&gt; | STABLE |
| kube_deployment_created | Gauge | Unix creation timestamp | `deployment`=&lt;deployment-name&gt; <br> `namespace`=&lt;deployment-namespace&gt; | STABLE |
| kube_deployment_deletion_timestamp | Gauge | Unix deletion timestamp | `deployment`=&lt;deployment-name&gt; <br> `namespace`=&lt;deployment-namespace&gt; | EXPIREMENTAL |
| kube_deployment_owner | Gauge | Information about the Deployment's owner. | `deployment`=&lt;deployment-name&gt; <br> `namespace`=&lt;deployment-namespace&gt; <br> `owner_kind`=&lt;owner-kind&gt; <br> `owner_name`=&lt;owner-name&gt; <br> `owner_is_controller`=&lt;true\|false&gt; | ALPHA |
46 changes: 46 additions & 0 deletions internal/store/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package store

import (
"context"
"strconv"

basemetrics "k8s.io/component-base/metrics"

Expand Down Expand Up @@ -60,6 +61,51 @@ var (

func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator {
return []generator.FamilyGenerator{
*generator.NewFamilyGeneratorWithStability(
"kube_deployment_owner",
"Information about the Deployment's owner.",
metric.Gauge,
basemetrics.ALPHA,
"",
wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family {
labelKeys := []string{"owner_kind", "owner_name", "owner_is_controller"}
Copy link
Contributor

@CatherineF-dev CatherineF-dev Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are other possible values other than controller?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Application or custom resources

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use an enum instead of boolean here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we should do this?, I found that owner_is_controller is used in multiple workload like pods, jobs and replicaset, all of them is in boolean form


owners := d.GetOwnerReferences()
if len(owners) == 0 {
return &metric.Family{
Metrics: []*metric.Metric{
{
LabelKeys: labelKeys,
LabelValues: []string{"", "", ""},
Value: 1,
},
},
}
}

ms := make([]*metric.Metric, len(owners))

for i, owner := range owners {
if owner.Controller != nil {
ms[i] = &metric.Metric{
LabelKeys: labelKeys,
LabelValues: []string{owner.Kind, owner.Name, strconv.FormatBool(*owner.Controller)},
Value: 1,
}
} else {
ms[i] = &metric.Metric{
LabelKeys: labelKeys,
LabelValues: []string{owner.Kind, owner.Name, "false"},
Value: 1,
}
}
}

return &metric.Family{
Metrics: ms,
}
}),
),
*generator.NewFamilyGeneratorWithStability(
"kube_deployment_created",
"Unix creation timestamp",
Expand Down
58 changes: 58 additions & 0 deletions internal/store/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func TestDeploymentStore(t *testing.T) {
// Fixed metadata on type and help text. We prepend this to every expected
// output so we only have to modify a single place when doing adjustments.
const metadata = `
# HELP kube_deployment_owner Information about the Deployment's owner.
# TYPE kube_deployment_owner gauge
# HELP kube_deployment_annotations Kubernetes annotations converted to Prometheus labels.
# TYPE kube_deployment_annotations gauge
# HELP kube_deployment_created [STABLE] Unix creation timestamp
Expand Down Expand Up @@ -119,6 +121,7 @@ func TestDeploymentStore(t *testing.T) {
Want: metadata + `
kube_deployment_annotations{annotation_company_io_team="my-brilliant-team",deployment="depl1",namespace="ns1"} 1
kube_deployment_created{deployment="depl1",namespace="ns1"} 1.5e+09
kube_deployment_owner{deployment="depl1",namespace="ns1",owner_kind="",owner_name="",owner_is_controller=""} 1
kube_deployment_metadata_generation{deployment="depl1",namespace="ns1"} 21
kube_deployment_spec_paused{deployment="depl1",namespace="ns1"} 0
kube_deployment_spec_replicas{deployment="depl1",namespace="ns1"} 200
Expand Down Expand Up @@ -174,6 +177,7 @@ func TestDeploymentStore(t *testing.T) {
},
Want: metadata + `
kube_deployment_metadata_generation{deployment="depl2",namespace="ns2"} 14
kube_deployment_owner{deployment="depl2",namespace="ns2",owner_kind="",owner_name="",owner_is_controller=""} 1
kube_deployment_spec_paused{deployment="depl2",namespace="ns2"} 1
kube_deployment_spec_replicas{deployment="depl2",namespace="ns2"} 5
kube_deployment_spec_strategy_rollingupdate_max_surge{deployment="depl2",namespace="ns2"} 1
Expand Down Expand Up @@ -213,6 +217,7 @@ func TestDeploymentStore(t *testing.T) {
},
Want: metadata + `
kube_deployment_metadata_generation{deployment="depl3",namespace="ns3"} 0
kube_deployment_owner{deployment="depl3",namespace="ns3",owner_kind="",owner_name="",owner_is_controller=""} 1
kube_deployment_spec_paused{deployment="depl3",namespace="ns3"} 0
kube_deployment_spec_replicas{deployment="depl3",namespace="ns3"} 1
kube_deployment_status_condition{condition="Available",deployment="depl3",namespace="ns3",reason="unknown",status="true"} 0
Expand Down Expand Up @@ -252,6 +257,59 @@ func TestDeploymentStore(t *testing.T) {
kube_deployment_deletion_timestamp{deployment="deployment-terminating",namespace="ns4"} 1.8e+09`,
MetricNames: []string{"kube_deployment_deletion_timestamp"},
},
{
Obj: &v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "deployment-with-owner",
Namespace: "ns5",
OwnerReferences: []metav1.OwnerReference{
{
Kind: "Application",
Name: "my-app",
Controller: &[]bool{true}[0],
},
},
},
Spec: v1.DeploymentSpec{
Replicas: &depl1Replicas,
},
},
Want: metadata + `
kube_deployment_owner{deployment="deployment-with-owner",namespace="ns5",owner_kind="Application",owner_name="my-app",owner_is_controller="true"} 1
kube_deployment_metadata_generation{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_spec_paused{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_spec_replicas{deployment="deployment-with-owner",namespace="ns5"} 200
kube_deployment_status_observed_generation{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_status_replicas{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_status_replicas_available{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_status_replicas_ready{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_status_replicas_unavailable{deployment="deployment-with-owner",namespace="ns5"} 0
kube_deployment_status_replicas_updated{deployment="deployment-with-owner",namespace="ns5"} 0
`,
},
{
Obj: &v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "deployment-without-owner",
Namespace: "ns5",
},
Spec: v1.DeploymentSpec{
Replicas: &depl1Replicas,
},
},
Want: metadata + `
kube_deployment_owner{deployment="deployment-without-owner",namespace="ns5",owner_kind="",owner_name="",owner_is_controller=""} 1
kube_deployment_metadata_generation{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_spec_paused{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_spec_replicas{deployment="deployment-without-owner",namespace="ns5"} 200
kube_deployment_status_observed_generation{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_status_replicas{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_status_replicas_available{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_status_replicas_ready{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_status_replicas_unavailable{deployment="deployment-without-owner",namespace="ns5"} 0
kube_deployment_status_replicas_updated{deployment="deployment-without-owner",namespace="ns5"} 0
`,
},
}
for i, c := range cases {
c.Func = generator.ComposeMetricGenFuncs(deploymentMetricFamilies(c.AllowAnnotationsList, nil))
Expand Down