-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
draft: add `inject-per-series-metadata' #2632
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,12 @@ var ( | |
podStatusReasons = []string{"Evicted", "NodeAffinity", "NodeLost", "Shutdown", "UnexpectedAdmissionError"} | ||
) | ||
|
||
func podMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { | ||
func podMetricFamilies(injectPerSeriesMetadata bool, allowAnnotationsList []string, allowLabelsList []string) []generator.FamilyGenerator { | ||
mc := &MetricConfig{ | ||
InjectPerSeriesMetadata: injectPerSeriesMetadata, | ||
AllowAnnotations: allowAnnotationsList, | ||
AllowLabels: allowLabelsList, | ||
} | ||
return []generator.FamilyGenerator{ | ||
createPodCompletionTimeFamilyGenerator(), | ||
createPodContainerInfoFamilyGenerator(), | ||
|
@@ -82,7 +87,7 @@ func podMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat | |
createPodSpecVolumesPersistentVolumeClaimsInfoFamilyGenerator(), | ||
createPodSpecVolumesPersistentVolumeClaimsReadonlyFamilyGenerator(), | ||
createPodStartTimeFamilyGenerator(), | ||
createPodStatusPhaseFamilyGenerator(), | ||
createPodStatusPhaseFamilyGenerator(mc), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The full implementation would add this param to every metric family generator. This is also the reason I'm bundling up the configuration in a struct and passing it as a single unit. |
||
createPodStatusQosClassFamilyGenerator(), | ||
createPodStatusReadyFamilyGenerator(), | ||
createPodStatusReadyTimeFamilyGenerator(), | ||
|
@@ -1333,7 +1338,7 @@ func createPodStartTimeFamilyGenerator() generator.FamilyGenerator { | |
) | ||
} | ||
|
||
func createPodStatusPhaseFamilyGenerator() generator.FamilyGenerator { | ||
func createPodStatusPhaseFamilyGenerator(mc *MetricConfig) generator.FamilyGenerator { | ||
return *generator.NewFamilyGeneratorWithStability( | ||
"kube_pod_status_phase", | ||
"The pods current phase.", | ||
|
@@ -1361,13 +1366,12 @@ func createPodStatusPhaseFamilyGenerator() generator.FamilyGenerator { | |
|
||
ms := make([]*metric.Metric, len(phases)) | ||
|
||
for i, p := range phases { | ||
ms[i] = &metric.Metric{ | ||
|
||
for i, ph := range phases { | ||
ms[i] = injectLabelsAndAnnos(&metric.Metric{ | ||
LabelKeys: []string{"phase"}, | ||
LabelValues: []string{p.n}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We were shadowing the outer |
||
Value: boolFloat64(p.v), | ||
} | ||
LabelValues: []string{ph.n}, | ||
Value: boolFloat64(ph.v), | ||
}, mc, &p.ObjectMeta) | ||
} | ||
|
||
return &metric.Family{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ import ( | |
"k8s.io/apimachinery/pkg/api/resource" | ||
|
||
v1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/util/validation" | ||
|
||
"k8s.io/kube-state-metrics/v2/pkg/metric" | ||
|
@@ -38,6 +39,12 @@ var ( | |
conditionStatuses = []v1.ConditionStatus{v1.ConditionTrue, v1.ConditionFalse, v1.ConditionUnknown} | ||
) | ||
|
||
type MetricConfig struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be made private since it's built / used internally to this module. |
||
InjectPerSeriesMetadata bool | ||
AllowAnnotations []string | ||
AllowLabels []string | ||
} | ||
|
||
func resourceVersionMetric(rv string) []*metric.Metric { | ||
v, err := strconv.ParseFloat(rv, 64) | ||
if err != nil { | ||
|
@@ -175,6 +182,17 @@ func isPrefixedNativeResource(name v1.ResourceName) bool { | |
return strings.Contains(string(name), v1.ResourceDefaultNamespacePrefix) | ||
} | ||
|
||
// convenience wrapper to inject allow-listed labels and annotations to a metric if per-series injection is enabled. | ||
func injectLabelsAndAnnos(m *metric.Metric, metricConfig *MetricConfig, obj *metav1.ObjectMeta) *metric.Metric { | ||
if !metricConfig.InjectPerSeriesMetadata { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think with the pass-by-reference + early guard clause, this should be "0-cost" for those leaving the |
||
return m | ||
} | ||
labelKeys, labelValues := createPrometheusLabelKeysValues("label", obj.Labels, metricConfig.AllowLabels) | ||
annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", obj.Annotations, metricConfig.AllowAnnotations) | ||
m.LabelKeys, m.LabelValues = mergeKeyValues(m.LabelKeys, m.LabelValues, annotationKeys, annotationValues, labelKeys, labelValues) | ||
return m | ||
} | ||
|
||
// createPrometheusLabelKeysValues takes in passed kubernetes annotations/labels | ||
// and associated allowed list in kubernetes label format. | ||
// It returns only those allowed annotations/labels that exist in the list and converts them to Prometheus labels. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing this so instead of adding 3 arguments to each generator, I add one. I suppose it makes it less "pure" as the behavior of the function is dictated by a complex configuration object.