1
16
17 package main
18
19 import (
20 "bytes"
21 "fmt"
22 "os"
23 "sort"
24 "strings"
25 "text/template"
26 "time"
27
28 flag "github.com/spf13/pflag"
29 "gopkg.in/yaml.v2"
30
31 "k8s.io/component-base/metrics"
32 )
33
34 var (
35 GOROOT string = os.Getenv("GOROOT")
36 GOOS string = os.Getenv("GOOS")
37 KUBE_ROOT string = os.Getenv("KUBE_ROOT")
38 funcMap = template.FuncMap{
39 "ToLower": strings.ToLower,
40 }
41 )
42
43 const (
44 templ = `---
45 title: Kubernetes Metrics Reference
46 content_type: reference
47 auto_generated: true
48 description: >-
49 Details of the metric data that Kubernetes components export.
50 ---
51
52 ## Metrics (v{{.GeneratedVersion}})
53
54 <!-- (auto-generated {{.GeneratedDate.Format "2006 Jan 02"}}) -->
55 <!-- (auto-generated v{{.GeneratedVersion}}) -->
56 This page details the metrics that different Kubernetes components export. You can query the metrics endpoint for these
57 components using an HTTP scrape, and fetch the current metrics data in Prometheus format.
58
59 ### List of Stable Kubernetes Metrics
60
61 Stable metrics observe strict API contracts and no labels can be added or removed from stable metrics during their lifetime.
62
63 <div class="metrics">
64 {{- range $index, $metric := .StableMetrics -}}
65 <div class="metric" data-stability="{{$metric.StabilityLevel | ToLower}}">
66 <div class="metric_name">{{with $metric}}{{.BuildFQName}}{{- end -}}</div>
67 <div class="metric_help">{{- $metric.Help -}}</div>
68 <ul>
69 <li><label class="metric_detail">Stability Level:</label><span class="metric_stability_level">{{- $metric.StabilityLevel -}}</span></li>
70 <li data-type="{{$metric.Type | ToLower}}"><label class="metric_detail">Type:</label> <span class="metric_type">{{- $metric.Type -}}</span></li>
71 {{if $metric.Labels }}<li class="metric_labels_varying"><label class="metric_detail">Labels:</label>{{range $label := $metric.Labels}}<span class="metric_label">{{- $label -}}</span>{{- end -}}</li>{{- end -}}
72 {{if $metric.ConstLabels }}<li class="metric_labels_constant"><label class="metric_detail">Const Labels:</label>{{range $key, $value := $metric.ConstLabels}}<span class="metric_label">{{$key}}:{{$value}}</span>{{- end -}}</li>{{- end -}}
73 {{if $metric.DeprecatedVersion }}<li class="metric_deprecated_version"><label class="metric_detail">Deprecated Versions:</label><span>{{- $metric.DeprecatedVersion -}}</span></li>{{- end -}}
74 </ul>
75 </div>{{end}}
76 </div>
77
78 ### List of Beta Kubernetes Metrics
79
80 Beta metrics observe a looser API contract than its stable counterparts. No labels can be removed from beta metrics during their lifetime, however, labels can be added while the metric is in the beta stage. This offers the assurance that beta metrics will honor existing dashboards and alerts, while allowing for amendments in the future.
81
82 <div class="metrics">
83 {{- range $index, $metric := .BetaMetrics -}}
84 <div class="metric" data-stability="{{$metric.StabilityLevel | ToLower}}">
85 <div class="metric_name">{{with $metric}}{{.BuildFQName}}{{- end -}}</div>
86 <div class="metric_help">{{- $metric.Help -}}</div>
87 <ul>
88 <li><label class="metric_detail">Stability Level:</label><span class="metric_stability_level">{{- $metric.StabilityLevel -}}</span></li>
89 <li data-type="{{$metric.Type | ToLower}}"><label class="metric_detail">Type:</label> <span class="metric_type">{{- $metric.Type -}}</span></li>
90 {{if $metric.Labels }}<li class="metric_labels_varying"><label class="metric_detail">Labels:</label>{{range $label := $metric.Labels}}<span class="metric_label">{{- $label -}}</span>{{- end -}}</li>{{- end -}}
91 {{if $metric.ConstLabels }}<li class="metric_labels_constant"><label class="metric_detail">Const Labels:</label>{{range $key, $value := $metric.ConstLabels}}<span class="metric_label">{{$key}}:{{$value}}</span>{{- end -}}</li>{{- end -}}
92 {{if $metric.DeprecatedVersion }}<li class="metric_deprecated_version"><label class="metric_detail">Deprecated Versions:</label><span>{{- $metric.DeprecatedVersion -}}</span></li>{{- end -}}
93 </ul>
94 </div>{{end}}
95 </div>
96
97 ### List of Alpha Kubernetes Metrics
98
99 Alpha metrics do not have any API guarantees. These metrics must be used at your own risk, subsequent versions of Kubernetes may remove these metrics altogether, or mutate the API in such a way that breaks existing dashboards and alerts.
100
101 <div class="metrics">
102 {{- range $index, $metric := .AlphaMetrics -}}
103 <div class="metric" data-stability="{{$metric.StabilityLevel | ToLower}}">
104 <div class="metric_name">{{with $metric}}{{.BuildFQName}}{{- end -}}</div>
105 <div class="metric_help">{{- $metric.Help -}}</div>
106 <ul>
107 <li><label class="metric_detail">Stability Level:</label><span class="metric_stability_level">{{- $metric.StabilityLevel -}}</span></li>
108 <li data-type="{{$metric.Type | ToLower}}"><label class="metric_detail">Type:</label> <span class="metric_type">{{- $metric.Type -}}</span></li>
109 {{if $metric.Labels }}<li class="metric_labels_varying"><label class="metric_detail">Labels:</label>{{range $label := $metric.Labels}}<span class="metric_label">{{- $label -}}</span>{{- end -}}</li>{{- end -}}
110 {{if $metric.ConstLabels }}<li class="metric_labels_constant"><label class="metric_detail">Const Labels:</label>{{range $key, $value := $metric.ConstLabels}}<span class="metric_label">{{$key}}:{{$value}}</span>{{- end -}}</li>{{- end -}}
111 {{if $metric.DeprecatedVersion }}<li class="metric_deprecated_version"><label class="metric_detail">Deprecated Versions:</label><span>{{- $metric.DeprecatedVersion -}}</span></li>{{- end -}}
112 </ul>
113 </div>{{end}}
114 </div>
115 `
116 )
117
118 type templateData struct {
119 AlphaMetrics []metric
120 BetaMetrics []metric
121 StableMetrics []metric
122 GeneratedDate time.Time
123 GeneratedVersion string
124 }
125
126 func main() {
127 var major string
128 var minor string
129 flag.StringVar(&major, "major", "", "k8s major version")
130 flag.StringVar(&minor, "minor", "", "k8s minor version")
131 flag.Parse()
132 println(major, minor)
133 dat, err := os.ReadFile("test/instrumentation/documentation/documentation-list.yaml")
134 if err == nil {
135 var parsedMetrics []metric
136 err = yaml.Unmarshal(dat, &parsedMetrics)
137 if err != nil {
138 println("err", err)
139 }
140 sort.Sort(byFQName(parsedMetrics))
141 t := template.New("t").Funcs(funcMap)
142 t, err := t.Parse(templ)
143 if err != nil {
144 println("err", err)
145 }
146 var tpl bytes.Buffer
147 for i, m := range parsedMetrics {
148 m.Help = strings.Join(strings.Split(m.Help, "\n"), ", ")
149 _ = m.BuildFQName()
150 parsedMetrics[i] = m
151 }
152 sortedMetrics := byStabilityLevel(parsedMetrics)
153 data := templateData{
154 AlphaMetrics: sortedMetrics["ALPHA"],
155 BetaMetrics: sortedMetrics["BETA"],
156 StableMetrics: sortedMetrics["STABLE"],
157 GeneratedDate: time.Now(),
158 GeneratedVersion: fmt.Sprintf("%v.%v", major, parseMinor(minor)),
159 }
160 err = t.Execute(&tpl, data)
161 if err != nil {
162 println("err", err)
163 }
164 fmt.Print(tpl.String())
165 } else {
166 fmt.Fprintf(os.Stderr, "%s\n", err)
167 }
168
169 }
170
171 type metric struct {
172 Name string `yaml:"name" json:"name"`
173 Subsystem string `yaml:"subsystem,omitempty" json:"subsystem,omitempty"`
174 Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
175 Help string `yaml:"help,omitempty" json:"help,omitempty"`
176 Type string `yaml:"type,omitempty" json:"type,omitempty"`
177 DeprecatedVersion string `yaml:"deprecatedVersion,omitempty" json:"deprecatedVersion,omitempty"`
178 StabilityLevel string `yaml:"stabilityLevel,omitempty" json:"stabilityLevel,omitempty"`
179 Labels []string `yaml:"labels,omitempty" json:"labels,omitempty"`
180 Buckets []float64 `yaml:"buckets,omitempty" json:"buckets,omitempty"`
181 Objectives map[float64]float64 `yaml:"objectives,omitempty" json:"objectives,omitempty"`
182 AgeBuckets uint32 `yaml:"ageBuckets,omitempty" json:"ageBuckets,omitempty"`
183 BufCap uint32 `yaml:"bufCap,omitempty" json:"bufCap,omitempty"`
184 MaxAge int64 `yaml:"maxAge,omitempty" json:"maxAge,omitempty"`
185 ConstLabels map[string]string `yaml:"constLabels,omitempty" json:"constLabels,omitempty"`
186 }
187
188 func (m metric) BuildFQName() string {
189 return metrics.BuildFQName(m.Namespace, m.Subsystem, m.Name)
190 }
191
192 type byFQName []metric
193
194 func (ms byFQName) Len() int { return len(ms) }
195 func (ms byFQName) Less(i, j int) bool {
196 if ms[i].StabilityLevel < ms[j].StabilityLevel {
197 return true
198 } else if ms[i].StabilityLevel > ms[j].StabilityLevel {
199 return false
200 }
201 return ms[i].BuildFQName() < ms[j].BuildFQName()
202 }
203 func (ms byFQName) Swap(i, j int) {
204 ms[i], ms[j] = ms[j], ms[i]
205 }
206
207 func byStabilityLevel(ms []metric) map[string][]metric {
208 res := map[string][]metric{}
209 for _, m := range ms {
210 if _, ok := res[m.StabilityLevel]; !ok {
211 res[m.StabilityLevel] = []metric{}
212 }
213 res[m.StabilityLevel] = append(res[m.StabilityLevel], m)
214 }
215 return res
216 }
217
218 func parseMinor(m string) string {
219 return strings.Trim(m, `+`)
220 }
221
View as plain text