From c04054af83f2ceffffa659351d02e4cd51858789 Mon Sep 17 00:00:00 2001 From: Chris Grindstaff Date: Mon, 2 Oct 2023 15:07:59 -0400 Subject: [PATCH] perf: remove extra dict wrapper Reduces matrix size and removes unnecessary indirection --- cmd/collectors/power.go | 5 +- .../rest/plugins/netroute/netroute.go | 2 +- cmd/collectors/rest/plugins/qtree/qtree.go | 17 ++- .../securityaccount/securityaccount.go | 2 +- .../rest/plugins/snapmirror/snapmirror.go | 6 +- cmd/collectors/rest/plugins/volume/volume.go | 2 +- .../volumeanalytics/volumeanalytics.go | 4 +- cmd/collectors/restperf/plugins/disk/disk.go | 15 ++- .../restperf/plugins/volume/volume.go | 9 +- cmd/collectors/restperf/restperf.go | 10 +- cmd/collectors/sensor_test.go | 3 +- cmd/collectors/zapi/plugins/qtree/qtree.go | 13 +-- cmd/collectors/zapi/plugins/shelf/shelf.go | 13 +-- .../zapi/plugins/snapmirror/snapmirror.go | 2 +- cmd/collectors/zapiperf/plugins/disk/disk.go | 13 +-- .../externalserviceoperation.go | 2 +- .../zapiperf/plugins/volume/volume.go | 13 ++- cmd/collectors/zapiperf/zapiperf.go | 50 +++++--- cmd/exporters/influxdb/influxdb.go | 12 +- cmd/exporters/prometheus/prometheus.go | 11 +- cmd/poller/plugin/aggregator/aggregator.go | 9 +- cmd/poller/plugin/labelagent/label_agent.go | 13 ++- .../plugin/labelagent/label_agent_test.go | 25 ++-- cmd/poller/plugin/max/max.go | 10 +- go.mod | 1 + go.sum | 29 +---- integration/go.mod | 12 +- integration/go.sum | 31 +++-- pkg/dict/dict.go | 109 ++---------------- pkg/dict/dict_test.go | 28 +++++ pkg/matrix/instance.go | 18 +-- pkg/matrix/matrix.go | 22 ++-- pkg/matrix/metric.go | 20 ++-- vendor/modules.txt | 3 + 34 files changed, 241 insertions(+), 293 deletions(-) create mode 100644 pkg/dict/dict_test.go diff --git a/cmd/collectors/power.go b/cmd/collectors/power.go index 647f7309d..30728672f 100644 --- a/cmd/collectors/power.go +++ b/cmd/collectors/power.go @@ -5,7 +5,6 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/cmd/tools/rest" "github.com/netapp/harvest/v2/pkg/conf" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/logging" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/util" @@ -384,7 +383,7 @@ type Sensor struct { data *matrix.Matrix client *rest.Client instanceKeys map[string]string - instanceLabels map[string]*dict.Dict + instanceLabels map[string]map[string]string } func (my *Sensor) Init() error { @@ -406,7 +405,7 @@ func (my *Sensor) Init() error { my.data = matrix.New(my.Parent+".Sensor", "environment_sensor", "environment_sensor") my.instanceKeys = make(map[string]string) - my.instanceLabels = make(map[string]*dict.Dict) + my.instanceLabels = make(map[string]map[string]string) // init environment metrics in plugin matrix // create environment metric if not exists diff --git a/cmd/collectors/rest/plugins/netroute/netroute.go b/cmd/collectors/rest/plugins/netroute/netroute.go index 791f601b4..6234ff58a 100644 --- a/cmd/collectors/rest/plugins/netroute/netroute.go +++ b/cmd/collectors/rest/plugins/netroute/netroute.go @@ -67,7 +67,7 @@ func (n *NetRoute) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, err count := 0 for key, instance := range data.GetInstances() { - cluster := data.GetGlobalLabels().Get("cluster") + cluster := data.GetGlobalLabels()["cluster"] routeID := instance.GetLabel("uuid") interfaceName := instance.GetLabel("interface_name") interfaceAddress := instance.GetLabel("interface_address") diff --git a/cmd/collectors/rest/plugins/qtree/qtree.go b/cmd/collectors/rest/plugins/qtree/qtree.go index 3c5b3cfd5..cf780cbeb 100644 --- a/cmd/collectors/rest/plugins/qtree/qtree.go +++ b/cmd/collectors/rest/plugins/qtree/qtree.go @@ -9,7 +9,6 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/cmd/tools/rest" "github.com/netapp/harvest/v2/pkg/conf" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree/node" @@ -24,7 +23,7 @@ type Qtree struct { *plugin.AbstractPlugin data *matrix.Matrix instanceKeys map[string]string - instanceLabels map[string]*dict.Dict + instanceLabels map[string]map[string]string client *rest.Client query string quotaType []string @@ -44,13 +43,13 @@ func (q *Qtree) Init() error { "space.used.hard_limit_percent => disk_used_pct_disk_limit", "space.used.soft_limit_percent => disk_used_pct_soft_disk_limit", "space.soft_limit => soft_disk_limit", - //"disk-used-pct-threshold" # deprecated and workaround to use same as disk_used_pct_soft_disk_limit + // "disk-used-pct-threshold" # deprecated and workaround to use same as disk_used_pct_soft_disk_limit "files.hard_limit => file_limit", "files.used.total => files_used", "files.used.hard_limit_percent => files_used_pct_file_limit", "files.used.soft_limit_percent => files_used_pct_soft_file_limit", "files.soft_limit => soft_file_limit", - //"threshold", # deprecated + // "threshold", # deprecated } if err = q.InitAbc(); err != nil { @@ -78,7 +77,7 @@ func (q *Qtree) Init() error { q.data = matrix.New(q.Parent+".Qtree", "quota", "quota") q.instanceKeys = make(map[string]string) - q.instanceLabels = make(map[string]*dict.Dict) + q.instanceLabels = make(map[string]map[string]string) q.historicalLabels = false if q.Params.HasChildS("historicalLabels") { @@ -87,7 +86,7 @@ func (q *Qtree) Init() error { // apply all instance keys, instance labels from parent (qtree.yaml) to all quota metrics if exportOption := q.ParentParams.GetChildS("export_options"); exportOption != nil { - //parent instancekeys would be added in plugin metrics + // parent instancekeys would be added in plugin metrics if parentKeys := exportOption.GetChildS("instance_keys"); parentKeys != nil { for _, parentKey := range parentKeys.GetAllChildContentS() { instanceKeys.NewChildS("", parentKey) @@ -167,7 +166,7 @@ func (q *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) } quotaCount := 0 - cluster, _ := data.GetGlobalLabels().GetHas("cluster") + cluster := data.GetGlobalLabels()["cluster"] if q.historicalLabels { // In 22.05, populate metrics with qtree prefix and old labels @@ -251,7 +250,7 @@ func (q *Qtree) handlingHistoricalMetrics(result []gjson.Result, data *matrix.Ma } } - //set labels + // set labels quotaInstance.SetLabel("type", quotaType) quotaInstance.SetLabel("qtree", tree) quotaInstance.SetLabel("volume", volume) @@ -320,7 +319,7 @@ func (q *Qtree) handlingQuotaMetrics(result []gjson.Result, cluster string, quot q.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) return err } - //set labels + // set labels quotaInstance.SetLabel("type", quotaType) quotaInstance.SetLabel("qtree", tree) quotaInstance.SetLabel("volume", volume) diff --git a/cmd/collectors/rest/plugins/securityaccount/securityaccount.go b/cmd/collectors/rest/plugins/securityaccount/securityaccount.go index 96c7f9909..6ab0797a7 100644 --- a/cmd/collectors/rest/plugins/securityaccount/securityaccount.go +++ b/cmd/collectors/rest/plugins/securityaccount/securityaccount.go @@ -103,7 +103,7 @@ func (s *SecurityAccount) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matr return nil, err } - for k, v := range securityAccountInstance.GetLabels().Map() { + for k, v := range securityAccountInstance.GetLabels() { securityAccountNewInstance.SetLabel(k, v) } securityAccountNewInstance.SetLabel("applications", application) diff --git a/cmd/collectors/rest/plugins/snapmirror/snapmirror.go b/cmd/collectors/rest/plugins/snapmirror/snapmirror.go index 2e9bd27ce..b6efab821 100644 --- a/cmd/collectors/rest/plugins/snapmirror/snapmirror.go +++ b/cmd/collectors/rest/plugins/snapmirror/snapmirror.go @@ -91,7 +91,7 @@ func (my *SnapMirror) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, if my.currentVal >= PluginInvocationRate { my.currentVal = 0 - if cluster, ok := data.GetGlobalLabels().GetHas("cluster"); ok { + if cluster, ok := data.GetGlobalLabels()["cluster"]; ok { if err := my.getSVMPeerData(cluster); err != nil { return nil, err } @@ -135,7 +135,7 @@ func (my *SnapMirror) getSVMPeerData(cluster string) error { func (my *SnapMirror) updateSMLabels(data *matrix.Matrix) { var keys []string - cluster, _ := data.GetGlobalLabels().GetHas("cluster") + cluster := data.GetGlobalLabels()["cluster"] lastTransferSizeMetric := data.GetMetric("last_transfer_size") lagTimeMetric := data.GetMetric("lag_time") @@ -204,7 +204,7 @@ func (my *SnapMirror) handleCGRelationships(data *matrix.Matrix, keys []string) continue } - for k, v := range cgInstance.GetLabels().Map() { + for k, v := range cgInstance.GetLabels() { cgVolumeInstance.SetLabel(k, v) } cgVolumeInstance.SetLabel("relationship_id", cgVolumeInstanceKey) diff --git a/cmd/collectors/rest/plugins/volume/volume.go b/cmd/collectors/rest/plugins/volume/volume.go index 966dc6df1..d57e4c19b 100644 --- a/cmd/collectors/rest/plugins/volume/volume.go +++ b/cmd/collectors/rest/plugins/volume/volume.go @@ -165,7 +165,7 @@ func (my *Volume) handleARWProtection(data *matrix.Matrix) { } } - arwInstanceKey := data.GetGlobalLabels().Get("cluster") + data.GetGlobalLabels().Get("datacenter") + arwInstanceKey := data.GetGlobalLabels()["cluster"] + data.GetGlobalLabels()["datacenter"] if arwInstance, err = my.arw.NewInstance(arwInstanceKey); err != nil { my.Logger.Error().Err(err).Str("arwInstanceKey", arwInstanceKey).Msg("Failed to create arw instance") return diff --git a/cmd/collectors/rest/plugins/volumeanalytics/volumeanalytics.go b/cmd/collectors/rest/plugins/volumeanalytics/volumeanalytics.go index 1b24d7312..d89a3e14a 100644 --- a/cmd/collectors/rest/plugins/volumeanalytics/volumeanalytics.go +++ b/cmd/collectors/rest/plugins/volumeanalytics/volumeanalytics.go @@ -88,7 +88,7 @@ func (v *VolumeAnalytics) initMatrix() error { func (v *VolumeAnalytics) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { data := dataMap[v.Object] - cluster, _ := data.GetGlobalLabels().GetHas("cluster") + cluster := data.GetGlobalLabels()["cluster"] clusterVersion := v.client.Cluster().GetVersion() ontapVersion, err := goversion.NewVersion(clusterVersion) if err != nil { @@ -152,7 +152,7 @@ func (v *VolumeAnalytics) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matr instance.SetLabel("dir_name", name) instance.SetLabel("index", cluster+"_"+strconv.Itoa(index)) // copy all labels - for k1, v1 := range dataInstance.GetLabels().Map() { + for k1, v1 := range dataInstance.GetLabels() { instance.SetLabel(k1, v1) } if bytesUsed != "" { diff --git a/cmd/collectors/restperf/plugins/disk/disk.go b/cmd/collectors/restperf/plugins/disk/disk.go index 5cc2a6b4d..6d586df6f 100644 --- a/cmd/collectors/restperf/plugins/disk/disk.go +++ b/cmd/collectors/restperf/plugins/disk/disk.go @@ -4,7 +4,6 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/cmd/tools/rest" "github.com/netapp/harvest/v2/pkg/conf" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree/node" @@ -44,7 +43,7 @@ type Disk struct { shelfData map[string]*matrix.Matrix powerData map[string]*matrix.Matrix instanceKeys map[string]string - instanceLabels map[string]*dict.Dict + instanceLabels map[string]map[string]string client *rest.Client query string aggrMap map[string]*aggregate @@ -169,7 +168,7 @@ func (d *Disk) Init() error { d.powerData = make(map[string]*matrix.Matrix) d.instanceKeys = make(map[string]string) - d.instanceLabels = make(map[string]*dict.Dict) + d.instanceLabels = make(map[string]map[string]string) for attribute, childObj := range shelfMetric { @@ -180,7 +179,7 @@ func (d *Disk) Init() error { objectName = strings.TrimSpace(x[1]) } - d.instanceLabels[attribute] = dict.New() + d.instanceLabels[attribute] = make(map[string]string) d.shelfData[attribute] = matrix.New(d.Parent+".Shelf", "shelf_"+objectName, "shelf_"+objectName) d.shelfData[attribute].SetGlobalLabel("datacenter", d.ParentParams.GetChildContentS("datacenter")) @@ -201,11 +200,11 @@ func (d *Disk) Init() error { switch kind { case "key": d.instanceKeys[attribute] = metricName - d.instanceLabels[attribute].Set(metricName, display) + d.instanceLabels[attribute][metricName] = display instanceKeys.NewChildS("", display) d.Logger.Debug().Msgf("added instance key: (%s) [%s]", attribute, display) case "label": - d.instanceLabels[attribute].Set(metricName, display) + d.instanceLabels[attribute][metricName] = display instanceLabels.NewChildS("", display) d.Logger.Debug().Msgf("added instance label: (%s) [%s]", attribute, display) case "float": @@ -305,7 +304,7 @@ func (d *Disk) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) } d.Logger.Debug().Msgf("add (%s) instance: %s.%s.%s", attribute, shelfSerialNumber, attribute, key) - for label, labelDisplay := range d.instanceLabels[attribute].Map() { + for label, labelDisplay := range d.instanceLabels[attribute] { if value := obj.Get(label); value.Exists() { if value.IsArray() { var labelArray []string @@ -331,7 +330,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 an ugly way to write all of them, - // so normal value would be mapped to 1 and rest all are mapped to 0. + // so normal value would be mapped to 1, and the rest all are mapped to 0. if shelfChildInstance.GetLabel("status") == "normal" { _ = statusMetric.SetValueInt64(shelfChildInstance, 1) } else { diff --git a/cmd/collectors/restperf/plugins/volume/volume.go b/cmd/collectors/restperf/plugins/volume/volume.go index 1ab572bc9..17568ba84 100644 --- a/cmd/collectors/restperf/plugins/volume/volume.go +++ b/cmd/collectors/restperf/plugins/volume/volume.go @@ -4,6 +4,7 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/set" + "maps" "regexp" "sort" "strings" @@ -67,7 +68,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error key := i.GetLabel("svm") + "." + match[1] if cache.GetInstance(key) == nil { fg, _ := cache.NewInstance(key) - fg.SetLabels(i.GetLabels().Copy()) + fg.SetLabels(maps.Clone(i.GetLabels())) fg.SetLabel("volume", match[1]) // Flexgroup don't show any aggregate, node fg.SetLabel("aggr", "") @@ -77,7 +78,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error if volumeAggrmetric.GetInstance(key) == nil { flexgroupInstance, _ := volumeAggrmetric.NewInstance(key) - flexgroupInstance.SetLabels(i.GetLabels().Copy()) + flexgroupInstance.SetLabels(maps.Clone(i.GetLabels())) flexgroupInstance.SetLabel("volume", match[1]) // Flexgroup don't show any node flexgroupInstance.SetLabel("node", "") @@ -98,7 +99,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error v.Logger.Error().Err(err).Str("key", key).Msg("Failed to create new instance") continue } - flexvolInstance.SetLabels(i.GetLabels().Copy()) + flexvolInstance.SetLabels(maps.Clone(i.GetLabels())) flexvolInstance.SetLabel(style, "flexvol") if err := metric.SetValueFloat64(flexvolInstance, 1); err != nil { v.Logger.Error().Err(err).Str("metric", metricName).Msg("Unable to set value on metric") @@ -108,7 +109,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error v.Logger.Debug().Int("flexgroup volume count", len(cache.GetInstances())).Msg("") - //cache.Reset() + // cache.Reset() // create summary for _, i := range data.GetInstances() { diff --git a/cmd/collectors/restperf/restperf.go b/cmd/collectors/restperf/restperf.go index e398e818a..60a05be31 100644 --- a/cmd/collectors/restperf/restperf.go +++ b/cmd/collectors/restperf/restperf.go @@ -16,11 +16,13 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/cmd/tools/rest" "github.com/netapp/harvest/v2/pkg/color" + "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/set" "github.com/netapp/harvest/v2/pkg/tree/node" "github.com/netapp/harvest/v2/pkg/util" + "github.com/rs/zerolog" "github.com/tidwall/gjson" "path" "strconv" @@ -1450,7 +1452,13 @@ func (r *RestPerf) updateQosLabels(qos gjson.Result, instance *matrix.Instance, r.Logger.Trace().Str("label", label).Str("key", key).Msg("Missing label") } } - r.Logger.Debug().Str("query", r.Prop.Query).Str("key", key).Str("qos labels", instance.GetLabels().String()).Send() + if r.Logger.GetLevel() == zerolog.DebugLevel { + r.Logger.Debug(). + Str("query", r.Prop.Query). + Str("key", key). + Str("qos labels", dict.String(instance.GetLabels())). + Send() + } } } diff --git a/cmd/collectors/sensor_test.go b/cmd/collectors/sensor_test.go index 6dd70c09d..9b233f23d 100644 --- a/cmd/collectors/sensor_test.go +++ b/cmd/collectors/sensor_test.go @@ -3,7 +3,6 @@ package collectors import ( "fmt" "github.com/netapp/harvest/v2/cmd/poller/plugin" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/logging" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree" @@ -94,7 +93,7 @@ func loadTestdata() { sensor.data = matrix.New("Sensor", "environment_sensor", "environment_sensor") sensor.instanceKeys = make(map[string]string) - sensor.instanceLabels = make(map[string]*dict.Dict) + sensor.instanceLabels = make(map[string]map[string]string) sensor.AbstractPlugin.Logger = logging.Get() for _, k := range eMetrics { diff --git a/cmd/collectors/zapi/plugins/qtree/qtree.go b/cmd/collectors/zapi/plugins/qtree/qtree.go index 999f04944..af8cfac88 100644 --- a/cmd/collectors/zapi/plugins/qtree/qtree.go +++ b/cmd/collectors/zapi/plugins/qtree/qtree.go @@ -6,7 +6,6 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/pkg/api/ontapi/zapi" "github.com/netapp/harvest/v2/pkg/conf" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree/node" @@ -23,7 +22,7 @@ type Qtree struct { *plugin.AbstractPlugin data *matrix.Matrix instanceKeys map[string]string - instanceLabels map[string]*dict.Dict + instanceLabels map[string]map[string]string batchSize string client *zapi.Client query string @@ -61,7 +60,7 @@ func (q *Qtree) Init() error { q.data = matrix.New(q.Parent+".Qtree", "quota", "quota") q.instanceKeys = make(map[string]string) - q.instanceLabels = make(map[string]*dict.Dict) + q.instanceLabels = make(map[string]map[string]string) q.historicalLabels = false if q.Params.HasChildS("historicalLabels") { @@ -70,7 +69,7 @@ func (q *Qtree) Init() error { // apply all instance keys, instance labels from parent (qtree.yaml) to all quota metrics if exportOption := q.ParentParams.GetChildS("export_options"); exportOption != nil { - //parent instancekeys would be added in plugin metrics + // parent instancekeys would be added in plugin metrics if parentKeys := exportOption.GetChildS("instance_keys"); parentKeys != nil { for _, parentKey := range parentKeys.GetAllChildContentS() { instanceKeys.NewChildS("", parentKey) @@ -173,7 +172,7 @@ func (q *Qtree) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) } } - cluster, _ := data.GetGlobalLabels().GetHas("cluster") + cluster := data.GetGlobalLabels()["cluster"] for { response, tag, ad, pd, err = q.client.InvokeBatchWithTimers(request, tag) @@ -291,7 +290,7 @@ func (q *Qtree) handlingHistoricalMetrics(quotas []*node.Node, data *matrix.Matr } } - //set labels + // set labels quotaInstance.SetLabel("type", quotaType) quotaInstance.SetLabel("qtree", tree) quotaInstance.SetLabel("volume", volume) @@ -385,7 +384,7 @@ func (q *Qtree) handlingQuotaMetrics(quotas []*node.Node, cluster string, quotaI q.Logger.Debug().Msgf("add (%s) instance: %v", attribute, err) return err } - //set labels + // set labels quotaInstance.SetLabel("type", quotaType) quotaInstance.SetLabel("qtree", tree) quotaInstance.SetLabel("volume", volume) diff --git a/cmd/collectors/zapi/plugins/shelf/shelf.go b/cmd/collectors/zapi/plugins/shelf/shelf.go index 0971326fa..6757b0fca 100644 --- a/cmd/collectors/zapi/plugins/shelf/shelf.go +++ b/cmd/collectors/zapi/plugins/shelf/shelf.go @@ -6,7 +6,6 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/pkg/api/ontapi/zapi" "github.com/netapp/harvest/v2/pkg/conf" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree/node" @@ -21,7 +20,7 @@ type Shelf struct { data map[string]*matrix.Matrix shelfData *matrix.Matrix instanceKeys map[string]string - instanceLabels map[string]*dict.Dict + instanceLabels map[string]map[string]string shelfInstanceKeys []string shelfInstanceLabels []shelfInstanceLabel batchSize string @@ -68,7 +67,7 @@ func (my *Shelf) Init() error { my.data = make(map[string]*matrix.Matrix) my.instanceKeys = make(map[string]string) - my.instanceLabels = make(map[string]*dict.Dict) + my.instanceLabels = make(map[string]map[string]string) objects := my.Params.GetChildS("objects") if objects == nil { @@ -85,7 +84,7 @@ func (my *Shelf) Init() error { objectName = strings.TrimSpace(x[1]) } - my.instanceLabels[attribute] = dict.New() + my.instanceLabels[attribute] = make(map[string]string) my.data[attribute] = matrix.New(my.Parent+".Shelf", "shelf_"+objectName, "shelf_"+objectName) my.data[attribute].SetGlobalLabel("datacenter", my.ParentParams.GetChildContentS("datacenter")) @@ -108,11 +107,11 @@ func (my *Shelf) Init() error { switch kind { case "key": my.instanceKeys[attribute] = metricName - my.instanceLabels[attribute].Set(metricName, display) + my.instanceLabels[attribute][metricName] = display instanceKeys.NewChildS("", display) my.Logger.Debug().Msgf("added instance key: (%s) (%s) [%s]", attribute, x.GetNameS(), display) case "label": - my.instanceLabels[attribute].Set(metricName, display) + my.instanceLabels[attribute][metricName] = display instanceLabels.NewChildS("", display) my.Logger.Debug().Msgf("added instance label: (%s) (%s) [%s]", attribute, x.GetNameS(), display) case "float": @@ -307,7 +306,7 @@ func (my *Shelf) handle7Mode(data *matrix.Matrix, result []*node.Node) ([]*matri } my.Logger.Debug().Msgf("add (%s) instance: %s.%s", attribute, shelfID, key) - for label, labelDisplay := range my.instanceLabels[attribute].Map() { + for label, labelDisplay := range my.instanceLabels[attribute] { if value := obj.GetChildContentS(label); value != "" { instance.SetLabel(labelDisplay, value) } diff --git a/cmd/collectors/zapi/plugins/snapmirror/snapmirror.go b/cmd/collectors/zapi/plugins/snapmirror/snapmirror.go index 26f082d69..5d6a86456 100644 --- a/cmd/collectors/zapi/plugins/snapmirror/snapmirror.go +++ b/cmd/collectors/zapi/plugins/snapmirror/snapmirror.go @@ -56,7 +56,7 @@ func (my *SnapMirror) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, destUpdCount := 0 srcUpdCount := 0 - if cluster, ok := data.GetGlobalLabels().GetHas("cluster"); ok { + if cluster, ok := data.GetGlobalLabels()["cluster"]; ok { if err := my.getSVMPeerData(cluster); err != nil { return nil, err } diff --git a/cmd/collectors/zapiperf/plugins/disk/disk.go b/cmd/collectors/zapiperf/plugins/disk/disk.go index 5e2d7b924..1d025d816 100644 --- a/cmd/collectors/zapiperf/plugins/disk/disk.go +++ b/cmd/collectors/zapiperf/plugins/disk/disk.go @@ -5,7 +5,6 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/pkg/api/ontapi/zapi" "github.com/netapp/harvest/v2/pkg/conf" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree/node" @@ -45,7 +44,7 @@ type Disk struct { shelfData map[string]*matrix.Matrix powerData map[string]*matrix.Matrix instanceKeys map[string]string - instanceLabels map[string]*dict.Dict + instanceLabels map[string]map[string]string batchSize string client *zapi.Client query string @@ -130,7 +129,7 @@ func (d *Disk) Init() error { d.powerData = make(map[string]*matrix.Matrix) d.instanceKeys = make(map[string]string) - d.instanceLabels = make(map[string]*dict.Dict) + d.instanceLabels = make(map[string]map[string]string) objects := d.Params.GetChildS("objects") if objects == nil { @@ -147,7 +146,7 @@ func (d *Disk) Init() error { objectName = strings.TrimSpace(x[1]) } - d.instanceLabels[attribute] = dict.New() + d.instanceLabels[attribute] = make(map[string]string) d.shelfData[attribute] = matrix.New(d.Parent+".Shelf", "shelf_"+objectName, "shelf_"+objectName) d.shelfData[attribute].SetGlobalLabel("datacenter", d.ParentParams.GetChildContentS("datacenter")) @@ -170,11 +169,11 @@ func (d *Disk) Init() error { switch kind { case "key": d.instanceKeys[attribute] = metricName - d.instanceLabels[attribute].Set(metricName, display) + d.instanceLabels[attribute][metricName] = display instanceKeys.NewChildS("", display) d.Logger.Debug().Msgf("added instance key: (%s) (%s) [%s]", attribute, x.GetNameS(), display) case "label": - d.instanceLabels[attribute].Set(metricName, display) + d.instanceLabels[attribute][metricName] = display instanceLabels.NewChildS("", display) d.Logger.Debug().Msgf("added instance label: (%s) (%s) [%s]", attribute, x.GetNameS(), display) case "float": @@ -843,7 +842,7 @@ func (d *Disk) handleCMode(shelves []*node.Node) ([]*matrix.Matrix, error) { } d.Logger.Debug().Msgf("add (%s) instance: %s.%s", attribute, shelfID, key) - for label, labelDisplay := range d.instanceLabels[attribute].Map() { + for label, labelDisplay := range d.instanceLabels[attribute] { if value := obj.GetChildContentS(label); value != "" { instance.SetLabel(labelDisplay, value) } diff --git a/cmd/collectors/zapiperf/plugins/externalserviceoperation/externalserviceoperation.go b/cmd/collectors/zapiperf/plugins/externalserviceoperation/externalserviceoperation.go index 219602607..9294b93b9 100644 --- a/cmd/collectors/zapiperf/plugins/externalserviceoperation/externalserviceoperation.go +++ b/cmd/collectors/zapiperf/plugins/externalserviceoperation/externalserviceoperation.go @@ -19,7 +19,7 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin { func (e *ExternalServiceOperation) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { data := dataMap[e.Object] - datacenterClusterKey := data.GetGlobalLabels().Get("datacenter") + Hyphen + data.GetGlobalLabels().Get("cluster") + Hyphen + datacenterClusterKey := data.GetGlobalLabels()["datacenter"] + Hyphen + data.GetGlobalLabels()["cluster"] + Hyphen for _, instance := range data.GetInstances() { if !instance.IsExportable() { continue diff --git a/cmd/collectors/zapiperf/plugins/volume/volume.go b/cmd/collectors/zapiperf/plugins/volume/volume.go index 6e8fd319a..21212f8ab 100644 --- a/cmd/collectors/zapiperf/plugins/volume/volume.go +++ b/cmd/collectors/zapiperf/plugins/volume/volume.go @@ -8,6 +8,7 @@ import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/set" + "maps" "regexp" "sort" "strings" @@ -37,8 +38,8 @@ func (v *Volume) Init() error { return nil } -//@TODO cleanup logging -//@TODO rewrite using vector arithmetic +// @TODO cleanup logging +// @TODO rewrite using vector arithmetic // will simplify the code a whole!!! func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { @@ -78,7 +79,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error key := i.GetLabel("svm") + "." + match[1] if cache.GetInstance(key) == nil { fg, _ := cache.NewInstance(key) - fg.SetLabels(i.GetLabels().Copy()) + fg.SetLabels(maps.Clone(i.GetLabels())) fg.SetLabel("volume", match[1]) // Flexgroup don't show any aggregate, node fg.SetLabel("aggr", "") @@ -88,7 +89,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error if volumeAggrmetric.GetInstance(key) == nil { flexgroupInstance, _ := volumeAggrmetric.NewInstance(key) - flexgroupInstance.SetLabels(i.GetLabels().Copy()) + flexgroupInstance.SetLabels(maps.Clone(i.GetLabels())) flexgroupInstance.SetLabel("volume", match[1]) // Flexgroup don't show any node flexgroupInstance.SetLabel("node", "") @@ -109,7 +110,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error v.Logger.Error().Err(err).Str("key", key).Msg("Failed to create new instance") continue } - flexvolInstance.SetLabels(i.GetLabels().Copy()) + flexvolInstance.SetLabels(maps.Clone(i.GetLabels())) flexvolInstance.SetLabel(style, "flexvol") if err := metric.SetValueFloat64(flexvolInstance, 1); err != nil { v.Logger.Error().Err(err).Str("metric", metricName).Msg("Unable to set value on metric") @@ -120,7 +121,7 @@ func (v *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error v.Logger.Debug().Msgf("extracted %d flexgroup volumes", len(cache.GetInstances())) - //cache.Reset() + // cache.Reset() // create summary for _, i := range data.GetInstances() { diff --git a/cmd/collectors/zapiperf/zapiperf.go b/cmd/collectors/zapiperf/zapiperf.go index fa76e749c..07ee1e0ae 100644 --- a/cmd/collectors/zapiperf/zapiperf.go +++ b/cmd/collectors/zapiperf/zapiperf.go @@ -43,6 +43,7 @@ import ( "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/set" "github.com/netapp/harvest/v2/pkg/tree/node" + "github.com/rs/zerolog" "strconv" "strings" "time" @@ -907,18 +908,18 @@ func (z *ZapiPerf) PollCounter() (map[string]*matrix.Matrix, error) { err error request, response, counterList *node.Node oldMetrics, oldLabels, replaced, missing *set.Set - wanted *dict.Dict + wanted map[string]string oldMetricsSize, oldLabelsSize int counters map[string]*node.Node ) z.scalarCounters = make([]string, 0) counters = make(map[string]*node.Node) - oldMetrics = set.New() // current set of metrics, so we can remove from matrix if not updated - oldLabels = set.New() // current set of labels - wanted = dict.New() // counters listed in template, maps raw name to display name - missing = set.New() // required base counters, missing in template - replaced = set.New() // deprecated and replaced counters + oldMetrics = set.New() // current set of metrics, so we can remove from matrix if not updated + oldLabels = set.New() // current set of labels + wanted = make(map[string]string) // counters listed in template, maps raw name to display name + missing = set.New() // required base counters, missing in template + replaced = set.New() // deprecated and replaced counters mat := z.Matrix[z.Object] for key := range mat.GetMetrics() { @@ -935,16 +936,16 @@ func (z *ZapiPerf) PollCounter() (map[string]*matrix.Matrix, error) { if counterList = z.Params.GetChildS("counters"); counterList != nil { for _, cnt := range counterList.GetAllChildContentS() { if renamed := strings.Split(cnt, "=>"); len(renamed) == 2 { - wanted.Set(strings.TrimSpace(renamed[0]), strings.TrimSpace(renamed[1])) + wanted[strings.TrimSpace(renamed[0])] = strings.TrimSpace(renamed[1]) } else if cnt == "instance_name" { - wanted.Set("instance_name", z.object) + wanted["instance_name"] = z.object } else { display := strings.ReplaceAll(cnt, "-", "_") if strings.HasPrefix(display, z.object) { display = strings.TrimPrefix(display, z.object) display = strings.TrimPrefix(display, "_") } - wanted.Set(cnt, display) + wanted[cnt] = display } } } else { @@ -987,7 +988,7 @@ func (z *ZapiPerf) PollCounter() (map[string]*matrix.Matrix, error) { counter.SetChildContentS("properties", p) } - display, ok := wanted.GetHas(key) + display, ok := wanted[key] // counter not requested if !ok { z.Logger.Trace(). @@ -1004,7 +1005,8 @@ func (z *ZapiPerf) PollCounter() (map[string]*matrix.Matrix, error) { Str("key", key). Str("replacement", r). Msg("Replaced deprecated counter") - if !wanted.Has(r) { + _, ok = wanted[r] + if !ok { replaced.Add(r) } } @@ -1018,9 +1020,12 @@ func (z *ZapiPerf) PollCounter() (map[string]*matrix.Matrix, error) { } else { // add counter as numeric metric oldMetrics.Remove(key) - if r := z.addCounter(counter, key, display, true, counters); r != "" && !wanted.Has(r) { - missing.Add(r) // required base counter, missing in template - z.Logger.Trace().Msgf("%smarking [%s] as required base counter for [%s]%s", color.Red, r, key, color.End) + if r := z.addCounter(counter, key, display, true, counters); r != "" { + _, ok = wanted[r] + if !ok { + missing.Add(r) // required base counter, missing in template + z.Logger.Trace().Msgf("%smarking [%s] as required base counter for [%s]%s", color.Red, r, key, color.End) + } } } } @@ -1032,9 +1037,12 @@ func (z *ZapiPerf) PollCounter() (map[string]*matrix.Matrix, error) { if replaced.Has(name) { oldMetrics.Remove(name) z.Logger.Debug().Msgf("adding [%s] (replacement for deprecated counter)", name) - if r := z.addCounter(counter, name, name, true, counters); r != "" && !wanted.Has(r) { - missing.Add(r) // required base counter, missing in template - z.Logger.Debug().Msgf("%smarking [%s] as required base counter for [%s]%s", color.Red, r, name, color.End) + if r := z.addCounter(counter, name, name, true, counters); r != "" { + _, ok := wanted[r] + if !ok { + missing.Add(r) // required base counter, missing in template + z.Logger.Debug().Msgf("%smarking [%s] as required base counter for [%s]%s", color.Red, r, name, color.End) + } } } } @@ -1507,7 +1515,13 @@ func (z *ZapiPerf) updateQosLabels(qos *node.Node, instance *matrix.Instance, ke instance.SetLabel(display, value) } } - z.Logger.Debug().Str("query", z.Query).Str("key", key).Str("qos labels", instance.GetLabels().String()).Send() + if z.Logger.GetLevel() == zerolog.DebugLevel { + z.Logger.Debug(). + Str("query", z.Query). + Str("key", key). + Str("qos labels", dict.String(instance.GetLabels())). + Send() + } } } diff --git a/cmd/exporters/influxdb/influxdb.go b/cmd/exporters/influxdb/influxdb.go index 137261d75..c8d5bf3d8 100644 --- a/cmd/exporters/influxdb/influxdb.go +++ b/cmd/exporters/influxdb/influxdb.go @@ -253,7 +253,7 @@ func (e *InfluxDB) Render(data *matrix.Matrix) ([][]byte, error) { // only to store global labels that we'll // add to all instances global := NewMeasurement("", 0) - for key, value := range data.GetGlobalLabels().Map() { + for key, value := range data.GetGlobalLabels() { global.AddTag(key, value) } @@ -271,14 +271,14 @@ func (e *InfluxDB) Render(data *matrix.Matrix) ([][]byte, error) { // tag set if includeAll { - for label, value := range instance.GetLabels().Map() { + for label, value := range instance.GetLabels() { if value != "" { m.AddTag(label, value) } } } else { for _, key := range keysToInclude { - if value, has := instance.GetLabels().GetHas(key); has && value != "" { + if value, has := instance.GetLabels()[key]; has && value != "" { m.AddTag(key, value) } } @@ -286,14 +286,14 @@ func (e *InfluxDB) Render(data *matrix.Matrix) ([][]byte, error) { // skip instance without key tags if len(m.tagSet) == 0 { - e.Logger.Debug().Msgf("skip instance (%s), no tag set parsed from labels (%v)", key, instance.GetLabels().Map()) + e.Logger.Debug().Msgf("skip instance (%s), no tag set parsed from labels (%v)", key, instance.GetLabels()) } // field set // strings for _, label := range labelsToInclude { - if value, has := instance.GetLabels().GetHas(label); has && value != "" { + if value, has := instance.GetLabels()[label]; has && value != "" { if value == "true" || value == "false" { m.AddField(label, value) } else { @@ -320,7 +320,7 @@ func (e *InfluxDB) Render(data *matrix.Matrix) ([][]byte, error) { fieldName := metric.GetName() if metric.HasLabels() { - for _, label := range metric.GetLabels().Map() { + for _, label := range metric.GetLabels() { fieldName += "_" + label } } diff --git a/cmd/exporters/prometheus/prometheus.go b/cmd/exporters/prometheus/prometheus.go index 46b7e8446..9ec28fc33 100644 --- a/cmd/exporters/prometheus/prometheus.go +++ b/cmd/exporters/prometheus/prometheus.go @@ -317,7 +317,7 @@ func (p *Prometheus) render(data *matrix.Matrix) [][]byte { prefix = p.globalPrefix + data.Object - for key, value := range data.GetGlobalLabels().Map() { + for key, value := range data.GetGlobalLabels() { globalLabels = append(globalLabels, escape(replacer, key, value)) } @@ -337,12 +337,13 @@ func (p *Prometheus) render(data *matrix.Matrix) [][]byte { instanceLabelsSet := make(map[string]struct{}) if includeAllLabels { - for label, value := range instance.GetLabels().Map() { + for label, value := range instance.GetLabels() { // temporary fix for the rarely happening duplicate labels // known case is: ZapiPerf -> 7mode -> disk.yaml // actual cause is the Aggregator plugin, which is adding node as // instance label (even though it's already a global label for 7modes) - if !data.GetGlobalLabels().Has(label) { + _, ok := data.GetGlobalLabels()[label] + if !ok { instanceKeys = append(instanceKeys, escape(replacer, label, value)) //nolint:makezero } } @@ -442,8 +443,8 @@ func (p *Prometheus) render(data *matrix.Matrix) [][]byte { histogram.values[index] = value continue } - metricLabels := make([]string, 0, metric.GetLabels().Size()) - for k, v := range metric.GetLabels().Map() { + metricLabels := make([]string, 0, len(metric.GetLabels())) + for k, v := range metric.GetLabels() { metricLabels = append(metricLabels, escape(replacer, k, v)) } x := fmt.Sprintf( diff --git a/cmd/poller/plugin/aggregator/aggregator.go b/cmd/poller/plugin/aggregator/aggregator.go index dcca39f6d..d8b0c105c 100644 --- a/cmd/poller/plugin/aggregator/aggregator.go +++ b/cmd/poller/plugin/aggregator/aggregator.go @@ -6,8 +6,11 @@ package aggregator import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" + "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" + "github.com/rs/zerolog" + "golang.org/x/exp/maps" "regexp" "strings" ) @@ -150,7 +153,9 @@ func (a *Aggregator) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, e continue } - a.Logger.Trace().Msgf("handling instance with labels [%s]", instance.GetLabels().String()) + if a.Logger.GetLevel() == zerolog.TraceLevel { + a.Logger.Trace().Msgf("handling instance with labels [%s]", dict.String(instance.GetLabels())) + } for i, rule := range a.rules { @@ -172,7 +177,7 @@ func (a *Aggregator) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, e } if rule.allLabels { - objKey = strings.Join(instance.GetLabels().Values(), ".") + objKey = strings.Join(maps.Values(instance.GetLabels()), ".") } else if len(rule.includeLabels) != 0 { objKey = objName for _, k := range rule.includeLabels { diff --git a/cmd/poller/plugin/labelagent/label_agent.go b/cmd/poller/plugin/labelagent/label_agent.go index c5c83d6d1..394bd0891 100644 --- a/cmd/poller/plugin/labelagent/label_agent.go +++ b/cmd/poller/plugin/labelagent/label_agent.go @@ -7,6 +7,7 @@ package labelagent import ( "fmt" "github.com/netapp/harvest/v2/cmd/poller/plugin" + "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" "strings" @@ -189,7 +190,7 @@ func (a *LabelAgent) excludeEquals(matrix *matrix.Matrix) error { instance.SetExportable(false) a.Logger.Trace().Str("label", r.label). Str("value", r.value). - Str("instance labels", instance.GetLabels().String()). + Str("instance labels", dict.String(instance.GetLabels())). Msg("excludeEquals: excluded") break } @@ -206,7 +207,7 @@ func (a *LabelAgent) excludeContains(matrix *matrix.Matrix) error { instance.SetExportable(false) a.Logger.Trace().Str("label", r.label). Str("value", r.value). - Str("instance labels", instance.GetLabels().String()). + Str("instance labels", dict.String(instance.GetLabels())). Msg("excludeContains: excluded") break } @@ -223,7 +224,7 @@ func (a *LabelAgent) excludeRegex(matrix *matrix.Matrix) error { instance.SetExportable(false) a.Logger.Trace().Str("label", r.label). Str("regex", r.reg.String()). - Str("instance labels", instance.GetLabels().String()). + Str("instance labels", dict.String(instance.GetLabels())). Msg("excludeRegex: excluded") break } @@ -242,7 +243,7 @@ func (a *LabelAgent) includeEquals(matrix *matrix.Matrix) error { isExport = true a.Logger.Trace().Str("label", r.label). Str("value", r.value). - Str("instance labels", instance.GetLabels().String()). + Str("instance labels", dict.String(instance.GetLabels())). Msg("includeEquals: included") break } @@ -263,7 +264,7 @@ func (a *LabelAgent) includeContains(matrix *matrix.Matrix) error { isExport = true a.Logger.Trace().Str("label", r.label). Str("value", r.value). - Str("instance labels", instance.GetLabels().String()). + Str("instance labels", dict.String(instance.GetLabels())). Msg("includeContains: included") break } @@ -286,7 +287,7 @@ func (a *LabelAgent) includeRegex(matrix *matrix.Matrix) error { isExport = true a.Logger.Trace().Str("label", r.label). Str("regex", r.reg.String()). - Str("instance labels", instance.GetLabels().String()). + Str("instance labels", dict.String(instance.GetLabels())). Msg("includeRegex: included") break } diff --git a/cmd/poller/plugin/labelagent/label_agent_test.go b/cmd/poller/plugin/labelagent/label_agent_test.go index 27ec7998a..d4a0afe2b 100644 --- a/cmd/poller/plugin/labelagent/label_agent_test.go +++ b/cmd/poller/plugin/labelagent/label_agent_test.go @@ -6,6 +6,7 @@ package labelagent import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" + "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/matrix" "github.com/netapp/harvest/v2/pkg/tree/node" "testing" @@ -79,9 +80,9 @@ func TestSplitSimpleRule(t *testing.T) { instance, _ := m.NewInstance("0") instance.SetLabel("X", "a/b/c/d") - t.Logf("before = [%s]\n", instance.GetLabels().String()) + t.Logf("before = [%s]\n", dict.String(instance.GetLabels())) _ = p.splitSimple(m) - t.Logf("after = [%s]\n", instance.GetLabels().String()) + t.Logf("after = [%s]\n", dict.String(instance.GetLabels())) if instance.GetLabel("C") != "c" || instance.GetLabel("D") != "d" { t.Error("Labels C and D don't have expected values") @@ -95,9 +96,9 @@ func TestSplitRegexRule(t *testing.T) { instance, _ := m.NewInstance("0") instance.SetLabel("X", "xxxA22_B333") - t.Logf("before = [%s]\n", instance.GetLabels().String()) + t.Logf("before = [%s]\n", dict.String(instance.GetLabels())) _ = p.splitRegex(m) - t.Logf("after = [%s]\n", instance.GetLabels().String()) + t.Logf("after = [%s]\n", dict.String(instance.GetLabels())) if instance.GetLabel("A") != "A22" || instance.GetLabel("B") != "B333" { t.Error("Labels A and B don't have expected values") @@ -111,9 +112,9 @@ func TestSplitPairsRule(t *testing.T) { instance, _ := m.NewInstance("0") instance.SetLabel("X", "owner:jack contact:some@email") - t.Logf("before = [%s]\n", instance.GetLabels().String()) + t.Logf("before = [%s]\n", dict.String(instance.GetLabels())) _ = p.splitPairs(m) - t.Logf("after = [%s]\n", instance.GetLabels().String()) + t.Logf("after = [%s]\n", dict.String(instance.GetLabels())) if instance.GetLabel("owner") != "jack" || instance.GetLabel("contact") != "some@email" { t.Error("Labels owner and contact don't have expected values") @@ -128,9 +129,9 @@ func TestJoinSimpleRule(t *testing.T) { instance.SetLabel("A", "aaa") instance.SetLabel("B", "bbb") - t.Logf("before = [%s]\n", instance.GetLabels().String()) + t.Logf("before = [%s]\n", dict.String(instance.GetLabels())) _ = p.joinSimple(m) - t.Logf("after = [%s]\n", instance.GetLabels().String()) + t.Logf("after = [%s]\n", dict.String(instance.GetLabels())) if instance.GetLabel("X") != "aaa_bbb" { t.Error("Label A does have expected value") @@ -144,9 +145,9 @@ func TestReplaceSimpleRule(t *testing.T) { instance, _ := m.NewInstance("0") instance.SetLabel("A", "aaa_X") - t.Logf("before = [%s]\n", instance.GetLabels().String()) + t.Logf("before = [%s]\n", dict.String(instance.GetLabels())) _ = p.replaceSimple(m) - t.Logf("after = [%s]\n", instance.GetLabels().String()) + t.Logf("after = [%s]\n", dict.String(instance.GetLabels())) if instance.GetLabel("A") != "X" || instance.GetLabel("B") != "bbb_X" { t.Error("Labels A and B don't have expected values") @@ -160,9 +161,9 @@ func TestReplaceRegexRule(t *testing.T) { instance, _ := m.NewInstance("0") instance.SetLabel("A", "aaa_12345_abcDEF") - t.Logf("before = [%s]\n", instance.GetLabels().String()) + t.Logf("before = [%s]\n", dict.String(instance.GetLabels())) _ = p.replaceRegex(m) - t.Logf("after = [%s]\n", instance.GetLabels().String()) + t.Logf("after = [%s]\n", dict.String(instance.GetLabels())) if instance.GetLabel("B") != "abcDEF-12345-bbb" { t.Error("Label B does not have expected value") diff --git a/cmd/poller/plugin/max/max.go b/cmd/poller/plugin/max/max.go index 80d00adfe..37bc27c99 100644 --- a/cmd/poller/plugin/max/max.go +++ b/cmd/poller/plugin/max/max.go @@ -6,8 +6,10 @@ package max import ( "github.com/netapp/harvest/v2/cmd/poller/plugin" + "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/matrix" + "github.com/rs/zerolog" "regexp" "strconv" "strings" @@ -125,7 +127,7 @@ func (m *Max) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { key := strconv.Itoa(i) + k - //Create matrix for each metric as each metric may have an instance with different label + // Create matrix for each metric as each metric may have an instance with different label matrices[key] = data.Clone(matrix.With{Data: false, Metrics: true, Instances: false, ExportInstances: true}) matrices[key].RemoveExceptMetric(k) @@ -134,7 +136,7 @@ func (m *Max) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { } else { matrices[key].Object = strings.ToLower(rule.label) + "_" + data.Object } - //UUID needs to be unique + // UUID needs to be unique matrices[key].UUID += key matrices[key].SetExportOptions(matrix.DefaultExportOptions()) matrices[key].SetExportable(true) @@ -159,7 +161,9 @@ func (m *Max) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error) { continue } - m.Logger.Trace().Msgf("handling instance with labels [%s]", instance.GetLabels().String()) + if m.Logger.GetLevel() == zerolog.TraceLevel { + m.Logger.Trace().Msgf("handling instance with labels [%s]", dict.String(instance.GetLabels())) + } for i, rule := range m.rules { diff --git a/go.mod b/go.mod index 77cc1aeb0..580670dd8 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/tidwall/pretty v1.2.1 github.com/tidwall/sjson v1.2.5 github.com/zekroTJA/timedmap v1.5.1 + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/sys v0.12.0 golang.org/x/term v0.12.0 golang.org/x/text v0.13.0 diff --git a/go.sum b/go.sum index 659bece08..edbdeb794 100644 --- a/go.sum +++ b/go.sum @@ -8,7 +8,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -53,16 +52,12 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -80,15 +75,9 @@ github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= -github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= -github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= -github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -112,10 +101,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.15.0 h1:5n/pM+v3r5ujuNl4YLZLsQ+UE5jlkLVm7jMzT5Mpolw= -github.com/tidwall/gjson v1.15.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= -github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -125,37 +110,27 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zekroTJA/timedmap v1.5.1 h1:s9SI1T8gl1OAfDw9LKZYMfbhNqqCIOhZTfhsHgpKHMw= github.com/zekroTJA/timedmap v1.5.1/go.mod h1:Go4uPxMN1Wjl5IgO6HYD1tM9IQhkYEVqcrrdsI4ljXo= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration/go.mod b/integration/go.mod index a231c398c..21ce0ad43 100644 --- a/integration/go.mod +++ b/integration/go.mod @@ -7,21 +7,21 @@ replace github.com/netapp/harvest/v2 => ../ require ( github.com/carlmjohnson/requests v0.23.4 github.com/netapp/harvest/v2 v2.0.0-20230811164902-1b91e21d6950 - github.com/rs/zerolog v1.30.0 - github.com/tidwall/gjson v1.16.0 - golang.org/x/text v0.12.0 + github.com/rs/zerolog v1.31.0 + github.com/tidwall/gjson v1.17.0 + golang.org/x/text v0.13.0 ) require ( dario.cat/mergo v1.0.0 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect - github.com/shirou/gopsutil/v3 v3.23.7 // indirect + github.com/shirou/gopsutil/v3 v3.23.9 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -31,6 +31,6 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.11.0 // indirect + golang.org/x/sys v0.12.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/integration/go.sum b/integration/go.sum index 44ae3d0d1..deefdb9f6 100644 --- a/integration/go.sum +++ b/integration/go.sum @@ -7,8 +7,9 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= @@ -20,10 +21,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik= github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -34,11 +33,11 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:Om github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= -github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= -github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= +github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= +github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -54,17 +53,15 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= -github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= +github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= @@ -73,17 +70,15 @@ golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/dict/dict.go b/pkg/dict/dict.go index 12136f9d4..b66f6fbec 100644 --- a/pkg/dict/dict.go +++ b/pkg/dict/dict.go @@ -6,105 +6,18 @@ package dict import "strings" -type Dict struct { - dict map[string]string -} - -func New() *Dict { - d := Dict{} - d.dict = make(map[string]string) - return &d -} - -func (d *Dict) Copy() *Dict { - c := &Dict{} - c.dict = make(map[string]string, len(d.dict)) - for k, v := range d.dict { - c.dict[k] = v - } - return c -} - -func (d *Dict) Set(key, val string) { - d.dict[key] = val -} - -// SetAll sets all global labels that do not already exist -func (d *Dict) SetAll(allKeyVals *Dict) { - if allKeyVals != nil { - for key, val := range allKeyVals.dict { - if _, has := d.dict[key]; !has { - d.dict[key] = val - } - } - } -} - -func (d *Dict) Delete(key string) { - delete(d.dict, key) -} - -func (d *Dict) Get(key string) string { - if value, has := d.dict[key]; has { - return value - } - return "" -} - -func (d *Dict) Pop(key string) string { - if value, has := d.GetHas(key); has { - d.Delete(key) - return value - } - return "" -} - -func (d *Dict) GetHas(key string) (string, bool) { - value, has := d.dict[key] - return value, has -} - -func (d *Dict) Has(key string) bool { - _, has := d.dict[key] - return has -} - -func (d *Dict) Iter() map[string]string { - return d.dict -} - -func (d *Dict) Map() map[string]string { - return d.dict -} - -func (d *Dict) Keys() []string { - keys := make([]string, 0, len(d.dict)) - for k := range d.dict { - keys = append(keys, k) +func String(m map[string]string) string { + b := strings.Builder{} + for k, v := range m { + b.WriteString(k) + b.WriteString("=") + b.WriteString(v) + b.WriteString(", ") } - return keys -} - -func (d *Dict) String() string { - s := make([]string, 0, len(d.dict)) - for k, v := range d.dict { - s = append(s, k+"="+v) - } - return strings.Join(s, ", ") -} -func (d *Dict) Values() []string { - values := make([]string, 0, len(d.dict)) - for _, v := range d.dict { - values = append(values, v) + s := b.String() + if len(s) > 0 { + return s[:len(s)-2] } - return values -} - -func (d *Dict) IsEmpty() bool { - return len(d.dict) == 0 -} - -func (d *Dict) Size() int { - return len(d.dict) + return s } diff --git a/pkg/dict/dict_test.go b/pkg/dict/dict_test.go new file mode 100644 index 000000000..d13010e2c --- /dev/null +++ b/pkg/dict/dict_test.go @@ -0,0 +1,28 @@ +package dict + +import ( + "strings" + "testing" +) + +func TestString(t *testing.T) { + tests := []struct { + name string + args map[string]string + wantCommas int + }{ + {name: "empty", args: make(map[string]string), wantCommas: 0}, + {name: "none", args: map[string]string{"a": "a"}, wantCommas: 0}, + {name: "one", args: map[string]string{"a": "a", "b": "b"}, wantCommas: 1}, + {name: "two", args: map[string]string{"a": "a", "b": "b", "c": "c"}, wantCommas: 2}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := String(tt.args) + gotCommas := strings.Count(s, ",") + if gotCommas != tt.wantCommas { + t.Errorf("String() commas got=%d, want=%d", gotCommas, tt.wantCommas) + } + }) + } +} diff --git a/pkg/matrix/instance.go b/pkg/matrix/instance.go index 0b168c333..78c57ba08 100644 --- a/pkg/matrix/instance.go +++ b/pkg/matrix/instance.go @@ -5,41 +5,41 @@ package matrix import ( - "github.com/netapp/harvest/v2/pkg/dict" + "maps" ) // Instance struct and related methods type Instance struct { index int - labels *dict.Dict + labels map[string]string exportable bool } func NewInstance(index int) *Instance { me := &Instance{index: index} - me.labels = dict.New() + me.labels = make(map[string]string) me.exportable = true return me } func (i *Instance) GetLabel(key string) string { - return i.labels.Get(key) + return i.labels[key] } -func (i *Instance) GetLabels() *dict.Dict { +func (i *Instance) GetLabels() map[string]string { return i.labels } func (i *Instance) ClearLabels() { - i.labels = dict.New() + clear(i.labels) } func (i *Instance) SetLabel(key, value string) { - i.labels.Set(key, value) + i.labels[key] = value } -func (i *Instance) SetLabels(labels *dict.Dict) { +func (i *Instance) SetLabels(labels map[string]string) { i.labels = labels } @@ -53,7 +53,7 @@ func (i *Instance) SetExportable(b bool) { func (i *Instance) Clone(isExportable bool) *Instance { clone := NewInstance(i.index) - clone.labels = i.labels.Copy() + clone.labels = maps.Clone(i.labels) clone.exportable = isExportable return clone } diff --git a/pkg/matrix/matrix.go b/pkg/matrix/matrix.go index b88921e55..af9a381ca 100644 --- a/pkg/matrix/matrix.go +++ b/pkg/matrix/matrix.go @@ -12,7 +12,6 @@ package matrix import ( "fmt" - "github.com/netapp/harvest/v2/pkg/dict" "github.com/netapp/harvest/v2/pkg/errs" "github.com/netapp/harvest/v2/pkg/logging" "github.com/netapp/harvest/v2/pkg/tree/node" @@ -23,7 +22,7 @@ type Matrix struct { UUID string Object string Identifier string - globalLabels *dict.Dict + globalLabels map[string]string instances map[string]*Instance metrics map[string]*Metric // ONTAP metric name => metric (in templates, this is left side) displayMetrics map[string]string // display name of metric to => metric name (in templates, this is right side) @@ -40,7 +39,7 @@ type With struct { func New(uuid, object string, identifier string) *Matrix { me := Matrix{UUID: uuid, Object: object, Identifier: identifier} - me.globalLabels = dict.New() + me.globalLabels = make(map[string]string) me.instances = make(map[string]*Instance) me.metrics = make(map[string]*Metric) me.displayMetrics = make(map[string]string) @@ -287,15 +286,22 @@ func (m *Matrix) RemoveInstance(key string) { } func (m *Matrix) SetGlobalLabel(label, value string) { - m.globalLabels.Set(label, value) + m.globalLabels[label] = value } -// SetGlobalLabels sets all global labels that do not already exist -func (m *Matrix) SetGlobalLabels(allLabels *dict.Dict) { - m.globalLabels.SetAll(allLabels) +// SetGlobalLabels copies allLabels to globalLabels when the label does not exist in globalLabels +func (m *Matrix) SetGlobalLabels(allLabels map[string]string) { + if allLabels == nil { + return + } + for key, val := range allLabels { + if _, has := m.globalLabels[key]; !has { + m.globalLabels[key] = val + } + } } -func (m *Matrix) GetGlobalLabels() *dict.Dict { +func (m *Matrix) GetGlobalLabels() map[string]string { return m.globalLabels } diff --git a/pkg/matrix/metric.go b/pkg/matrix/metric.go index ed548d99c..60eacb643 100644 --- a/pkg/matrix/metric.go +++ b/pkg/matrix/metric.go @@ -13,7 +13,7 @@ package matrix import ( "fmt" - "github.com/netapp/harvest/v2/pkg/dict" + "maps" "strconv" ) @@ -25,7 +25,7 @@ type Metric struct { array bool histogram bool exportable bool - labels *dict.Dict + labels map[string]string buckets *[]string record []bool values []float64 @@ -42,9 +42,7 @@ func (m *Metric) Clone(deep bool) *Metric { histogram: m.histogram, buckets: m.buckets, } - if m.labels != nil { - clone.labels = m.labels.Copy() - } + clone.labels = maps.Clone(m.labels) if deep { if len(m.record) != 0 { clone.record = make([]bool, len(m.record)) @@ -100,9 +98,9 @@ func (m *Metric) SetArray(c bool) { func (m *Metric) SetLabel(key, value string) { if m.labels == nil { - m.labels = dict.New() + m.labels = make(map[string]string) } - m.labels.Set(key, value) + m.labels[key] = value } func (m *Metric) SetHistogram(b bool) { @@ -121,23 +119,23 @@ func (m *Metric) SetBuckets(buckets *[]string) { m.buckets = buckets } -func (m *Metric) SetLabels(labels *dict.Dict) { +func (m *Metric) SetLabels(labels map[string]string) { m.labels = labels } func (m *Metric) GetLabel(key string) string { if m.labels != nil { - return m.labels.Get(key) + return m.labels[key] } return "" } -func (m *Metric) GetLabels() *dict.Dict { +func (m *Metric) GetLabels() map[string]string { return m.labels } func (m *Metric) HasLabels() bool { - return m.labels != nil && m.labels.Size() != 0 + return m.labels != nil && len(m.labels) > 0 } func (m *Metric) GetRecords() []bool { diff --git a/vendor/modules.txt b/vendor/modules.txt index 744c4b1ca..ce202e218 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -106,6 +106,9 @@ github.com/yusufpapurcu/wmi # github.com/zekroTJA/timedmap v1.5.1 ## explicit; go 1.13 github.com/zekroTJA/timedmap +# golang.org/x/exp v0.0.0-20230905200255-921286631fa9 +## explicit; go 1.20 +golang.org/x/exp/maps # golang.org/x/sys v0.12.0 ## explicit; go 1.17 golang.org/x/sys/internal/unsafeheader