/
metrics.go
106 lines (83 loc) · 2.44 KB
/
metrics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package docs
import (
"bytes"
"log"
"sort"
"strings"
"text/template"
"github.com/machadovilaca/operator-observability/pkg/operatormetrics"
"github.com/machadovilaca/operator-observability/pkg/operatorrules"
)
const defaultMetricsTemplate = `# Operator Metrics
{{- range . }}
### {{.Name}}
{{.Help}}.
Type: {{.Type}}.
{{- end }}
## Developing new metrics
All metrics documented here are auto-generated and reflect exactly what is being
exposed. After developing new metrics or changing old ones please regenerate
this document.
`
type metricDocs struct {
Name string
Help string
Type string
ExtraFields map[string]string
}
type docOptions interface {
GetOpts() operatormetrics.MetricOpts
GetType() operatormetrics.MetricType
}
// BuildMetricsDocsWithCustomTemplate returns a string with the documentation
// for the given metrics, using the given template.
func BuildMetricsDocsWithCustomTemplate(
metrics []operatormetrics.Metric,
recordingRules []operatorrules.RecordingRule,
tplString string,
) string {
tpl, err := template.New("metrics").Parse(tplString)
if err != nil {
log.Fatalln(err)
}
var allDocs []metricDocs
if metrics != nil {
allDocs = append(allDocs, buildMetricsDocs(metrics)...)
}
if recordingRules != nil {
allDocs = append(allDocs, buildMetricsDocs(recordingRules)...)
}
sortMetricsDocs(allDocs)
buf := bytes.NewBufferString("")
err = tpl.Execute(buf, allDocs)
if err != nil {
log.Fatalln(err)
}
return buf.String()
}
// BuildMetricsDocs returns a string with the documentation for the given
// metrics.
func BuildMetricsDocs(metrics []operatormetrics.Metric, recordingRules []operatorrules.RecordingRule) string {
return BuildMetricsDocsWithCustomTemplate(metrics, recordingRules, defaultMetricsTemplate)
}
func buildMetricsDocs[T docOptions](items []T) []metricDocs {
metricsDocs := make([]metricDocs, len(items))
for i, metric := range items {
metricOpts := metric.GetOpts()
metricsDocs[i] = metricDocs{
Name: metricOpts.Name,
Help: metricOpts.Help,
Type: getAndConvertMetricType(metric.GetType()),
ExtraFields: metricOpts.ExtraFields,
}
}
return metricsDocs
}
func sortMetricsDocs(metricsDocs []metricDocs) {
sort.Slice(metricsDocs, func(i, j int) bool {
return metricsDocs[i].Name < metricsDocs[j].Name
})
}
func getAndConvertMetricType(metricType operatormetrics.MetricType) string {
return strings.ReplaceAll(string(metricType), "Vec", "")
}