From 82afa69f46fa1f6abd0dfbb0f5ba91af84700baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Fri, 21 Aug 2020 12:42:44 +0200 Subject: [PATCH 1/5] The system info metrics now use OpenCensus instead of the Prometheus client library --- go.mod | 1 - .../http/services/prometheus/prometheus.go | 13 +- pkg/sysinfo/metrics.go | 135 ++++++++++++++++++ pkg/sysinfo/prometheus.go | 103 ------------- pkg/sysinfo/reva.go | 2 +- 5 files changed, 140 insertions(+), 114 deletions(-) create mode 100644 pkg/sysinfo/metrics.go delete mode 100644 pkg/sysinfo/prometheus.go diff --git a/go.mod b/go.mod index 5e91d48b9d..5a00947977 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,6 @@ require ( github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 // indirect github.com/pkg/xattr v0.4.1 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect - github.com/prometheus/client_golang v1.7.1 github.com/rs/cors v1.7.0 github.com/rs/zerolog v1.19.0 github.com/stretchr/testify v1.6.1 diff --git a/internal/http/services/prometheus/prometheus.go b/internal/http/services/prometheus/prometheus.go index 99f2bd5f3b..298ca9c47f 100644 --- a/internal/http/services/prometheus/prometheus.go +++ b/internal/http/services/prometheus/prometheus.go @@ -24,7 +24,6 @@ import ( "contrib.go.opencensus.io/exporter/prometheus" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" - promclient "github.com/prometheus/client_golang/prometheus" "github.com/rs/zerolog" "go.opencensus.io/stats/view" @@ -48,23 +47,21 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) conf.init() - registry := promclient.NewRegistry() // A Prometheus registry shared by OpenCensus and SysInfo pe, err := prometheus.NewExporter(prometheus.Options{ Namespace: "revad", - Registry: registry, }) if err != nil { return nil, errors.Wrap(err, "prometheus: error creating exporter") } // Initialize the SysInfo Prometheus exporter - sysinfo, err := sysinfo.NewPrometheusExporter(registry) - if err != nil { - return nil, errors.Wrap(err, "prometheus: unable to create system info exporter") + // TODO: Centralize registration of new metrics + if err := sysinfo.RegisterSystemInfoMetrics(); err != nil { + return nil, errors.Wrap(err, "prometheus: unable to create system info metrics") } view.RegisterExporter(pe) - return &svc{prefix: conf.Prefix, h: pe, sysinfo: sysinfo}, nil + return &svc{prefix: conf.Prefix, h: pe}, nil } type config struct { @@ -80,8 +77,6 @@ func (c *config) init() { type svc struct { prefix string h http.Handler - - sysinfo *sysinfo.PrometheusExporter } func (s *svc) Prefix() string { diff --git a/pkg/sysinfo/metrics.go b/pkg/sysinfo/metrics.go new file mode 100644 index 0000000000..ca66bc0ab2 --- /dev/null +++ b/pkg/sysinfo/metrics.go @@ -0,0 +1,135 @@ +// Copyright 2018-2020 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package sysinfo + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/pkg/errors" + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" + + "github.com/cs3org/reva/pkg/utils" +) + +type sysInfoMetricsLabels = map[tag.Key]string + +type sysInfoMetrics struct { + sysInfoStats *stats.Int64Measure + sysInfoView *view.View + + labels sysInfoMetricsLabels + + ctx context.Context +} + +var ( + metrics *sysInfoMetrics +) + +func (m *sysInfoMetrics) init() error { + m.labels = m.getLabels("", SysInfo) + + // Collect all labels and their values; the values are stored as mutators + var tagKeys []tag.Key + var mutators []tag.Mutator + for key, value := range m.labels { + tagKeys = append(tagKeys, key) + mutators = append(mutators, tag.Insert(key, value)) + } + + // Create the OpenCensus statistics and a corresponding view + m.sysInfoStats = stats.Int64("sys_info", "A metric with a constant '1' value labeled by various system information elements", stats.UnitDimensionless) + m.sysInfoView = &view.View{ + Name: m.sysInfoStats.Name(), + Description: m.sysInfoStats.Description(), + Measure: m.sysInfoStats, + TagKeys: tagKeys, + Aggregation: view.LastValue(), + } + + if err := view.Register(m.sysInfoView); err != nil { + return errors.Wrap(err, "unable to register the system info view") + } + + // Create a new context to serve the metrics + if ctx, err := tag.New(context.Background(), mutators...); err == nil { + m.ctx = ctx + } else { + return errors.Wrap(err, "unable to create a context") + } + + return nil +} + +func (m *sysInfoMetrics) getLabels(root string, i interface{}) sysInfoMetricsLabels { + labels := sysInfoMetricsLabels{} + + // Iterate over each field of the given interface, recursively collecting the values as labels + v := reflect.ValueOf(i).Elem() + for i := 0; i < v.NumField(); i++ { + // Check if the field was tagged with 'sysinfo:omitlabel'; if so, skip this field + tags := v.Type().Field(i).Tag.Get("sysinfo") + if strings.Contains(tags, "omitlabel") { + continue + } + + // Get the name of the field from the parent structure + fieldName := utils.ToSnakeCase(v.Type().Field(i).Name) + if len(root) > 0 { + fieldName = "_" + fieldName + } + fieldName = root + fieldName + + // Check if the field is either a struct or a pointer to a struct; in that case, process the field recursively + f := v.Field(i) + if f.Kind() == reflect.Struct || (f.Kind() == reflect.Ptr && f.Elem().Kind() == reflect.Struct) { + // Merge labels recursively + for key, val := range m.getLabels(fieldName, f.Interface()) { + labels[key] = val + } + } else { // Store the value of the field in the labels + key := tag.MustNewKey(fieldName) + labels[key] = fmt.Sprintf("%v", f) + } + } + + return labels +} + +func (m *sysInfoMetrics) record() { + // Just record a simple hardcoded '1' to expose the system info as a metric + stats.Record(m.ctx, m.sysInfoStats.M(1)) +} + +// RegisterSystemInfoMetrics initializes and registers the system info metrics. +func RegisterSystemInfoMetrics() error { + // Create and initialize the local system info metrics object + metrics = &sysInfoMetrics{} + if err := metrics.init(); err != nil { + return errors.Wrap(err, "unable to initialize the system information metrics") + } + + metrics.record() + return nil +} diff --git a/pkg/sysinfo/prometheus.go b/pkg/sysinfo/prometheus.go deleted file mode 100644 index f327cb4010..0000000000 --- a/pkg/sysinfo/prometheus.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2018-2020 CERN -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// In applying this license, CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -package sysinfo - -import ( - "fmt" - "reflect" - "strings" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/cs3org/reva/pkg/utils" -) - -// PrometheusExporter exports system information via Prometheus. -type PrometheusExporter struct { - registry *prometheus.Registry - sysInfoMetric prometheus.GaugeFunc -} - -func (psysinfo *PrometheusExporter) init(registry *prometheus.Registry) error { - // Create all necessary Prometheus objects - psysinfo.registry = registry - psysinfo.sysInfoMetric = prometheus.NewGaugeFunc( - prometheus.GaugeOpts{ - Namespace: "revad", - Name: "sys_info", - Help: "A metric with a constant '1' value labeled by various system information elements", - ConstLabels: psysinfo.getLabels("", SysInfo), - }, - func() float64 { return 1 }, - ) - - if err := psysinfo.registry.Register(psysinfo.sysInfoMetric); err != nil { - return fmt.Errorf("unable to register the system information metrics: %v", err) - } - - return nil -} - -func (psysinfo *PrometheusExporter) getLabels(root string, i interface{}) prometheus.Labels { - labels := prometheus.Labels{} - - // Iterate over each field of the given interface, recursively collecting the values as labels - v := reflect.ValueOf(i).Elem() - for i := 0; i < v.NumField(); i++ { - // Check if the field was tagged with 'sysinfo:omitlabel'; if so, skip this field - tags := v.Type().Field(i).Tag.Get("sysinfo") - if strings.Contains(tags, "omitlabel") { - continue - } - - // Get the name of the field from the parent structure - fieldName := utils.ToSnakeCase(v.Type().Field(i).Name) - if len(root) > 0 { - fieldName = "_" + fieldName - } - fieldName = root + fieldName - - // Check if the field is either a struct or a pointer to a struct; in that case, process the field recursively - f := v.Field(i) - if f.Kind() == reflect.Struct || (f.Kind() == reflect.Ptr && f.Elem().Kind() == reflect.Struct) { - // Merge labels recursively - for key, val := range psysinfo.getLabels(fieldName, f.Interface()) { - labels[key] = val - } - } else { // Store the value of the field in the labels - labels[fieldName] = fmt.Sprintf("%v", f) - } - } - - return labels -} - -// NewPrometheusExporter creates a new Prometheus system information exporter. -func NewPrometheusExporter(registry *prometheus.Registry) (*PrometheusExporter, error) { - if registry == nil { - return nil, fmt.Errorf("no registry provided") - } - - exporter := &PrometheusExporter{} - if err := exporter.init(registry); err != nil { - return nil, err - } - - return exporter, nil -} diff --git a/pkg/sysinfo/reva.go b/pkg/sysinfo/reva.go index 1420a5252c..6438e85cc8 100644 --- a/pkg/sysinfo/reva.go +++ b/pkg/sysinfo/reva.go @@ -21,7 +21,7 @@ package sysinfo // RevaVersion stores version information about Reva. type RevaVersion struct { Version string `json:"version"` - BuildDate string `json:"build_date" sysinfo:"omitlabel"` + BuildDate string `json:"build_date"` GitCommit string `json:"git_commit" sysinfo:"omitlabel"` GoVersion string `json:"go_version" sysinfo:"omitlabel"` } From c80f50afc108aa8c5d2833b655a52f0e79815c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Fri, 21 Aug 2020 12:53:24 +0200 Subject: [PATCH 2/5] Lint fixes --- go.sum | 1 + pkg/sysinfo/metrics.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index e492c2ff34..b3c2b80dda 100644 --- a/go.sum +++ b/go.sum @@ -906,6 +906,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20u golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/pkg/sysinfo/metrics.go b/pkg/sysinfo/metrics.go index ca66bc0ab2..a4e1c4a832 100644 --- a/pkg/sysinfo/metrics.go +++ b/pkg/sysinfo/metrics.go @@ -51,8 +51,8 @@ func (m *sysInfoMetrics) init() error { m.labels = m.getLabels("", SysInfo) // Collect all labels and their values; the values are stored as mutators - var tagKeys []tag.Key - var mutators []tag.Mutator + tagKeys := make([]tag.Key, 0, len(m.labels)) + mutators := make([]tag.Mutator, 0, len(m.labels)) for key, value := range m.labels { tagKeys = append(tagKeys, key) mutators = append(mutators, tag.Insert(key, value)) From bb44d964005b7c22401e1ca05965e6a40ace371d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Fri, 21 Aug 2020 16:12:09 +0200 Subject: [PATCH 3/5] Moved the system info metrics registration out of the Prometheus service --- cmd/revad/main.go | 5 +++- .../http/services/prometheus/prometheus.go | 8 ----- pkg/sysinfo/metrics.go | 3 +- pkg/sysinfo/sysinfo.go | 29 ++++++++++++------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/cmd/revad/main.go b/cmd/revad/main.go index cfb5cb3a37..ac6eddae7e 100644 --- a/cmd/revad/main.go +++ b/cmd/revad/main.go @@ -53,7 +53,10 @@ func main() { flag.Parse() // initialize the global system information - sysinfo.InitSystemInfo(&sysinfo.RevaVersion{Version: version, BuildDate: buildDate, GitCommit: gitCommit, GoVersion: goVersion}) + if err := sysinfo.InitSystemInfo(&sysinfo.RevaVersion{Version: version, BuildDate: buildDate, GitCommit: gitCommit, GoVersion: goVersion}); err != nil { + fmt.Fprintf(os.Stderr, "error initializing system info: %s\n", err.Error()) + // This is not really a fatal error, so don't panic + } handleVersionFlag() handleSignalFlag() diff --git a/internal/http/services/prometheus/prometheus.go b/internal/http/services/prometheus/prometheus.go index 298ca9c47f..7330fcb111 100644 --- a/internal/http/services/prometheus/prometheus.go +++ b/internal/http/services/prometheus/prometheus.go @@ -28,8 +28,6 @@ import ( "go.opencensus.io/stats/view" "github.com/cs3org/reva/pkg/rhttp/global" - "github.com/cs3org/reva/pkg/sysinfo" - // Initializes goroutines which periodically update stats _ "github.com/cs3org/reva/pkg/metrics/reader/dummy" ) @@ -54,12 +52,6 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) return nil, errors.Wrap(err, "prometheus: error creating exporter") } - // Initialize the SysInfo Prometheus exporter - // TODO: Centralize registration of new metrics - if err := sysinfo.RegisterSystemInfoMetrics(); err != nil { - return nil, errors.Wrap(err, "prometheus: unable to create system info metrics") - } - view.RegisterExporter(pe) return &svc{prefix: conf.Prefix, h: pe}, nil } diff --git a/pkg/sysinfo/metrics.go b/pkg/sysinfo/metrics.go index a4e1c4a832..d4a1068d72 100644 --- a/pkg/sysinfo/metrics.go +++ b/pkg/sysinfo/metrics.go @@ -122,8 +122,7 @@ func (m *sysInfoMetrics) record() { stats.Record(m.ctx, m.sysInfoStats.M(1)) } -// RegisterSystemInfoMetrics initializes and registers the system info metrics. -func RegisterSystemInfoMetrics() error { +func registerSystemInfoMetrics() error { // Create and initialize the local system info metrics object metrics = &sysInfoMetrics{} if err := metrics.init(); err != nil { diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go index 8c8743df97..da4f89075a 100644 --- a/pkg/sysinfo/sysinfo.go +++ b/pkg/sysinfo/sysinfo.go @@ -22,6 +22,8 @@ import ( "encoding/json" "fmt" "reflect" + + "github.com/pkg/errors" ) // SystemInformation stores general information about Reva and the system it's running on. @@ -44,16 +46,6 @@ func (sysInfo *SystemInformation) ToJSON() (string, error) { return string(data), nil } -// InitSystemInfo initializes the global system information object. -func InitSystemInfo(revaVersion *RevaVersion) { - SysInfo = &SystemInformation{ - Reva: revaVersion, - } - - // Replace any empty values in the system information by more meaningful ones - replaceEmptyInfoValues(SysInfo) -} - func replaceEmptyInfoValues(i interface{}) { // Iterate over each field of the given interface and search for "empty" values v := reflect.ValueOf(i).Elem() @@ -71,3 +63,20 @@ func replaceEmptyInfoValues(i interface{}) { } } } + +// InitSystemInfo initializes the global system information object and also registers the corresponding metrics. +func InitSystemInfo(revaVersion *RevaVersion) error { + SysInfo = &SystemInformation{ + Reva: revaVersion, + } + + // Replace any empty values in the system information by more meaningful ones + replaceEmptyInfoValues(SysInfo) + + // Register the system information metrics, as the necessary system info object has been filled out + if err := registerSystemInfoMetrics(); err != nil { + return errors.Wrap(err, "unable to register the system info metrics") + } + + return nil +} From 5c1ab6d9af157a2731479427fa101f43bae2ada7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Fri, 21 Aug 2020 16:20:19 +0200 Subject: [PATCH 4/5] Added changelog --- changelog/unreleased/sysinfo-cleanup.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/unreleased/sysinfo-cleanup.md diff --git a/changelog/unreleased/sysinfo-cleanup.md b/changelog/unreleased/sysinfo-cleanup.md new file mode 100644 index 0000000000..a772d8461d --- /dev/null +++ b/changelog/unreleased/sysinfo-cleanup.md @@ -0,0 +1,5 @@ +Enhancement: System information metrics now use OpenCensus and were moved out of the Prometheus service + +The system information metrics are now based on OpenCensus instead of the Prometheus client library. Furthermore, its initialization was moved out of the Prometheus HTTP service to keep things clean. + +https://github.com/cs3org/reva/pull/1114 From 1a1a0f5c5e61cdb62a9332b348f6b52c51604ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Tue, 25 Aug 2020 15:45:45 +0200 Subject: [PATCH 5/5] Some cleanup --- changelog/unreleased/sysinfo-cleanup.md | 2 +- pkg/sysinfo/metrics.go | 62 +++++++------------------ 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/changelog/unreleased/sysinfo-cleanup.md b/changelog/unreleased/sysinfo-cleanup.md index a772d8461d..b247ff5d97 100644 --- a/changelog/unreleased/sysinfo-cleanup.md +++ b/changelog/unreleased/sysinfo-cleanup.md @@ -1,4 +1,4 @@ -Enhancement: System information metrics now use OpenCensus and were moved out of the Prometheus service +Enhancement: System information metrics cleanup The system information metrics are now based on OpenCensus instead of the Prometheus client library. Furthermore, its initialization was moved out of the Prometheus HTTP service to keep things clean. diff --git a/pkg/sysinfo/metrics.go b/pkg/sysinfo/metrics.go index d4a1068d72..6b7b443a9e 100644 --- a/pkg/sysinfo/metrics.go +++ b/pkg/sysinfo/metrics.go @@ -34,55 +34,43 @@ import ( type sysInfoMetricsLabels = map[tag.Key]string -type sysInfoMetrics struct { - sysInfoStats *stats.Int64Measure - sysInfoView *view.View - - labels sysInfoMetricsLabels - - ctx context.Context -} - -var ( - metrics *sysInfoMetrics -) - -func (m *sysInfoMetrics) init() error { - m.labels = m.getLabels("", SysInfo) +func registerSystemInfoMetrics() error { + labels := getSystemInfoMetricsLabels("", SysInfo) // Collect all labels and their values; the values are stored as mutators - tagKeys := make([]tag.Key, 0, len(m.labels)) - mutators := make([]tag.Mutator, 0, len(m.labels)) - for key, value := range m.labels { + tagKeys := make([]tag.Key, 0, len(labels)) + mutators := make([]tag.Mutator, 0, len(labels)) + for key, value := range labels { tagKeys = append(tagKeys, key) mutators = append(mutators, tag.Insert(key, value)) } // Create the OpenCensus statistics and a corresponding view - m.sysInfoStats = stats.Int64("sys_info", "A metric with a constant '1' value labeled by various system information elements", stats.UnitDimensionless) - m.sysInfoView = &view.View{ - Name: m.sysInfoStats.Name(), - Description: m.sysInfoStats.Description(), - Measure: m.sysInfoStats, + sysInfoStats := stats.Int64("sys_info", "A metric with a constant '1' value labeled by various system information elements", stats.UnitDimensionless) + sysInfoView := &view.View{ + Name: sysInfoStats.Name(), + Description: sysInfoStats.Description(), + Measure: sysInfoStats, TagKeys: tagKeys, Aggregation: view.LastValue(), } - if err := view.Register(m.sysInfoView); err != nil { - return errors.Wrap(err, "unable to register the system info view") + if err := view.Register(sysInfoView); err != nil { + return errors.Wrap(err, "unable to register the system info metrics view") } // Create a new context to serve the metrics if ctx, err := tag.New(context.Background(), mutators...); err == nil { - m.ctx = ctx + // Just record a simple hardcoded '1' to expose the system info as a metric + stats.Record(ctx, sysInfoStats.M(1)) } else { - return errors.Wrap(err, "unable to create a context") + return errors.Wrap(err, "unable to create a context for the system info metrics") } return nil } -func (m *sysInfoMetrics) getLabels(root string, i interface{}) sysInfoMetricsLabels { +func getSystemInfoMetricsLabels(root string, i interface{}) sysInfoMetricsLabels { labels := sysInfoMetricsLabels{} // Iterate over each field of the given interface, recursively collecting the values as labels @@ -105,7 +93,7 @@ func (m *sysInfoMetrics) getLabels(root string, i interface{}) sysInfoMetricsLab f := v.Field(i) if f.Kind() == reflect.Struct || (f.Kind() == reflect.Ptr && f.Elem().Kind() == reflect.Struct) { // Merge labels recursively - for key, val := range m.getLabels(fieldName, f.Interface()) { + for key, val := range getSystemInfoMetricsLabels(fieldName, f.Interface()) { labels[key] = val } } else { // Store the value of the field in the labels @@ -116,19 +104,3 @@ func (m *sysInfoMetrics) getLabels(root string, i interface{}) sysInfoMetricsLab return labels } - -func (m *sysInfoMetrics) record() { - // Just record a simple hardcoded '1' to expose the system info as a metric - stats.Record(m.ctx, m.sysInfoStats.M(1)) -} - -func registerSystemInfoMetrics() error { - // Create and initialize the local system info metrics object - metrics = &sysInfoMetrics{} - if err := metrics.init(); err != nil { - return errors.Wrap(err, "unable to initialize the system information metrics") - } - - metrics.record() - return nil -}