@@ -21,29 +21,78 @@ import (
21
21
"strings"
22
22
23
23
"github.com/gobuffalo/flect"
24
-
25
24
"k8s.io/klog/v2"
25
+
26
+ "k8s.io/kube-state-metrics/v2/pkg/customresource"
26
27
)
27
28
29
+ // Metrics is the top level configuration object.
30
+ type Metrics struct {
31
+ Spec MetricsSpec `yaml:"spec" json:"spec"`
32
+ }
33
+
34
+ // MetricsSpec is the configuration describing the custom resource state metrics to generate.
35
+ type MetricsSpec struct {
36
+ // Resources is the list of custom resources to be monitored. A resource with the same GroupVersionKind may appear
37
+ // multiple times (e.g., to customize the namespace or subsystem,) but will incur additional overhead.
38
+ Resources []Resource `yaml:"resources" json:"resources"`
39
+ }
40
+
41
+ // Resource configures a custom resource for metric generation.
42
+ type Resource struct {
43
+ // MetricNamePrefix defines a prefix for all metrics of the resource.
44
+ // It defaults to the GroupVersionKind string, with invalid characters replaced by _.
45
+ // If set to "_", no prefix will be added.
46
+ // Example: If GroupVersionKind is "my-team.io/v1/MyResource", MetricNamePrefix will be "my_team_io_v1_MyResource".
47
+ MetricNamePrefix string `yaml:"metricNamePrefix" json:"metricNamePrefix"`
48
+
49
+ // GroupVersionKind of the custom resource to be monitored.
50
+ GroupVersionKind GroupVersionKind `yaml:"groupVersionKind" json:"groupVersionKind"`
51
+
52
+ // Labels are added to all metrics. If the same key is used in a metric, the value from the metric will overwrite the value here.
53
+ Labels `yaml:",inline" json:",inline"`
54
+
55
+ // Metrics are the custom resource fields to be collected.
56
+ Metrics []Generator `yaml:"metrics" json:"metrics"`
57
+ // ErrorLogV defines the verbosity threshold for errors logged for this resource.
58
+ ErrorLogV klog.Level `yaml:"errorLogV" json:"errorLogV"`
59
+
60
+ // ResourcePlural sets the plural name of the resource. Defaults to the plural version of the Kind according to flect.Pluralize.
61
+ ResourcePlural string `yaml:"resourcePlural" json:"resourcePlural"`
62
+ }
63
+
64
+ // GetMetricNamePrefix returns the prefix to use for metrics.
65
+ func (r Resource ) GetMetricNamePrefix () string {
66
+ switch r .MetricNamePrefix {
67
+ case "" :
68
+ return strings .NewReplacer (
69
+ "/" , "_" ,
70
+ "." , "_" ,
71
+ "-" , "_" ,
72
+ ).Replace (fmt .Sprintf ("%s_%s_%s" , r .GroupVersionKind .Group , r .GroupVersionKind .Version , r .GroupVersionKind .Kind ))
73
+ case "_" :
74
+ return ""
75
+ default :
76
+ return r .MetricNamePrefix
77
+ }
78
+ }
79
+
80
+ // GetResourceName returns the lowercase, plural form of the resource Kind. This is ResourcePlural if it is set.
81
+ func (r Resource ) GetResourceName () string {
82
+ if r .ResourcePlural != "" {
83
+ return r .ResourcePlural
84
+ }
85
+ // kubebuilder default:
86
+ return strings .ToLower (flect .Pluralize (r .GroupVersionKind .Kind ))
87
+ }
88
+
28
89
// GroupVersionKind is the Kubernetes group, version, and kind of a resource.
29
90
type GroupVersionKind struct {
30
91
Group string `yaml:"group" json:"group"`
31
92
Version string `yaml:"version" json:"version"`
32
93
Kind string `yaml:"kind" json:"kind"`
33
94
}
34
95
35
- // MetricPer targets a Path that may be a single value, array, or object. Arrays and objects will generate a metric per element.
36
- type MetricPer struct {
37
- // Path is the path to the value to generate metric(s) for.
38
- Path []string `yaml:"path" json:"path"`
39
- // ValueFrom is the path to a numeric field under Path that will be the metric value.
40
- ValueFrom []string `yaml:"valueFrom" json:"valueFrom"`
41
- // LabelFromKey adds a label with the given name if Path is an object. The label value will be the object key.
42
- LabelFromKey string `yaml:"labelFromKey" json:"labelFromKey"`
43
- // LabelsFromPath adds additional labels where the value of the label is taken from a field under Path.
44
- LabelsFromPath map [string ][]string `yaml:"labelsFromPath" json:"labelsFromPath"`
45
- }
46
-
47
96
// Labels is common configuration of labels to add to metrics.
48
97
type Labels struct {
49
98
// CommonLabels are added to all metrics.
@@ -82,82 +131,49 @@ type Generator struct {
82
131
// Help text for the metric.
83
132
Help string `yaml:"help" json:"help"`
84
133
// Each targets a value or values from the resource.
85
- Each MetricPer `yaml:"each" json:"each"`
134
+ Each Metric `yaml:"each" json:"each"`
86
135
87
136
// Labels are added to all metrics. Labels from Each will overwrite these if using the same key.
88
- Labels `yaml:",inline"` // json will inline because it is already tagged
137
+ Labels `yaml:",inline" json:",inline" ` // json will inline because it is already tagged
89
138
// ErrorLogV defines the verbosity threshold for errors logged for this metric. Must be non-zero to override the resource setting.
90
139
ErrorLogV klog.Level `yaml:"errorLogV" json:"errorLogV"`
91
140
}
92
141
93
- // Resource configures a custom resource for metric generation.
94
- type Resource struct {
95
- // Namespace is an optional prefix for all metrics. Defaults to "kube" if not set. If set to "_", no namespace will be added.
96
- // The combination of Namespace and Subsystem will be prefixed to all metrics generated for this resource.
97
- // e.g., if Namespace is "kube" and Subsystem is "myteam_io_v1_MyResource", all metrics will be prefixed with "kube_myteam_io_v1_MyResource_".
98
- Namespace string `yaml:"namespace" json:"namespace"`
99
- // Subsystem defaults to the GroupVersionKind string, with invalid character replaced with _. If set to "_", no subsystem will be added.
100
- // e.g., if GroupVersionKind is "myteam.io/v1/MyResource", Subsystem will be "myteam_io_v1_MyResource".
101
- Subsystem string `yaml:"subsystem" json:"subsystem"`
102
-
103
- // GroupVersionKind of the custom resource to be monitored.
104
- GroupVersionKind GroupVersionKind `yaml:"groupVersionKind" json:"groupVersionKind"`
105
-
106
- // Labels are added to all metrics. If the same key is used in a metric, the value from the metric will overwrite the value here.
107
- Labels `yaml:",inline"`
108
-
109
- // Metrics are the custom resource fields to be collected.
110
- Metrics []Generator `yaml:"metrics" json:"metrics"`
111
- // ErrorLogV defines the verbosity threshold for errors logged for this resource.
112
- ErrorLogV klog.Level `yaml:"errorLogV" json:"errorLogV"`
113
-
114
- // ResourcePlural sets the plural name of the resource. Defaults to the plural version of the Kind according to flect.Pluralize.
115
- ResourcePlural string `yaml:"resourcePlural" json:"resourcePlural"`
142
+ // Metric defines a metric to expose.
143
+ // +union
144
+ type Metric struct {
145
+ // Type defines the type of the metric.
146
+ // +unionDiscriminator
147
+ Type MetricType `yaml:"type" json:"type"`
148
+
149
+ // Gauge defines a gauge metric.
150
+ // +optional
151
+ Gauge * MetricGauge `yaml:"gauge" json:"gauge"`
152
+ // StateSet defines a state set metric.
153
+ // +optional
154
+ StateSet * MetricStateSet `yaml:"stateSet" json:"stateSet"`
155
+ // Info defines a info metric.
156
+ // +optional
157
+ Info * MetricInfo `yaml:"info" json:"info"`
116
158
}
117
159
118
- // GetNamespace returns the namespace prefix to use for metrics.
119
- func (r Resource ) GetNamespace () string {
120
- if r .Namespace == "" {
121
- return "kube"
122
- }
123
- if r .Namespace == "_" {
124
- return ""
125
- }
126
- return r .Namespace
160
+ // ConfigDecoder is for use with FromConfig.
161
+ type ConfigDecoder interface {
162
+ Decode (v interface {}) (err error )
127
163
}
128
164
129
- // GetSubsystem returns the subsystem prefix to use for metrics (will be joined between namespace and the metric name).
130
- func (r Resource ) GetSubsystem () string {
131
- if r .Subsystem == "" {
132
- return strings .NewReplacer (
133
- "/" , "_" ,
134
- "." , "_" ,
135
- "-" , "_" ,
136
- ).Replace (fmt .Sprintf ("%s_%s_%s" , r .GroupVersionKind .Group , r .GroupVersionKind .Version , r .GroupVersionKind .Kind ))
137
- }
138
- if r .Subsystem == "_" {
139
- return ""
165
+ // FromConfig decodes a configuration source into a slice of customresource.RegistryFactory that are ready to use.
166
+ func FromConfig (decoder ConfigDecoder ) (factories []customresource.RegistryFactory , err error ) {
167
+ var crconfig Metrics
168
+ if err := decoder .Decode (& crconfig ); err != nil {
169
+ return nil , fmt .Errorf ("failed to parse Custom Resource State metrics: %w" , err )
140
170
}
141
- return r .Subsystem
142
- }
143
-
144
- // GetResourceName returns the lowercase, plural form of the resource Kind. This is ResourcePlural if it is set.
145
- func (r Resource ) GetResourceName () string {
146
- if r .ResourcePlural != "" {
147
- return r .ResourcePlural
171
+ for _ , resource := range crconfig .Spec .Resources {
172
+ factory , err := NewCustomResourceMetrics (resource )
173
+ if err != nil {
174
+ return nil , fmt .Errorf ("failed to create metrics factory for %s: %w" , resource .GroupVersionKind , err )
175
+ }
176
+ factories = append (factories , factory )
148
177
}
149
- // kubebuilder default:
150
- return strings .ToLower (flect .Pluralize (r .GroupVersionKind .Kind ))
151
- }
152
-
153
- // Metrics is the top level configuration object.
154
- type Metrics struct {
155
- Spec MetricsSpec `yaml:"spec" json:"spec"`
156
- }
157
-
158
- // MetricsSpec is the configuration describing the custom resource state metrics to generate.
159
- type MetricsSpec struct {
160
- // Resources is the list of custom resources to be monitored. A resource with the same GroupVersionKind may appear
161
- // multiple times (e.g., to customize the namespace or subsystem,) but will incur additional overhead.
162
- Resources []Resource `yaml:"resources" json:"resources"`
178
+ return factories , nil
163
179
}
0 commit comments