From 24a879a063a562125d1458b759a1f95b48b415e4 Mon Sep 17 00:00:00 2001 From: Chris Grindstaff Date: Thu, 20 Jul 2023 14:22:58 -0400 Subject: [PATCH 1/2] refactor: fix inconsistent pointer receivers refactor: fix receive has generic name refactor: Unquoted port mapping not recommended refactor: delete redundant size hint refactor: don't alias imported package name refactor: Type assertion on errors fail on wrapped errors --- cmd/collectors/rest/plugins/disk/disk.go | 4 +- cmd/collectors/rest/plugins/qtree/qtree.go | 4 +- cmd/collectors/restperf/plugins/disk/disk.go | 8 +- .../restperf/plugins/headroom/headroom.go | 4 +- cmd/collectors/restperf/plugins/nic/nic.go | 20 +-- cmd/collectors/zapi/plugins/qtree/qtree.go | 4 +- cmd/collectors/zapiperf/plugins/disk/disk.go | 6 +- cmd/collectors/zapiperf/plugins/fcvi/fcvi.go | 4 +- .../zapiperf/plugins/headroom/headroom.go | 4 +- cmd/collectors/zapiperf/plugins/nic/nic.go | 20 +-- cmd/poller/exporter/exporter.go | 60 +++---- cmd/poller/poller.go | 3 +- go.mod | 2 +- go.sum | 2 + pkg/matrix/errors.go | 1 - pkg/matrix/matrix.go | 14 +- pkg/tree/xml/xml.go | 8 +- .../go-openapi/jsonpointer/pointer.go | 147 ++++++++++++++++-- vendor/modules.txt | 4 +- 19 files changed, 217 insertions(+), 102 deletions(-) diff --git a/cmd/collectors/rest/plugins/disk/disk.go b/cmd/collectors/rest/plugins/disk/disk.go index 20a55467c..9a585b4c3 100644 --- a/cmd/collectors/rest/plugins/disk/disk.go +++ b/cmd/collectors/rest/plugins/disk/disk.go @@ -16,8 +16,8 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { return &Disk{AbstractPlugin: p} } -func (me *Disk) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { - data := dataMap[me.Object] +func (d *Disk) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { + data := dataMap[d.Object] for _, instance := range data.GetInstances() { containerType := instance.GetLabel("container_type") diff --git a/cmd/collectors/rest/plugins/qtree/qtree.go b/cmd/collectors/rest/plugins/qtree/qtree.go index e854c1e51..840e0edce 100644 --- a/cmd/collectors/rest/plugins/qtree/qtree.go +++ b/cmd/collectors/rest/plugins/qtree/qtree.go @@ -194,7 +194,7 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error return []*matrix.Matrix{qtreePluginData, my.data}, nil } -func (my Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { +func (my *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { for _, quota := range result { var tree string var quotaInstance *matrix.Instance @@ -289,7 +289,7 @@ func (my Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.Ma return nil } -func (my Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quotaCount *int, numMetrics *int) error { +func (my *Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quotaCount *int, numMetrics *int) error { for quotaIndex, quota := range result { var tree string diff --git a/cmd/collectors/restperf/plugins/disk/disk.go b/cmd/collectors/restperf/plugins/disk/disk.go index f5ce44d37..03855a07d 100644 --- a/cmd/collectors/restperf/plugins/disk/disk.go +++ b/cmd/collectors/restperf/plugins/disk/disk.go @@ -331,7 +331,7 @@ func (d *Disk) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) shelfChildInstance.SetLabel("shelf", shelfName) - // Each child would have different possible values which is ugly way to write all of them, + // Each child would have different possible values which is an ugly way to write all of them, // so normal value would be mapped to 1 and rest all are mapped to 0. if shelfChildInstance.GetLabel("status") == "normal" { _ = statusMetric.SetValueInt64(shelfChildInstance, 1) @@ -744,7 +744,7 @@ func (d *Disk) initMaps() { func (d *Disk) calculateEnvironmentMetrics(data *matrix.Matrix) { var err error - shelfEnvironmentMetricMap := make(map[string]*shelfEnvironmentMetric, 0) + shelfEnvironmentMetricMap := make(map[string]*shelfEnvironmentMetric) for _, o := range d.shelfData { for k, instance := range o.GetInstances() { firstInd := strings.Index(k, "#") @@ -779,7 +779,7 @@ func (d *Disk) calculateEnvironmentMetrics(data *matrix.Matrix) { if mkey == "voltage" { if value, ok := metric.GetValueFloat64(instance); ok { if shelfEnvironmentMetricMap[iKey].voltageSensor == nil { - shelfEnvironmentMetricMap[iKey].voltageSensor = make(map[string]float64, 0) + shelfEnvironmentMetricMap[iKey].voltageSensor = make(map[string]float64) } shelfEnvironmentMetricMap[iKey].voltageSensor[iKey2] = value } @@ -788,7 +788,7 @@ func (d *Disk) calculateEnvironmentMetrics(data *matrix.Matrix) { if mkey == "current" { if value, ok := metric.GetValueFloat64(instance); ok { if shelfEnvironmentMetricMap[iKey].currentSensor == nil { - shelfEnvironmentMetricMap[iKey].currentSensor = make(map[string]float64, 0) + shelfEnvironmentMetricMap[iKey].currentSensor = make(map[string]float64) } shelfEnvironmentMetricMap[iKey].currentSensor[iKey2] = value } diff --git a/cmd/collectors/restperf/plugins/headroom/headroom.go b/cmd/collectors/restperf/plugins/headroom/headroom.go index 3bdf30098..9ca63bbf1 100644 --- a/cmd/collectors/restperf/plugins/headroom/headroom.go +++ b/cmd/collectors/restperf/plugins/headroom/headroom.go @@ -14,9 +14,9 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { return &Headroom{AbstractPlugin: p} } -func (me *Headroom) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { +func (h *Headroom) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { - data := dataMap[me.Object] + data := dataMap[h.Object] for _, instance := range data.GetInstances() { // no need to continue if labels are already parsed diff --git a/cmd/collectors/restperf/plugins/nic/nic.go b/cmd/collectors/restperf/plugins/nic/nic.go index 09f55a7b5..8d4436127 100644 --- a/cmd/collectors/restperf/plugins/nic/nic.go +++ b/cmd/collectors/restperf/plugins/nic/nic.go @@ -30,11 +30,11 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { } // Run speed label is reported in bits-per-second and rx/tx is reported as bytes-per-second -func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { +func (n *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { var read, write, rx, tx, util *matrix.Metric var err error - data := dataMap[me.Object] + data := dataMap[n.Object] if read = data.GetMetric("receive_bytes"); read == nil { return nil, errs.New(errs.ErrNoMetric, "receive_bytes") @@ -78,14 +78,14 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) if strings.HasSuffix(s, "M") { base, err = strconv.Atoi(strings.TrimSuffix(s, "M")) if err != nil { - me.Logger.Warn().Msgf("convert speed [%s]", s) + n.Logger.Warn().Msgf("convert speed [%s]", s) } else { // NIC speed value converted from Mbps to Bps(bytes per second) speed = base * 125000 - me.Logger.Debug().Msgf("converted speed (%s) to numeric (%d)", s, speed) + n.Logger.Debug().Msgf("converted speed (%s) to numeric (%d)", s, speed) } } else if speed, err = strconv.Atoi(s); err != nil { - me.Logger.Warn().Msgf("convert speed [%s]", s) + n.Logger.Warn().Msgf("convert speed [%s]", s) } if speed != 0 { @@ -97,7 +97,7 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) rxPercent = rxBytes / float64(speed) err := rx.SetValueFloat64(instance, rxPercent) if err != nil { - me.Logger.Error().Stack().Err(err).Msg("error") + n.Logger.Error().Stack().Err(err).Msg("error") } } @@ -105,14 +105,14 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) txPercent = txBytes / float64(speed) err := tx.SetValueFloat64(instance, txPercent) if err != nil { - me.Logger.Error().Stack().Err(err).Msg("error") + n.Logger.Error().Stack().Err(err).Msg("error") } } if rxOk || txOk { err := util.SetValueFloat64(instance, math.Max(rxPercent, txPercent)) if err != nil { - me.Logger.Error().Stack().Err(err).Msg("error") + n.Logger.Error().Stack().Err(err).Msg("error") } } } @@ -121,12 +121,12 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) if s = instance.GetLabel("speed"); strings.HasSuffix(s, "M") { base, err = strconv.Atoi(strings.TrimSuffix(s, "M")) if err != nil { - me.Logger.Warn().Msgf("convert speed [%s]", s) + n.Logger.Warn().Msgf("convert speed [%s]", s) } else { // NIC speed value converted from Mbps to bps(bits per second) speed = base * 1_000_000 instance.SetLabel("speed", strconv.Itoa(speed)) - me.Logger.Debug().Msgf("converted speed (%s) to numeric (%d)", s, speed) + n.Logger.Debug().Msgf("converted speed (%s) to numeric (%d)", s, speed) } } diff --git a/cmd/collectors/zapi/plugins/qtree/qtree.go b/cmd/collectors/zapi/plugins/qtree/qtree.go index fc0dc20b5..ddabda1c6 100644 --- a/cmd/collectors/zapi/plugins/qtree/qtree.go +++ b/cmd/collectors/zapi/plugins/qtree/qtree.go @@ -233,7 +233,7 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error return []*matrix.Matrix{qtreePluginData, my.data}, nil } -func (my Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { +func (my *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { for qIndex, quota := range quotas { var vserver, quotaInstanceKey string var qtreeInstance *matrix.Instance @@ -328,7 +328,7 @@ func (my Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Matr return nil } -func (my Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quotaIndex *int, numMetrics *int) error { +func (my *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quotaIndex *int, numMetrics *int) error { for _, quota := range quotas { var vserver, quotaInstanceKey, uid, uName string diff --git a/cmd/collectors/zapiperf/plugins/disk/disk.go b/cmd/collectors/zapiperf/plugins/disk/disk.go index 37f43bea1..e5dcd3d9f 100644 --- a/cmd/collectors/zapiperf/plugins/disk/disk.go +++ b/cmd/collectors/zapiperf/plugins/disk/disk.go @@ -665,7 +665,7 @@ func (d *Disk) handleShelfPower(shelves []*node.Node, output []*matrix.Matrix) ( func (d *Disk) calculateEnvironmentMetrics(data *matrix.Matrix) { var err error - shelfEnvironmentMetricMap := make(map[string]*shelfEnvironmentMetric, 0) + shelfEnvironmentMetricMap := make(map[string]*shelfEnvironmentMetric) for _, o := range d.shelfData { for k, instance := range o.GetInstances() { if !instance.IsExportable() { @@ -702,7 +702,7 @@ func (d *Disk) calculateEnvironmentMetrics(data *matrix.Matrix) { if mkey == "voltage-sensor-reading" { if value, ok := metric.GetValueFloat64(instance); ok { if shelfEnvironmentMetricMap[iKey].voltageSensor == nil { - shelfEnvironmentMetricMap[iKey].voltageSensor = make(map[string]float64, 0) + shelfEnvironmentMetricMap[iKey].voltageSensor = make(map[string]float64) } shelfEnvironmentMetricMap[iKey].voltageSensor[iKey2] = value } @@ -711,7 +711,7 @@ func (d *Disk) calculateEnvironmentMetrics(data *matrix.Matrix) { if mkey == "current-sensor-reading" { if value, ok := metric.GetValueFloat64(instance); ok { if shelfEnvironmentMetricMap[iKey].currentSensor == nil { - shelfEnvironmentMetricMap[iKey].currentSensor = make(map[string]float64, 0) + shelfEnvironmentMetricMap[iKey].currentSensor = make(map[string]float64) } shelfEnvironmentMetricMap[iKey].currentSensor[iKey2] = value } diff --git a/cmd/collectors/zapiperf/plugins/fcvi/fcvi.go b/cmd/collectors/zapiperf/plugins/fcvi/fcvi.go index 9363c25f2..6f7d8e882 100644 --- a/cmd/collectors/zapiperf/plugins/fcvi/fcvi.go +++ b/cmd/collectors/zapiperf/plugins/fcvi/fcvi.go @@ -66,9 +66,9 @@ func (f *FCVI) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) for _, adapterData := range result { adapter := adapterData.GetChildContentS("adapter-name") - node := adapterData.GetChildContentS("node-name") + nodeName := adapterData.GetChildContentS("node-name") port := adapterData.GetChildContentS("port-name") - adapterPortMap[node+adapter] = port + adapterPortMap[nodeName+adapter] = port } // we would not use getInstance() as key would be `sti8300mcc-215:kernel:fcvi_device_1` diff --git a/cmd/collectors/zapiperf/plugins/headroom/headroom.go b/cmd/collectors/zapiperf/plugins/headroom/headroom.go index 48724c946..cefc0f14e 100644 --- a/cmd/collectors/zapiperf/plugins/headroom/headroom.go +++ b/cmd/collectors/zapiperf/plugins/headroom/headroom.go @@ -17,9 +17,9 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { return &Headroom{AbstractPlugin: p} } -func (me *Headroom) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { +func (h *Headroom) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { - data := dataMap[me.Object] + data := dataMap[h.Object] for _, instance := range data.GetInstances() { if !instance.IsExportable() { continue diff --git a/cmd/collectors/zapiperf/plugins/nic/nic.go b/cmd/collectors/zapiperf/plugins/nic/nic.go index 8de000939..1bc696b0f 100644 --- a/cmd/collectors/zapiperf/plugins/nic/nic.go +++ b/cmd/collectors/zapiperf/plugins/nic/nic.go @@ -32,12 +32,12 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { } // Run speed label is reported in bits-per-second and rx/tx is reported as bytes-per-second -func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { +func (n *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { var read, write, rx, tx, util *matrix.Metric var err error - data := dataMap[me.Object] + data := dataMap[n.Object] if read = data.GetMetric("rx_bytes"); read == nil { return nil, errs.New(errs.ErrNoMetric, "rx_bytes") } @@ -85,14 +85,14 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) if strings.HasSuffix(s, "M") { base, err = strconv.Atoi(strings.TrimSuffix(s, "M")) if err != nil { - me.Logger.Warn().Msgf("convert speed [%s]", s) + n.Logger.Warn().Msgf("convert speed [%s]", s) } else { // NIC speed value converted from Mbps to Bps(bytes per second) speed = base * 125000 - me.Logger.Debug().Msgf("converted speed (%s) to Bps numeric (%d)", s, speed) + n.Logger.Debug().Msgf("converted speed (%s) to Bps numeric (%d)", s, speed) } } else if speed, err = strconv.Atoi(s); err != nil { - me.Logger.Warn().Msgf("convert speed [%s]", s) + n.Logger.Warn().Msgf("convert speed [%s]", s) } if speed != 0 { @@ -103,7 +103,7 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) rxPercent = rxBytes / float64(speed) err := rx.SetValueFloat64(instance, rxPercent) if err != nil { - me.Logger.Error().Stack().Err(err).Msg("error") + n.Logger.Error().Stack().Err(err).Msg("error") } } @@ -111,14 +111,14 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) txPercent = txBytes / float64(speed) err := tx.SetValueFloat64(instance, txPercent) if err != nil { - me.Logger.Error().Stack().Err(err).Msg("error") + n.Logger.Error().Stack().Err(err).Msg("error") } } if rxOk || txOk { err := util.SetValueFloat64(instance, math.Max(rxPercent, txPercent)) if err != nil { - me.Logger.Error().Stack().Err(err).Msg("error") + n.Logger.Error().Stack().Err(err).Msg("error") } } } @@ -127,12 +127,12 @@ func (me *Nic) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) if s = instance.GetLabel("speed"); strings.HasSuffix(s, "M") { base, err = strconv.Atoi(strings.TrimSuffix(s, "M")) if err != nil { - me.Logger.Warn().Msgf("convert speed [%s]", s) + n.Logger.Warn().Msgf("convert speed [%s]", s) } else { // NIC speed value converted from Mbps to bps(bits per second) speed = base * 1_000_000 instance.SetLabel("speed", strconv.Itoa(speed)) - me.Logger.Debug().Msgf("converted speed (%s) to bps numeric (%d)", s, speed) + n.Logger.Debug().Msgf("converted speed (%s) to bps numeric (%d)", s, speed) } } diff --git a/cmd/poller/exporter/exporter.go b/cmd/poller/exporter/exporter.go index 9bc093b68..402ae4b59 100644 --- a/cmd/poller/exporter/exporter.go +++ b/cmd/poller/exporter/exporter.go @@ -77,77 +77,77 @@ func New(c, n string, o *options.Options, p conf.Exporter, params *conf.Poller) } // InitAbc initializes AbstractExporter -func (me *AbstractExporter) InitAbc() error { - me.Metadata.SetGlobalLabel("hostname", me.Options.Hostname) - me.Metadata.SetGlobalLabel("version", me.Options.Version) - me.Metadata.SetGlobalLabel("poller", me.Options.Poller) - me.Metadata.SetGlobalLabel("exporter", me.Class) - me.Metadata.SetGlobalLabel("target", me.Name) - - if _, err := me.Metadata.NewMetricInt64("time"); err != nil { +func (e *AbstractExporter) InitAbc() error { + e.Metadata.SetGlobalLabel("hostname", e.Options.Hostname) + e.Metadata.SetGlobalLabel("version", e.Options.Version) + e.Metadata.SetGlobalLabel("poller", e.Options.Poller) + e.Metadata.SetGlobalLabel("exporter", e.Class) + e.Metadata.SetGlobalLabel("target", e.Name) + + if _, err := e.Metadata.NewMetricInt64("time"); err != nil { return err } - if _, err := me.Metadata.NewMetricUint64("count"); err != nil { + if _, err := e.Metadata.NewMetricUint64("count"); err != nil { return err } //e.Metadata.AddLabel("task", "") - if instance, err := me.Metadata.NewInstance("export"); err == nil { + if instance, err := e.Metadata.NewInstance("export"); err == nil { instance.SetLabel("task", "export") } else { return err } - if instance, err := me.Metadata.NewInstance("render"); err == nil { + if instance, err := e.Metadata.NewInstance("render"); err == nil { instance.SetLabel("task", "render") } else { return err } - me.SetStatus(0, "initialized") + e.SetStatus(0, "initialized") return nil } // GetClass returns the class of the AbstractExporter -func (me *AbstractExporter) GetClass() string { - return me.Class +func (e *AbstractExporter) GetClass() string { + return e.Class } // GetName returns the name of the AbstractExporter -func (me *AbstractExporter) GetName() string { - return me.Name +func (e *AbstractExporter) GetName() string { + return e.Name } // GetExportCount reports and resets count of exported data points "atomically" // this and next methods are only to report the poller // how much data we have exported (independent of poll/export interval) -func (me *AbstractExporter) GetExportCount() uint64 { - me.countMux.Lock() - count := me.exportCount - me.exportCount = 0 - me.countMux.Unlock() +func (e *AbstractExporter) GetExportCount() uint64 { + e.countMux.Lock() + count := e.exportCount + e.exportCount = 0 + e.countMux.Unlock() return count } // AddExportCount adds count n to the export counter -func (me *AbstractExporter) AddExportCount(n uint64) { - me.countMux.Lock() - me.exportCount += n - me.countMux.Unlock() +func (e *AbstractExporter) AddExportCount(n uint64) { + e.countMux.Lock() + e.exportCount += n + e.countMux.Unlock() } // GetStatus returns current state of exporter -func (me *AbstractExporter) GetStatus() (uint8, string, string) { - return me.Status, ExporterStatus[me.Status], me.Message +func (e *AbstractExporter) GetStatus() (uint8, string, string) { + return e.Status, ExporterStatus[e.Status], e.Message } // SetStatus sets the current state of exporter -func (me *AbstractExporter) SetStatus(code uint8, msg string) { +func (e *AbstractExporter) SetStatus(code uint8, msg string) { if code >= uint8(len(ExporterStatus)) { panic("invalid status code " + strconv.Itoa(int(code))) } - me.Status = code - me.Message = msg + e.Status = code + e.Message = msg } // @TODO: implement! diff --git a/cmd/poller/poller.go b/cmd/poller/poller.go index eda5f8068..1c4e7b164 100644 --- a/cmd/poller/poller.go +++ b/cmd/poller/poller.go @@ -1244,8 +1244,7 @@ func main() { // log as much as possible defer func() { if r := recover(); r != nil { - e := r.(error) - logger.Error().Stack().Err(e).Msg("Poller panicked") + logger.Error().Stack().Any("err", r).Msg("Poller panicked") logger.Fatal().Msg(`(main) terminating abnormally, tip: run in foreground mode (with "--loglevel 0") to debug`) } }() diff --git a/go.mod b/go.mod index 405934627..d8110d669 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( require ( github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 67ecf27e9..e4afcf57e 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= diff --git a/pkg/matrix/errors.go b/pkg/matrix/errors.go index 0cdc97419..6ae4963d0 100644 --- a/pkg/matrix/errors.go +++ b/pkg/matrix/errors.go @@ -14,6 +14,5 @@ const ( ErrInvalidInstanceKey = matrixError("invalid instance key") ErrDuplicateMetricKey = matrixError("duplicate metric key") ErrDuplicateInstanceKey = matrixError("duplicate instance key") - ErrOverflow = matrixError("overflow error") ErrUnequalVectors = matrixError("unequal vectors") ) diff --git a/pkg/matrix/matrix.go b/pkg/matrix/matrix.go index 59186bade..b88921e55 100644 --- a/pkg/matrix/matrix.go +++ b/pkg/matrix/matrix.go @@ -41,9 +41,9 @@ type With struct { func New(uuid, object string, identifier string) *Matrix { me := Matrix{UUID: uuid, Object: object, Identifier: identifier} me.globalLabels = dict.New() - me.instances = make(map[string]*Instance, 0) - me.metrics = make(map[string]*Metric, 0) - me.displayMetrics = make(map[string]string, 0) + me.instances = make(map[string]*Instance) + me.metrics = make(map[string]*Metric) + me.displayMetrics = make(map[string]string) me.exportable = true return &me } @@ -78,7 +78,7 @@ func (m *Matrix) Clone(with With) *Matrix { clone.globalLabels = m.globalLabels clone.exportOptions = m.exportOptions clone.exportable = m.exportable - clone.displayMetrics = make(map[string]string, 0) + clone.displayMetrics = make(map[string]string) if with.Instances { clone.instances = make(map[string]*Instance, len(m.GetInstances())) @@ -90,7 +90,7 @@ func (m *Matrix) Clone(with With) *Matrix { } } } else { - clone.instances = make(map[string]*Instance, 0) + clone.instances = make(map[string]*Instance) } if with.Metrics { @@ -101,7 +101,7 @@ func (m *Matrix) Clone(with With) *Matrix { clone.displayMetrics[c.GetName()] = key } } else { - clone.metrics = make(map[string]*Metric, 0) + clone.metrics = make(map[string]*Metric) } return clone @@ -193,7 +193,7 @@ func (m *Matrix) RemoveMetric(key string) { } func (m *Matrix) PurgeMetrics() { - m.metrics = make(map[string]*Metric, 0) + m.metrics = make(map[string]*Metric) } func (m *Matrix) RemoveExceptMetric(key string) { diff --git a/pkg/tree/xml/xml.go b/pkg/tree/xml/xml.go index 01065295b..a213cd758 100644 --- a/pkg/tree/xml/xml.go +++ b/pkg/tree/xml/xml.go @@ -1,13 +1,13 @@ /* * Copyright NetApp Inc, 2021 All rights reserved */ + package xml import ( "bytes" "encoding/xml" "github.com/netapp/harvest/v2/pkg/tree/node" - "io" ) func Load(data []byte) (*node.Node, error) { @@ -20,12 +20,6 @@ func Load(data []byte) (*node.Node, error) { return root, nil } -func LoadFromReader(r io.Reader) (*node.Node, error) { - root := new(node.Node) - dec := xml.NewDecoder(r) - return root, dec.Decode(&root) -} - func Dump(n *node.Node) ([]byte, error) { return xml.Marshal(&n) } diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index 7df9853de..de60dc7dd 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -26,6 +26,7 @@ package jsonpointer import ( + "encoding/json" "errors" "fmt" "reflect" @@ -40,6 +41,7 @@ const ( pointerSeparator = `/` invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator + notFound = `Can't find the pointer in the document` ) var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem() @@ -48,13 +50,13 @@ var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem() // JSONPointable is an interface for structs to implement when they need to customize the // json pointer process type JSONPointable interface { - JSONLookup(string) (interface{}, error) + JSONLookup(string) (any, error) } // JSONSetable is an interface for structs to implement when they need to customize the // json pointer process type JSONSetable interface { - JSONSet(string, interface{}) error + JSONSet(string, any) error } // New creates a new json pointer for the given string @@ -81,9 +83,7 @@ func (p *Pointer) parse(jsonPointerString string) error { err = errors.New(invalidStart) } else { referenceTokens := strings.Split(jsonPointerString, pointerSeparator) - for _, referenceToken := range referenceTokens[1:] { - p.referenceTokens = append(p.referenceTokens, referenceToken) - } + p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...) } } @@ -91,26 +91,26 @@ func (p *Pointer) parse(jsonPointerString string) error { } // Get uses the pointer to retrieve a value from a JSON document -func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) { +func (p *Pointer) Get(document any) (any, reflect.Kind, error) { return p.get(document, swag.DefaultJSONNameProvider) } // Set uses the pointer to set a value from a JSON document -func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) { +func (p *Pointer) Set(document any, value any) (any, error) { return document, p.set(document, value, swag.DefaultJSONNameProvider) } // GetForToken gets a value for a json pointer token 1 level deep -func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) { +func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) { return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider) } // SetForToken gets a value for a json pointer token 1 level deep -func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) { +func SetForToken(document any, decodedToken string, value any) (any, error) { return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider) } -func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { +func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() @@ -159,7 +159,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam } -func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error { +func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error { rValue := reflect.Indirect(reflect.ValueOf(node)) if ns, ok := node.(JSONSetable); ok { // pointer impl @@ -210,7 +210,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw } -func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { +func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { if nameProvider == nil { nameProvider = swag.DefaultJSONNameProvider @@ -241,7 +241,7 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf return node, kind, nil } -func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error { +func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error { knd := reflect.ValueOf(node).Kind() if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { @@ -363,6 +363,127 @@ func (p *Pointer) String() string { return pointerString } +func (p *Pointer) Offset(document string) (int64, error) { + dec := json.NewDecoder(strings.NewReader(document)) + var offset int64 + for _, ttk := range p.DecodedTokens() { + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + offset, err = offsetSingleObject(dec, ttk) + if err != nil { + return 0, err + } + case '[': + offset, err = offsetSingleArray(dec, ttk) + if err != nil { + return 0, err + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + } + return offset, nil +} + +func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { + for dec.More() { + offset := dec.InputOffset() + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err := drainSingle(dec); err != nil { + return 0, err + } + case '[': + if err := drainSingle(dec); err != nil { + return 0, err + } + } + case string: + if tk == decodedToken { + return offset, nil + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + } + return 0, fmt.Errorf("token reference %q not found", decodedToken) +} + +func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { + idx, err := strconv.Atoi(decodedToken) + if err != nil { + return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err) + } + var i int + for i = 0; i < idx && dec.More(); i++ { + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err := drainSingle(dec); err != nil { + return 0, err + } + case '[': + if err := drainSingle(dec); err != nil { + return 0, err + } + } + } + } + if !dec.More() { + return 0, fmt.Errorf("token reference %q not found", decodedToken) + } + return dec.InputOffset(), nil +} + +// drainSingle drains a single level of object or array. +// The decoder has to guarantee the begining delim (i.e. '{' or '[') has been consumed. +func drainSingle(dec *json.Decoder) error { + for dec.More() { + tk, err := dec.Token() + if err != nil { + return err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err := drainSingle(dec); err != nil { + return err + } + case '[': + if err := drainSingle(dec); err != nil { + return err + } + } + } + } + // Consumes the ending delim + if _, err := dec.Token(); err != nil { + return err + } + return nil +} + // Specific JSON pointer encoding here // ~0 => ~ // ~1 => / diff --git a/vendor/modules.txt b/vendor/modules.txt index dba59a8ee..d0abaaafa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -8,8 +8,8 @@ github.com/bbrks/wrap/v2 ## explicit; go 1.12 github.com/go-ole/go-ole github.com/go-ole/go-ole/oleutil -# github.com/go-openapi/jsonpointer v0.19.6 -## explicit; go 1.13 +# github.com/go-openapi/jsonpointer v0.20.0 +## explicit; go 1.18 github.com/go-openapi/jsonpointer # github.com/go-openapi/jsonreference v0.20.2 ## explicit; go 1.13 From 77aa4564d990b762e0569c91ca10b072de21f330 Mon Sep 17 00:00:00 2001 From: Chris Grindstaff Date: Fri, 21 Jul 2023 07:58:05 -0400 Subject: [PATCH 2/2] refactor: fix receive has generic name --- cmd/collectors/rest/plugins/qtree/qtree.go | 120 ++++++++--------- cmd/collectors/zapi/plugins/qtree/qtree.go | 150 ++++++++++----------- 2 files changed, 135 insertions(+), 135 deletions(-) diff --git a/cmd/collectors/rest/plugins/qtree/qtree.go b/cmd/collectors/rest/plugins/qtree/qtree.go index 840e0edce..3c5b3cfd5 100644 --- a/cmd/collectors/rest/plugins/qtree/qtree.go +++ b/cmd/collectors/rest/plugins/qtree/qtree.go @@ -35,7 +35,7 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { return &Qtree{AbstractPlugin: p} } -func (my *Qtree) Init() error { +func (q *Qtree) Init() error { var err error quotaMetric := []string{ @@ -53,40 +53,40 @@ func (my *Qtree) Init() error { //"threshold", # deprecated } - if err = my.InitAbc(); err != nil { + if err = q.InitAbc(); err != nil { return err } - clientTimeout := my.ParentParams.GetChildContentS("client_timeout") + clientTimeout := q.ParentParams.GetChildContentS("client_timeout") timeout, _ := time.ParseDuration(rest.DefaultTimeout) duration, err := time.ParseDuration(clientTimeout) if err == nil { timeout = duration } else { - my.Logger.Info().Str("timeout", timeout.String()).Msg("Using default timeout") + q.Logger.Info().Str("timeout", timeout.String()).Msg("Using default timeout") } - if my.client, err = rest.New(conf.ZapiPoller(my.ParentParams), timeout, my.Auth); err != nil { - my.Logger.Error().Stack().Err(err).Msg("connecting") + if q.client, err = rest.New(conf.ZapiPoller(q.ParentParams), timeout, q.Auth); err != nil { + q.Logger.Error().Stack().Err(err).Msg("connecting") return err } - if err = my.client.Init(5); err != nil { + if err = q.client.Init(5); err != nil { return err } - my.query = "api/storage/quota/reports" + q.query = "api/storage/quota/reports" - my.data = matrix.New(my.Parent+".Qtree", "quota", "quota") - my.instanceKeys = make(map[string]string) - my.instanceLabels = make(map[string]*dict.Dict) - my.historicalLabels = false + q.data = matrix.New(q.Parent+".Qtree", "quota", "quota") + q.instanceKeys = make(map[string]string) + q.instanceLabels = make(map[string]*dict.Dict) + q.historicalLabels = false - if my.Params.HasChildS("historicalLabels") { + if q.Params.HasChildS("historicalLabels") { exportOptions := node.NewS("export_options") instanceKeys := exportOptions.NewChildS("instance_keys", "") // apply all instance keys, instance labels from parent (qtree.yaml) to all quota metrics - if exportOption := my.ParentParams.GetChildS("export_options"); exportOption != nil { + if exportOption := q.ParentParams.GetChildS("export_options"); exportOption != nil { //parent instancekeys would be added in plugin metrics if parentKeys := exportOption.GetChildS("instance_keys"); parentKeys != nil { for _, parentKey := range parentKeys.GetAllChildContentS() { @@ -105,103 +105,103 @@ func (my *Qtree) Init() error { instanceKeys.NewChildS("", "index") instanceKeys.NewChildS("", "unit") - my.data.SetExportOptions(exportOptions) - my.historicalLabels = true + q.data.SetExportOptions(exportOptions) + q.historicalLabels = true } - quotaType := my.Params.GetChildS("quotaType") + quotaType := q.Params.GetChildS("quotaType") if quotaType != nil { - my.quotaType = []string{} - my.quotaType = append(my.quotaType, quotaType.GetAllChildContentS()...) + q.quotaType = []string{} + q.quotaType = append(q.quotaType, quotaType.GetAllChildContentS()...) } else { - my.quotaType = []string{"user", "group", "tree"} + q.quotaType = []string{"user", "group", "tree"} } for _, obj := range quotaMetric { metricName, display, _, _ := util.ParseMetric(obj) - metric, err := my.data.NewMetricFloat64(metricName, display) + metric, err := q.data.NewMetricFloat64(metricName, display) if err != nil { - my.Logger.Error().Stack().Err(err).Msg("add metric") + q.Logger.Error().Stack().Err(err).Msg("add metric") return err } - my.Logger.Trace().Msgf("added metric: (%s) [%s] %v", metricName, display, metric) + q.Logger.Trace().Msgf("added metric: (%s) [%s] %v", metricName, display, metric) } - my.Logger.Debug().Msgf("added data with %d metrics", len(my.data.GetMetrics())) + q.Logger.Debug().Msgf("added data with %d metrics", len(q.data.GetMetrics())) return nil } -func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { +func (q *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { var ( result []gjson.Result err error numMetrics int ) - data := dataMap[my.Object] + data := dataMap[q.Object] // Purge and reset data - my.data.PurgeInstances() - my.data.Reset() + q.data.PurgeInstances() + q.data.Reset() // Set all global labels from Rest.go if already not exist - my.data.SetGlobalLabels(data.GetGlobalLabels()) + q.data.SetGlobalLabels(data.GetGlobalLabels()) - filter := []string{"return_unmatched_nested_array_objects=true", "show_default_records=false", "type=" + strings.Join(my.quotaType[:], "|")} + filter := []string{"return_unmatched_nested_array_objects=true", "show_default_records=false", "type=" + strings.Join(q.quotaType[:], "|")} // In 22.05, all qtrees were exported - if my.historicalLabels { + if q.historicalLabels { for _, qtreeInstance := range data.GetInstances() { qtreeInstance.SetExportable(true) } // In 22.05, we would need default records as well. - filter = []string{"return_unmatched_nested_array_objects=true", "show_default_records=true", "type=" + strings.Join(my.quotaType[:], "|")} + filter = []string{"return_unmatched_nested_array_objects=true", "show_default_records=true", "type=" + strings.Join(q.quotaType[:], "|")} } - href := rest.BuildHref("", "*", filter, "", "", "", "", my.query) + href := rest.BuildHref("", "*", filter, "", "", "", "", q.query) - if result, err = collectors.InvokeRestCall(my.client, href, my.Logger); err != nil { + if result, err = collectors.InvokeRestCall(q.client, href, q.Logger); err != nil { return nil, err } quotaCount := 0 cluster, _ := data.GetGlobalLabels().GetHas("cluster") - if my.historicalLabels { + if q.historicalLabels { // In 22.05, populate metrics with qtree prefix and old labels - err = my.handlingHistoricalMetrics(result, data, cluster, "aCount, &numMetrics) + err = q.handlingHistoricalMetrics(result, data, cluster, "aCount, &numMetrics) } else { // Populate metrics with quota prefix and current labels - err = my.handlingQuotaMetrics(result, cluster, "aCount, &numMetrics) + err = q.handlingQuotaMetrics(result, cluster, "aCount, &numMetrics) } if err != nil { return nil, err } - my.Logger.Info(). + q.Logger.Info(). Int("numQuotas", quotaCount). Int("metrics", numMetrics). Msg("Collected") // metrics with qtree prefix and quota prefix are available to support backward compatibility - qtreePluginData := my.data.Clone(matrix.With{Data: true, Metrics: true, Instances: true, ExportInstances: true}) - qtreePluginData.UUID = my.Parent + ".Qtree" + qtreePluginData := q.data.Clone(matrix.With{Data: true, Metrics: true, Instances: true, ExportInstances: true}) + qtreePluginData.UUID = q.Parent + ".Qtree" qtreePluginData.Object = "qtree" qtreePluginData.Identifier = "qtree" - return []*matrix.Matrix{qtreePluginData, my.data}, nil + return []*matrix.Matrix{qtreePluginData, q.data}, nil } -func (my *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { +func (q *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { for _, quota := range result { var tree string var quotaInstance *matrix.Instance var err error if !quota.IsObject() { - my.Logger.Error().Str("type", quota.Type.String()).Msg("Quota is not an object, skipping") + q.Logger.Error().Str("type", quota.Type.String()).Msg("Quota is not an object, skipping") return errs.New(errs.ErrNoInstance, "quota is not an object") } @@ -215,25 +215,25 @@ func (my *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.M // If quota-type is not a tree, then skip if quotaType != "tree" { - my.Logger.Trace().Str("quotaType", quotaType).Msg("Quota is not tree type, skipping") + q.Logger.Trace().Str("quotaType", quotaType).Msg("Quota is not tree type, skipping") continue } // Ex. InstanceKey: vserver1vol1qtree15989279 quotaInstanceKey := vserver + volume + tree + qIndex - if quotaInstance = my.data.GetInstance(quotaInstanceKey); quotaInstance == nil { - if quotaInstance, err = my.data.NewInstance(quotaInstanceKey); err != nil { - my.Logger.Error().Stack().Err(err).Str("quotaInstanceKey", quotaInstanceKey).Msg("Failed to create quota instance") + if quotaInstance = q.data.GetInstance(quotaInstanceKey); quotaInstance == nil { + if quotaInstance, err = q.data.NewInstance(quotaInstanceKey); err != nil { + q.Logger.Error().Stack().Err(err).Str("quotaInstanceKey", quotaInstanceKey).Msg("Failed to create quota instance") return err } - my.Logger.Debug().Msgf("add (%s) quota instance: %s.%s.%s.%s", quotaInstanceKey, vserver, volume, tree, qIndex) + q.Logger.Debug().Msgf("add (%s) quota instance: %s.%s.%s.%s", quotaInstanceKey, vserver, volume, tree, qIndex) } // qtree instancekey would be qtree, svm and volume(sorted keys) qtreeInstance := data.GetInstance(tree + vserver + volume) if qtreeInstance == nil { - my.Logger.Warn(). + q.Logger.Warn(). Str("tree", tree). Str("volume", volume). Str("vserver", vserver). @@ -245,7 +245,7 @@ func (my *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.M continue } - for _, label := range my.data.GetExportOptions().GetChildS("instance_keys").GetAllChildContentS() { + for _, label := range q.data.GetExportOptions().GetChildS("instance_keys").GetAllChildContentS() { if value := qtreeInstance.GetLabel(label); value != "" { quotaInstance.SetLabel(label, value) } @@ -264,7 +264,7 @@ func (my *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.M } *quotaIndex++ - for attribute, m := range my.data.GetMetrics() { + for attribute, m := range q.data.GetMetrics() { value := 0.0 if attrValue := quota.Get(attribute); attrValue.Exists() { @@ -279,22 +279,22 @@ func (my *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.M // populate numeric data if err = m.SetValueFloat64(quotaInstance, value); err != nil { - my.Logger.Error().Stack().Err(err).Str("attribute", attribute).Float64("value", value).Msg("Failed to parse value") + q.Logger.Error().Stack().Err(err).Str("attribute", attribute).Float64("value", value).Msg("Failed to parse value") } else { *numMetrics++ - my.Logger.Debug().Str("attribute", attribute).Float64("value", value).Msg("added value") + q.Logger.Debug().Str("attribute", attribute).Float64("value", value).Msg("added value") } } } return nil } -func (my *Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quotaCount *int, numMetrics *int) error { +func (q *Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quotaCount *int, numMetrics *int) error { for quotaIndex, quota := range result { var tree string if !quota.IsObject() { - my.Logger.Error().Str("type", quota.Type.String()).Msg("Quota is not an object, skipping") + q.Logger.Error().Str("type", quota.Type.String()).Msg("Quota is not an object, skipping") return errs.New(errs.ErrNoInstance, "quota is not an object") } @@ -309,15 +309,15 @@ func (my *Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quo group := quota.Get("group.name").String() *quotaCount++ - for attribute, m := range my.data.GetMetrics() { + for attribute, m := range q.data.GetMetrics() { // set -1 for unlimited value := -1.0 quotaInstanceKey := strconv.Itoa(quotaIndex) + "." + attribute - quotaInstance, err := my.data.NewInstance(quotaInstanceKey) + quotaInstance, err := q.data.NewInstance(quotaInstanceKey) if err != nil { - my.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) + q.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) return err } //set labels @@ -352,10 +352,10 @@ func (my *Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quo // populate numeric data if err = m.SetValueFloat64(quotaInstance, value); err != nil { - my.Logger.Error().Stack().Err(err).Str("attribute", attribute).Float64("value", value).Msg("Failed to parse value") + q.Logger.Error().Stack().Err(err).Str("attribute", attribute).Float64("value", value).Msg("Failed to parse value") } else { *numMetrics++ - my.Logger.Trace().Str("attribute", attribute).Float64("value", value).Msg("added value") + q.Logger.Trace().Str("attribute", attribute).Float64("value", value).Msg("added value") } } } diff --git a/cmd/collectors/zapi/plugins/qtree/qtree.go b/cmd/collectors/zapi/plugins/qtree/qtree.go index ddabda1c6..999f04944 100644 --- a/cmd/collectors/zapi/plugins/qtree/qtree.go +++ b/cmd/collectors/zapi/plugins/qtree/qtree.go @@ -35,41 +35,41 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { return &Qtree{AbstractPlugin: p} } -func (my *Qtree) Init() error { +func (q *Qtree) Init() error { var err error - if err = my.InitAbc(); err != nil { + if err = q.InitAbc(); err != nil { return err } - if my.client, err = zapi.New(conf.ZapiPoller(my.ParentParams), my.Auth); err != nil { - my.Logger.Error().Stack().Err(err).Msg("connecting") + if q.client, err = zapi.New(conf.ZapiPoller(q.ParentParams), q.Auth); err != nil { + q.Logger.Error().Stack().Err(err).Msg("connecting") return err } - if err = my.client.Init(5); err != nil { + if err = q.client.Init(5); err != nil { return err } - if my.client.IsClustered() { - my.query = "quota-report-iter" + if q.client.IsClustered() { + q.query = "quota-report-iter" } else { - my.query = "quota-report" + q.query = "quota-report" } - my.Logger.Debug().Msg("plugin connected!") + q.Logger.Debug().Msg("plugin connected!") - my.data = matrix.New(my.Parent+".Qtree", "quota", "quota") - my.instanceKeys = make(map[string]string) - my.instanceLabels = make(map[string]*dict.Dict) - my.historicalLabels = false + q.data = matrix.New(q.Parent+".Qtree", "quota", "quota") + q.instanceKeys = make(map[string]string) + q.instanceLabels = make(map[string]*dict.Dict) + q.historicalLabels = false - if my.Params.HasChildS("historicalLabels") { + if q.Params.HasChildS("historicalLabels") { exportOptions := node.NewS("export_options") instanceKeys := exportOptions.NewChildS("instance_keys", "") // apply all instance keys, instance labels from parent (qtree.yaml) to all quota metrics - if exportOption := my.ParentParams.GetChildS("export_options"); exportOption != nil { + if exportOption := q.ParentParams.GetChildS("export_options"); exportOption != nil { //parent instancekeys would be added in plugin metrics if parentKeys := exportOption.GetChildS("instance_keys"); parentKeys != nil { for _, parentKey := range parentKeys.GetAllChildContentS() { @@ -88,19 +88,19 @@ func (my *Qtree) Init() error { instanceKeys.NewChildS("", "index") instanceKeys.NewChildS("", "unit") - my.data.SetExportOptions(exportOptions) - my.historicalLabels = true + q.data.SetExportOptions(exportOptions) + q.historicalLabels = true } - quotaType := my.Params.GetChildS("quotaType") + quotaType := q.Params.GetChildS("quotaType") if quotaType != nil { - my.quotaType = []string{} - my.quotaType = append(my.quotaType, quotaType.GetAllChildContentS()...) + q.quotaType = []string{} + q.quotaType = append(q.quotaType, quotaType.GetAllChildContentS()...) } else { - my.quotaType = []string{"user", "group", "tree"} + q.quotaType = []string{"user", "group", "tree"} } - objects := my.Params.GetChildS("objects") + objects := q.Params.GetChildS("objects") if objects == nil { return errs.New(errs.ErrMissingParam, "objects") } @@ -109,23 +109,23 @@ func (my *Qtree) Init() error { metricName, display, _, _ := util.ParseMetric(obj) - metric, err := my.data.NewMetricFloat64(metricName, display) + metric, err := q.data.NewMetricFloat64(metricName, display) if err != nil { - my.Logger.Error().Stack().Err(err).Msg("add metric") + q.Logger.Error().Stack().Err(err).Msg("add metric") return err } - my.Logger.Debug().Msgf("added metric: (%s) [%s] %v", metricName, display, metric) + q.Logger.Debug().Msgf("added metric: (%s) [%s] %v", metricName, display, metric) } - my.Logger.Debug().Msgf("added data with %d metrics", len(my.data.GetMetrics())) + q.Logger.Debug().Msgf("added data with %d metrics", len(q.data.GetMetrics())) // setup batchSize for request - my.batchSize = BatchSize - if my.client.IsClustered() { - if b := my.Params.GetChildContentS("batch_size"); b != "" { + q.batchSize = BatchSize + if q.client.IsClustered() { + if b := q.Params.GetChildContentS("batch_size"); b != "" { if _, err := strconv.Atoi(b); err == nil { - my.batchSize = b + q.batchSize = b } } } @@ -133,7 +133,7 @@ func (my *Qtree) Init() error { return nil } -func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { +func (q *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { var ( request, response *node.Node quotas []*node.Node @@ -142,32 +142,32 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error numMetrics int ) - data := dataMap[my.Object] + data := dataMap[q.Object] apiT := 0 * time.Second parseT := 0 * time.Second // Purge and reset data - my.data.PurgeInstances() - my.data.Reset() + q.data.PurgeInstances() + q.data.Reset() // Set all global labels from zapi.go if already not exist - my.data.SetGlobalLabels(data.GetGlobalLabels()) + q.data.SetGlobalLabels(data.GetGlobalLabels()) - request = node.NewXMLS(my.query) + request = node.NewXMLS(q.query) - if my.client.IsClustered() && my.batchSize != "" { - request.NewChildS("max-records", my.batchSize) + if q.client.IsClustered() && q.batchSize != "" { + request.NewChildS("max-records", q.batchSize) // add quota filter query := request.NewChildS("query", "") quotaQuery := query.NewChildS("quota", "") - quotaQuery.NewChildS("quota-type", strings.Join(my.quotaType[:], "|")) + quotaQuery.NewChildS("quota-type", strings.Join(q.quotaType[:], "|")) } tag := "initial" quotaIndex := 0 // In 22.05, all qtrees were exported - if my.historicalLabels { + if q.historicalLabels { for _, qtreeInstance := range data.GetInstances() { qtreeInstance.SetExportable(true) } @@ -176,7 +176,7 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error cluster, _ := data.GetGlobalLabels().GetHas("cluster") for { - response, tag, ad, pd, err = my.client.InvokeBatchWithTimers(request, tag) + response, tag, ad, pd, err = q.client.InvokeBatchWithTimers(request, tag) if err != nil { return nil, err @@ -189,7 +189,7 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error apiT += ad parseT += pd - if my.client.IsClustered() { + if q.client.IsClustered() { if x := response.GetChildS("attributes-list"); x != nil { quotas = x.GetChildren() } @@ -198,18 +198,18 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error } if len(quotas) == 0 { - my.Logger.Debug().Msg("no quota instances found") + q.Logger.Debug().Msg("no quota instances found") return nil, nil } - my.Logger.Debug().Int("quotas", len(quotas)).Msg("fetching quotas") + q.Logger.Debug().Int("quotas", len(quotas)).Msg("fetching quotas") - if my.historicalLabels { + if q.historicalLabels { // In 22.05, populate metrics with qtree prefix and old labels - err = my.handlingHistoricalMetrics(quotas, data, cluster, "aIndex, &numMetrics) + err = q.handlingHistoricalMetrics(quotas, data, cluster, "aIndex, &numMetrics) } else { // Populate metrics with quota prefix and current labels - err = my.handlingQuotaMetrics(quotas, cluster, "aIndex, &numMetrics) + err = q.handlingQuotaMetrics(quotas, cluster, "aIndex, &numMetrics) } if err != nil { @@ -217,23 +217,23 @@ func (my *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error } } - my.Logger.Info(). + q.Logger.Info(). Int("numQuotas", quotaIndex). Int("metrics", numMetrics). Str("apiD", apiT.Round(time.Millisecond).String()). Str("parseD", parseT.Round(time.Millisecond).String()). - Str("batchSize", my.batchSize). + Str("batchSize", q.batchSize). Msg("Collected") // metrics with qtree prefix and quota prefix are available to support backward compatibility - qtreePluginData := my.data.Clone(matrix.With{Data: true, Metrics: true, Instances: true, ExportInstances: true}) - qtreePluginData.UUID = my.Parent + ".Qtree" + qtreePluginData := q.data.Clone(matrix.With{Data: true, Metrics: true, Instances: true, ExportInstances: true}) + qtreePluginData.UUID = q.Parent + ".Qtree" qtreePluginData.Object = "qtree" qtreePluginData.Identifier = "qtree" - return []*matrix.Matrix{qtreePluginData, my.data}, nil + return []*matrix.Matrix{qtreePluginData, q.data}, nil } -func (my *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { +func (q *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Matrix, cluster string, quotaIndex *int, numMetrics *int) error { for qIndex, quota := range quotas { var vserver, quotaInstanceKey string var qtreeInstance *matrix.Instance @@ -241,12 +241,12 @@ func (my *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Mat quotaType := quota.GetChildContentS("quota-type") tree := quota.GetChildContentS("tree") volume := quota.GetChildContentS("volume") - if my.client.IsClustered() { + if q.client.IsClustered() { vserver = quota.GetChildContentS("vserver") } *quotaIndex++ - for attribute, m := range my.data.GetMetrics() { + for attribute, m := range q.data.GetMetrics() { objectElem := quota.GetChildS(attribute) if objectElem == nil { @@ -254,13 +254,13 @@ func (my *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Mat } if attrValue := quota.GetChildContentS(attribute); attrValue != "" { - if my.client.IsClustered() { + if q.client.IsClustered() { qtreeInstance = data.GetInstance(tree + "." + volume + "." + vserver) } else { qtreeInstance = data.GetInstance(volume + "." + tree) } if qtreeInstance == nil { - my.Logger.Warn(). + q.Logger.Warn(). Str("tree", tree). Str("volume", volume). Str("vserver", vserver). @@ -271,21 +271,21 @@ func (my *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Mat continue } // Ex. InstanceKey: SVMA.vol1Abc.qtree1.5.disk-limit - if my.client.IsClustered() { + if q.client.IsClustered() { quotaInstanceKey = vserver + "." + volume + "." + tree + "." + strconv.Itoa(qIndex) + "." + attribute } else { quotaInstanceKey = volume + "." + tree + "." + strconv.Itoa(qIndex) + "." + attribute } - quotaInstance, err := my.data.NewInstance(quotaInstanceKey) + quotaInstance, err := q.data.NewInstance(quotaInstanceKey) if err != nil { - my.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) + q.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) return err } - my.Logger.Debug().Msgf("add (%s) instance: %s.%s.%s", attribute, vserver, volume, tree) + q.Logger.Debug().Msgf("add (%s) instance: %s.%s.%s", attribute, vserver, volume, tree) - for _, label := range my.data.GetExportOptions().GetChildS("instance_keys").GetAllChildContentS() { + for _, label := range q.data.GetExportOptions().GetChildS("instance_keys").GetAllChildContentS() { if value := qtreeInstance.GetLabel(label); value != "" { quotaInstance.SetLabel(label, value) } @@ -313,29 +313,29 @@ func (my *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Mat quotaInstance.SetLabel("unit", "Kbyte") } if err := m.SetValueString(quotaInstance, value); err != nil { - my.Logger.Debug().Msgf("(%s) failed to parse value (%s): %v", attribute, value, err) + q.Logger.Debug().Msgf("(%s) failed to parse value (%s): %v", attribute, value, err) } else { *numMetrics++ - my.Logger.Debug().Msgf("(%s) added value (%s)", attribute, value) + q.Logger.Debug().Msgf("(%s) added value (%s)", attribute, value) } } } else { - my.Logger.Debug().Msgf("instance without [%s], skipping", attribute) + q.Logger.Debug().Msgf("instance without [%s], skipping", attribute) } } } return nil } -func (my *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quotaIndex *int, numMetrics *int) error { +func (q *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quotaIndex *int, numMetrics *int) error { for _, quota := range quotas { var vserver, quotaInstanceKey, uid, uName string quotaType := quota.GetChildContentS("quota-type") tree := quota.GetChildContentS("tree") volume := quota.GetChildContentS("volume") - if my.client.IsClustered() { + if q.client.IsClustered() { vserver = quota.GetChildContentS("vserver") } @@ -365,7 +365,7 @@ func (my *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quota } *quotaIndex++ - for attribute, m := range my.data.GetMetrics() { + for attribute, m := range q.data.GetMetrics() { objectElem := quota.GetChildS(attribute) if objectElem == nil { @@ -375,14 +375,14 @@ func (my *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quota if attrValue := quota.GetChildContentS(attribute); attrValue != "" { // Ex. InstanceKey: SVMA.vol1Abc.qtree1.5.disk-limit - if my.client.IsClustered() { + if q.client.IsClustered() { quotaInstanceKey = vserver + "." + volume + "." + tree + "." + strconv.Itoa(*quotaIndex) + "." + attribute } else { quotaInstanceKey = volume + "." + tree + "." + strconv.Itoa(*quotaIndex) + "." + attribute } - quotaInstance, err := my.data.NewInstance(quotaInstanceKey) + quotaInstance, err := q.data.NewInstance(quotaInstanceKey) if err != nil { - my.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) + q.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) return err } //set labels @@ -406,7 +406,7 @@ func (my *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quota } } - my.Logger.Debug().Msgf("add (%s) instance: %s.%s.%s", attribute, vserver, volume, tree) + q.Logger.Debug().Msgf("add (%s) instance: %s.%s.%s", attribute, vserver, volume, tree) // populate numeric data if value := strings.Split(attrValue, " ")[0]; value != "" { @@ -419,14 +419,14 @@ func (my *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quota quotaInstance.SetLabel("unit", "Kbyte") } if err := m.SetValueString(quotaInstance, value); err != nil { - my.Logger.Debug().Msgf("(%s) failed to parse value (%s): %v", attribute, value, err) + q.Logger.Debug().Msgf("(%s) failed to parse value (%s): %v", attribute, value, err) } else { *numMetrics++ - my.Logger.Debug().Msgf("(%s) added value (%s)", attribute, value) + q.Logger.Debug().Msgf("(%s) added value (%s)", attribute, value) } } } else { - my.Logger.Debug().Msgf("instance without [%s], skipping", attribute) + q.Logger.Debug().Msgf("instance without [%s], skipping", attribute) } } }