Skip to content

Commit

Permalink
Make CRS metrics type dynamic
Browse files Browse the repository at this point in the history
All CRS metrics are hardcoded to "gauge" type, this patch addresses
that.
  • Loading branch information
rexagod committed Dec 11, 2022
1 parent f01ce58 commit db78bd4
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
60 changes: 60 additions & 0 deletions pkg/customresourcestate/custom_resource_metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package customresourcestate

import (
"testing"
)

func TestNewCustomResourceMetrics(t *testing.T) {
tests := []struct {
r Resource
wantErr bool
name string
}{
{
// https://github.com/kubernetes/kube-state-metrics/issues/1886
name: "dynamic metric type (not just hardcoded to gauge)",
r: Resource{
GroupVersionKind: GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
},
Labels: Labels{
LabelsFromPath: map[string][]string{
"name": {"metadata", "name"},
},
},
Metrics: []Generator{
{
Name: "test_metrics",
Help: "metrics for testing",
Each: Metric{
Type: MetricTypeInfo,
Info: &MetricInfo{
MetricMeta: MetricMeta{
Path: []string{
"metadata",
"annotations",
},
},
LabelFromKey: "test",
},
},
},
},
},
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v, err := NewCustomResourceMetrics(tt.r)
expectedError := v.(*customResourceMetrics).Families[0].Each.Type() != "info"
if (err != nil) != tt.wantErr || expectedError {
t.Errorf("NewCustomResourceMetrics() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
11 changes: 9 additions & 2 deletions pkg/customresourcestate/registry_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ type compiledEach compiledMetric
type compiledCommon struct {
labelFromPath map[string]valuePath
path valuePath
t metric.Type
}

func (c compiledCommon) Path() valuePath {
Expand All @@ -126,6 +127,9 @@ func (c compiledCommon) Path() valuePath {
func (c compiledCommon) LabelFromPath() map[string]valuePath {
return c.labelFromPath
}
func (c compiledCommon) Type() metric.Type {
return c.t
}

type eachValue struct {
Labels map[string]string
Expand All @@ -136,6 +140,7 @@ type compiledMetric interface {
Values(v interface{}) (result []eachValue, err []error)
Path() valuePath
LabelFromPath() map[string]valuePath
Type() metric.Type
}

// newCompiledMetric returns a compiledMetric depending given the metric type.
Expand All @@ -146,6 +151,7 @@ func newCompiledMetric(m Metric) (compiledMetric, error) {
return nil, errors.New("expected each.gauge to not be nil")
}
cc, err := compileCommon(m.Gauge.MetricMeta)
cc.t = metric.Gauge
if err != nil {
return nil, fmt.Errorf("each.gauge: %w", err)
}
Expand All @@ -164,6 +170,7 @@ func newCompiledMetric(m Metric) (compiledMetric, error) {
return nil, errors.New("expected each.info to not be nil")
}
cc, err := compileCommon(m.Info.MetricMeta)
cc.t = metric.Info
if err != nil {
return nil, fmt.Errorf("each.info: %w", err)
}
Expand All @@ -176,6 +183,7 @@ func newCompiledMetric(m Metric) (compiledMetric, error) {
return nil, errors.New("expected each.stateSet to not be nil")
}
cc, err := compileCommon(m.StateSet.MetricMeta)
cc.t = metric.StateSet
if err != nil {
return nil, fmt.Errorf("each.stateSet: %w", err)
}
Expand Down Expand Up @@ -569,8 +577,7 @@ func famGen(f compiledFamily) generator.FamilyGenerator {
errLog := klog.V(f.ErrorLogV)
return generator.FamilyGenerator{
Name: f.Name,
// TODO(@rexagod): This should be dynamic.
Type: metric.Gauge,
Type: f.Each.Type(),
Help: f.Help,
GenerateFunc: func(obj interface{}) *metric.Family {
return generate(obj.(*unstructured.Unstructured), f, errLog)
Expand Down
9 changes: 8 additions & 1 deletion pkg/metric/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@ var (
)

// Type represents the type of a metric e.g. a counter. See
// https://prometheus.io/docs/concepts/metric_types/.
// https://prometheus.io/docs/concepts/metric_types/ and,
// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#metric-types.
type Type string

// Gauge defines a Prometheus gauge.
var Gauge Type = "gauge"

// Info defines an OpenMetrics info.
var Info Type = "info"

// StateSet defines an OpenMetrics stateset.
var StateSet Type = "stateset"

// Counter defines a Prometheus counter.
var Counter Type = "counter"

Expand Down

0 comments on commit db78bd4

Please sign in to comment.