From ee639f6ffdb2bab6e88ffc049565ca4c4235da2b Mon Sep 17 00:00:00 2001 From: Aviv Litman Date: Sun, 26 Feb 2023 18:08:39 +0200 Subject: [PATCH] Follow up for Add automated documentation for metrics -Use go template in metricsdocs.go - Add condition to the log messages - Update the logs messages to use `and monitoring` only when needed. Signed-off-by: Aviv Litman --- .../memcached_with_customization.go | 147 ++++++------------ .../monitoring/metricsdocs/metricsdocs.go | 116 ++++---------- .../monitoring/metricsdocs/metricsdocs.go | 116 ++++---------- 3 files changed, 106 insertions(+), 273 deletions(-) diff --git a/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go b/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go index 5c51dc445e7..a6fcfb5e37a 100644 --- a/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go +++ b/hack/generate/samples/internal/go/memcached-with-customization/memcached_with_customization.go @@ -27,7 +27,9 @@ import ( "github.com/operator-framework/operator-sdk/hack/generate/samples/internal/pkg" ) -// Memcached defines the Memcached Sample in GO using webhooks and monitoring code +const monitoringString = " and monitoring=true" + +// Memcached defines the Memcached Sample in GO using webhooks or webhooks and monitoring code type Memcached struct { ctx *pkg.SampleContext } @@ -39,25 +41,36 @@ var prometheusAPIVersion = "v0.59.0" // GenerateSample will call all actions to create the directory and generate the sample // Note that it should NOT be called in the e2e tests. func GenerateSample(binaryPath, samplesPath string) { - log.Infof("starting to generate Go memcached sample with webhooks and metrics documentation") - ctx, err := pkg.NewSampleContext(binaryPath, filepath.Join(samplesPath, "memcached-operator"), "GO111MODULE=on") - pkg.CheckError("generating Go memcached with webhooks and metrics documentation context", err) + generateWithMonitoring = strings.HasSuffix(samplesPath, "monitoring") + + logInfo := "starting to generate Go memcached sample with webhooks" + errorInfo := "generating Go memcached with context: webhooks" - generateWithMonitoring = false - if strings.HasSuffix(samplesPath, "monitoring") { - generateWithMonitoring = true + if generateWithMonitoring { + logInfo += monitoringString + errorInfo += monitoringString } + log.Infof(logInfo) + ctx, err := pkg.NewSampleContext(binaryPath, filepath.Join(samplesPath, "memcached-operator"), "GO111MODULE=on") + pkg.CheckError(errorInfo, err) + memcached := Memcached{&ctx} memcached.Prepare() memcached.Run() } -// Prepare the Context for the Memcached with webhooks and metrics documentation Go Sample +// Prepare the Context for the Memcached with webhooks or with webhooks and monitoring Go Sample // Note that sample directory will be re-created and the context data for the sample // will be set such as the domain and GVK. func (mh *Memcached) Prepare() { - log.Infof("destroying directory for Memcached with webhooks and metrics documentation Go samples") + logInfo := "destroying directory for Go Memcached sample with webhooks" + + if generateWithMonitoring { + logInfo += monitoringString + } + + log.Infof(logInfo) mh.ctx.Destroy() log.Infof("creating directory") @@ -71,7 +84,7 @@ func (mh *Memcached) Prepare() { mh.ctx.Kind = "Memcached" } -// Run the steps to create the Memcached with metrics and webhooks Go Sample +// Run the steps to create the Memcached with webhooks or with webhooks and monitoring Go Sample func (mh *Memcached) Run() { if !mh.isV3() { @@ -930,105 +943,45 @@ const metricsdocsFragment = ` package main import ( + "bytes" "fmt" "sort" + "text/template" "github.com/example/memcached-operator/monitoring" ) -// please run "make generate-metricsdocs" to run this tool and update metrics documentation -const ( - title = "# Operator Metrics\n" - background = "This document aims to help users that are not familiar with metrics exposed by this operator.\n" + - "The metrics documentation is auto-generated by the utility tool \"monitoring/metricsdocs\" and reflects all of the metrics that are exposed by the operator.\n\n" - - KVSpecificMetrics = "## Operator Metrics List\n" - - opening = title + - background + - KVSpecificMetrics - - // footer - footerHeading = "## Developing new metrics\n" - footerContent = "After developing new metrics or changing old ones, please run \"make generate-metricsdocs\" to regenerate this document.\n\n" + - "If you feel that the new metric doesn't follow these rules, please change \"monitoring/metricsdocs\" according to your needs.\n" - - footer = footerHeading + footerContent -) - -// TODO: scaffolding these helpers with operator-lib: https://github.com/operator-framework/operator-lib. - -// metricList contains the name, description, and type for each metric. func main() { - metricList := metricDescriptionListToMetricList(monitoring.ListMetrics()) - sort.Sort(metricList) - writeToStdOut(metricList) -} + metricDescriptions := monitoring.ListMetrics() + sort.Slice(metricDescriptions, func(i, j int) bool { + return metricDescriptions[i].Name < metricDescriptions[j].Name + }) + + tmpl, err := template.New("Operator metrics").Parse("# Operator Metrics\n" + + "This document aims to help users that are not familiar with metrics exposed by this operator.\n" + + "The metrics documentation is auto-generated by the utility tool \"monitoring/metricsdocs\" and reflects all of the metrics that are exposed by the operator.\n\n" + + "## Operator Metrics List" + + "{{range .}}\n" + + "### {{.Name}}\n" + + "{{.Help}} " + + "Type: {{.Type}}.\n" + + "{{end}}" + + "## Developing new metrics\n" + + "After developing new metrics or changing old ones, please run \"make generate-metricsdocs\" to regenerate this document.\n\n" + + "If you feel that the new metric doesn't follow these rules, please change \"monitoring/metricsdocs\" according to your needs.") -// writeToStdOut receives a list of metrics and prints them to STDOUT. -func writeToStdOut(metricsList metricList) { - fmt.Print(opening) - metricsList.writeOut() - fmt.Print(footer) -} - -// Metric is an exported struct that defines the metric -// name, description, and type as a new type named Metric. -type Metric struct { - name string - description string - metricType string -} - -func metricDescriptionToMetric(md monitoring.MetricDescription) Metric { - return Metric{ - name: md.Name, - description: md.Help, - metricType: md.Type, + if err != nil { + panic(err) } -} - -// writeOut receives a metric of type metric and prints -// the metric name, description, and type. -func (m Metric) writeOut() { - fmt.Println("###", m.name) - fmt.Println(m.description, "Type: "+m.metricType+".") -} -// metricList is an array that contain metrics from type metric, -// as a new type named metricList. -type metricList []Metric - -// metricDescriptionListToMetricList collects the metrics exposed by the -// operator, and inserts them into the metricList array. -func metricDescriptionListToMetricList(mdl []monitoring.MetricDescription) metricList { - res := make([]Metric, len(mdl)) - for i, md := range mdl { - res[i] = metricDescriptionToMetric(md) + // generate the template using the sorted list of metrics + var buf bytes.Buffer + if err := tmpl.Execute(&buf, metricDescriptions); err != nil { + panic(err) } - return res -} - -// Len implements sort.Interface.Len -func (m metricList) Len() int { - return len(m) -} - -// Less implements sort.Interface.Less -func (m metricList) Less(i, j int) bool { - return m[i].name < m[j].name -} - -// Swap implements sort.Interface.Swap -func (m metricList) Swap(i, j int) { - m[i], m[j] = m[j], m[i] -} - -func (m metricList) writeOut() { - for _, met := range m { - met.writeOut() - } + // print the generated metrics documentation + fmt.Println(buf.String()) } ` diff --git a/testdata/go/v3/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go b/testdata/go/v3/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go index 08fb06f0804..84ae54faf4a 100644 --- a/testdata/go/v3/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go +++ b/testdata/go/v3/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go @@ -17,103 +17,43 @@ limitations under the License. package main import ( + "bytes" "fmt" "sort" + "text/template" "github.com/example/memcached-operator/monitoring" ) -// please run "make generate-metricsdocs" to run this tool and update metrics documentation -const ( - title = "# Operator Metrics\n" - background = "This document aims to help users that are not familiar with metrics exposed by this operator.\n" + - "The metrics documentation is auto-generated by the utility tool \"monitoring/metricsdocs\" and reflects all of the metrics that are exposed by the operator.\n\n" - - KVSpecificMetrics = "## Operator Metrics List\n" - - opening = title + - background + - KVSpecificMetrics - - // footer - footerHeading = "## Developing new metrics\n" - footerContent = "After developing new metrics or changing old ones, please run \"make generate-metricsdocs\" to regenerate this document.\n\n" + - "If you feel that the new metric doesn't follow these rules, please change \"monitoring/metricsdocs\" according to your needs.\n" - - footer = footerHeading + footerContent -) - -// TODO: scaffolding these helpers with operator-lib: https://github.com/operator-framework/operator-lib. - -// metricList contains the name, description, and type for each metric. func main() { - metricList := metricDescriptionListToMetricList(monitoring.ListMetrics()) - sort.Sort(metricList) - writeToStdOut(metricList) -} - -// writeToStdOut receives a list of metrics and prints them to STDOUT. -func writeToStdOut(metricsList metricList) { - fmt.Print(opening) - metricsList.writeOut() - fmt.Print(footer) -} - -// Metric is an exported struct that defines the metric -// name, description, and type as a new type named Metric. -type Metric struct { - name string - description string - metricType string -} - -func metricDescriptionToMetric(md monitoring.MetricDescription) Metric { - return Metric{ - name: md.Name, - description: md.Help, - metricType: md.Type, + metricDescriptions := monitoring.ListMetrics() + sort.Slice(metricDescriptions, func(i, j int) bool { + return metricDescriptions[i].Name < metricDescriptions[j].Name + }) + + tmpl, err := template.New("Operator metrics").Parse("# Operator Metrics\n" + + "This document aims to help users that are not familiar with metrics exposed by this operator.\n" + + "The metrics documentation is auto-generated by the utility tool \"monitoring/metricsdocs\" and reflects all of the metrics that are exposed by the operator.\n\n" + + "## Operator Metrics List" + + "{{range .}}\n" + + "### {{.Name}}\n" + + "{{.Help}} " + + "Type: {{.Type}}.\n" + + "{{end}}" + + "## Developing new metrics\n" + + "After developing new metrics or changing old ones, please run \"make generate-metricsdocs\" to regenerate this document.\n\n" + + "If you feel that the new metric doesn't follow these rules, please change \"monitoring/metricsdocs\" according to your needs.") + + if err != nil { + panic(err) } -} - -// writeOut receives a metric of type metric and prints -// the metric name, description, and type. -func (m Metric) writeOut() { - fmt.Println("###", m.name) - fmt.Println(m.description, "Type: "+m.metricType+".") -} - -// metricList is an array that contain metrics from type metric, -// as a new type named metricList. -type metricList []Metric -// metricDescriptionListToMetricList collects the metrics exposed by the -// operator, and inserts them into the metricList array. -func metricDescriptionListToMetricList(mdl []monitoring.MetricDescription) metricList { - res := make([]Metric, len(mdl)) - for i, md := range mdl { - res[i] = metricDescriptionToMetric(md) + // generate the template using the sorted list of metrics + var buf bytes.Buffer + if err := tmpl.Execute(&buf, metricDescriptions); err != nil { + panic(err) } - return res -} - -// Len implements sort.Interface.Len -func (m metricList) Len() int { - return len(m) -} - -// Less implements sort.Interface.Less -func (m metricList) Less(i, j int) bool { - return m[i].name < m[j].name -} - -// Swap implements sort.Interface.Swap -func (m metricList) Swap(i, j int) { - m[i], m[j] = m[j], m[i] -} - -func (m metricList) writeOut() { - for _, met := range m { - met.writeOut() - } + // print the generated metrics documentation + fmt.Println(buf.String()) } diff --git a/testdata/go/v4-alpha/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go b/testdata/go/v4-alpha/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go index 08fb06f0804..84ae54faf4a 100644 --- a/testdata/go/v4-alpha/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go +++ b/testdata/go/v4-alpha/monitoring/memcached-operator/monitoring/metricsdocs/metricsdocs.go @@ -17,103 +17,43 @@ limitations under the License. package main import ( + "bytes" "fmt" "sort" + "text/template" "github.com/example/memcached-operator/monitoring" ) -// please run "make generate-metricsdocs" to run this tool and update metrics documentation -const ( - title = "# Operator Metrics\n" - background = "This document aims to help users that are not familiar with metrics exposed by this operator.\n" + - "The metrics documentation is auto-generated by the utility tool \"monitoring/metricsdocs\" and reflects all of the metrics that are exposed by the operator.\n\n" - - KVSpecificMetrics = "## Operator Metrics List\n" - - opening = title + - background + - KVSpecificMetrics - - // footer - footerHeading = "## Developing new metrics\n" - footerContent = "After developing new metrics or changing old ones, please run \"make generate-metricsdocs\" to regenerate this document.\n\n" + - "If you feel that the new metric doesn't follow these rules, please change \"monitoring/metricsdocs\" according to your needs.\n" - - footer = footerHeading + footerContent -) - -// TODO: scaffolding these helpers with operator-lib: https://github.com/operator-framework/operator-lib. - -// metricList contains the name, description, and type for each metric. func main() { - metricList := metricDescriptionListToMetricList(monitoring.ListMetrics()) - sort.Sort(metricList) - writeToStdOut(metricList) -} - -// writeToStdOut receives a list of metrics and prints them to STDOUT. -func writeToStdOut(metricsList metricList) { - fmt.Print(opening) - metricsList.writeOut() - fmt.Print(footer) -} - -// Metric is an exported struct that defines the metric -// name, description, and type as a new type named Metric. -type Metric struct { - name string - description string - metricType string -} - -func metricDescriptionToMetric(md monitoring.MetricDescription) Metric { - return Metric{ - name: md.Name, - description: md.Help, - metricType: md.Type, + metricDescriptions := monitoring.ListMetrics() + sort.Slice(metricDescriptions, func(i, j int) bool { + return metricDescriptions[i].Name < metricDescriptions[j].Name + }) + + tmpl, err := template.New("Operator metrics").Parse("# Operator Metrics\n" + + "This document aims to help users that are not familiar with metrics exposed by this operator.\n" + + "The metrics documentation is auto-generated by the utility tool \"monitoring/metricsdocs\" and reflects all of the metrics that are exposed by the operator.\n\n" + + "## Operator Metrics List" + + "{{range .}}\n" + + "### {{.Name}}\n" + + "{{.Help}} " + + "Type: {{.Type}}.\n" + + "{{end}}" + + "## Developing new metrics\n" + + "After developing new metrics or changing old ones, please run \"make generate-metricsdocs\" to regenerate this document.\n\n" + + "If you feel that the new metric doesn't follow these rules, please change \"monitoring/metricsdocs\" according to your needs.") + + if err != nil { + panic(err) } -} - -// writeOut receives a metric of type metric and prints -// the metric name, description, and type. -func (m Metric) writeOut() { - fmt.Println("###", m.name) - fmt.Println(m.description, "Type: "+m.metricType+".") -} - -// metricList is an array that contain metrics from type metric, -// as a new type named metricList. -type metricList []Metric -// metricDescriptionListToMetricList collects the metrics exposed by the -// operator, and inserts them into the metricList array. -func metricDescriptionListToMetricList(mdl []monitoring.MetricDescription) metricList { - res := make([]Metric, len(mdl)) - for i, md := range mdl { - res[i] = metricDescriptionToMetric(md) + // generate the template using the sorted list of metrics + var buf bytes.Buffer + if err := tmpl.Execute(&buf, metricDescriptions); err != nil { + panic(err) } - return res -} - -// Len implements sort.Interface.Len -func (m metricList) Len() int { - return len(m) -} - -// Less implements sort.Interface.Less -func (m metricList) Less(i, j int) bool { - return m[i].name < m[j].name -} - -// Swap implements sort.Interface.Swap -func (m metricList) Swap(i, j int) { - m[i], m[j] = m[j], m[i] -} - -func (m metricList) writeOut() { - for _, met := range m { - met.writeOut() - } + // print the generated metrics documentation + fmt.Println(buf.String()) }