Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/collectors/restperf/plugins/disk/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ func (d *Disk) Init(remote conf.Remote) error {
d.instanceKeys = make(map[string][]string)
d.instanceLabels = make(map[string]map[string]string)

// StatPerf uses "total_transfers" while RestPerf uses "total_transfer_count"
if d.IsStatPerfCollector() {
// StatPerf and CmPerf use "total_transfers" while RestPerf uses "total_transfer_count"
if d.IsStatPerfCollector() || d.IsCmPerfCollector() {
d.totalTransfersCounter = "total_transfers"
} else {
d.totalTransfersCounter = "total_transfer_count"
Expand Down
10 changes: 9 additions & 1 deletion cmd/collectors/restperf/plugins/fabricpool/fabricpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,15 @@ func (f *FabricPool) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *
}
}

cache, err := collectors.GetFlexGroupFabricPoolMetrics(dataMap, f.Object, "cloud_bin_op", f.includeConstituents, f.SLogger)
// GetFlexGroupFabricPoolMetrics looks the ops counter up by matrix key, which is the
// counter's ONTAP name. RestPerf's name is cloud_bin_op and only its display is renamed
// to cloud_bin_operation; CmPerf's counter is named cloud_bin_operation.
opName := "cloud_bin_op"
if f.IsCmPerfCollector() {
opName = "cloud_bin_operation"
}

cache, err := collectors.GetFlexGroupFabricPoolMetrics(dataMap, f.Object, opName, f.includeConstituents, f.SLogger)
if err != nil {
return nil, nil, err
}
Expand Down
77 changes: 77 additions & 0 deletions cmd/collectors/restperf/plugins/fabricpool/fabricpool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package fabricpool

import (
"github.com/netapp/harvest/v2/assert"
"github.com/netapp/harvest/v2/cmd/poller/options"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/tree/node"
"log/slog"
"testing"
)

// TestRunWeightedLatency checks that the flexgroup latency is weighted by the ops counter.
// RestPerf keys the ops counter as cloud_bin_op (only its display is renamed to cloud_bin_operation),
// while CmPerf keys it as cloud_bin_operation, so the plugin has to look up a different key in each.
func TestRunWeightedLatency(t *testing.T) {
tests := []struct {
name string
parent string
opsKey string
}{
{name: "RestPerf", parent: "RestPerf", opsKey: "cloud_bin_op#GET"},
{name: "CmPerf", parent: "CmPerf", opsKey: "cloud_bin_operation#GET"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
const latencyKey = "cloud_bin_op_latency_average#GET"

data := matrix.New("fabricpool", "fabricpool", "fabricpool")
latency, err := data.NewMetricFloat64(latencyKey)
assert.Nil(t, err)
ops, err := data.NewMetricFloat64(tt.opsKey)
assert.Nil(t, err)

// two constituents of the flexgroup "fg"
constituents := []struct {
name string
latency float64
ops float64
}{
{name: "aggr1_fg__0001_bin_0", latency: 100, ops: 10},
{name: "aggr1_fg__0002_bin_1", latency: 200, ops: 30},
}
for _, c := range constituents {
i, err := data.NewInstance(c.name)
assert.Nil(t, err)
i.SetLabel("fabricpool", c.name)
i.SetLabel("comp_aggr_name", "aggr1")
i.SetLabel("svm", "svm1")
i.SetLabel("cloud_target", "target1")
latency.SetValueFloat64(i, c.latency)
ops.SetValueFloat64(i, c.ops)
}

o := options.Options{IsTest: true}
f := &FabricPool{AbstractPlugin: plugin.New(tt.parent, &o, node.NewS("FabricPool"), nil, "fabricpool", nil)}
f.SLogger = slog.Default()

output, _, err := f.Run(map[string]*matrix.Matrix{"fabricpool": data})
assert.Nil(t, err)
assert.Equal(t, len(output), 1)

fg := output[0].GetInstance("svm1.fg.target1")
assert.NotNil(t, fg)

// The weighted average of the two constituents is 175, the ops total is 40
got, ok := output[0].GetMetric(latencyKey).GetValueFloat64(fg)
assert.True(t, ok)
assert.Equal(t, got, 175.0)

gotOps, ok := output[0].GetMetric(tt.opsKey).GetValueFloat64(fg)
assert.True(t, ok)
assert.Equal(t, gotOps, 40.0)
})
}
}
7 changes: 3 additions & 4 deletions cmd/collectors/restperf/plugins/fcp/fcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,23 @@ func (f *Fcp) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *collect
instance.SetLabel("port", strings.TrimPrefix(instance.GetLabel("port"), "port."))

var speed int
var s string
var err error

if speed, err = strconv.Atoi(instance.GetLabel("speed")); err != nil {
f.SLogger.Debug("skip, can't convert speed to numeric", slog.String("speed", s))
f.SLogger.Debug("skip, can't convert speed to numeric", slog.String("speed", instance.GetLabel("speed")))
}

if speed != 0 {

var rxBytes, txBytes, rxPercent, txPercent float64
var rxOk, txOk bool

if rxBytes, rxOk = write.GetValueFloat64(instance); rxOk {
if rxBytes, rxOk = read.GetValueFloat64(instance); rxOk {
rxPercent = rxBytes / float64(speed)
rx.SetValueFloat64(instance, rxPercent)
}

if txBytes, txOk = read.GetValueFloat64(instance); txOk {
if txBytes, txOk = write.GetValueFloat64(instance); txOk {
txPercent = txBytes / float64(speed)
tx.SetValueFloat64(instance, txPercent)
}
Expand Down
43 changes: 43 additions & 0 deletions cmd/collectors/restperf/plugins/fcp/fcp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package fcp

import (
"github.com/netapp/harvest/v2/assert"
"github.com/netapp/harvest/v2/cmd/poller/options"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/tree/node"
"log/slog"
"testing"
)

func TestRunPercents(t *testing.T) {
data := matrix.New("fcp", "fcp", "fcp")
read, err := data.NewMetricFloat64("read_data")
assert.Nil(t, err)
write, err := data.NewMetricFloat64("write_data")
assert.Nil(t, err)

inst, err := data.NewInstance("node1:0a")
assert.Nil(t, err)
inst.SetLabel("port", "port.0a")
inst.SetLabel("speed", "1000")
read.SetValueFloat64(inst, 100)
write.SetValueFloat64(inst, 300)

o := options.Options{IsTest: true}
f := &Fcp{AbstractPlugin: plugin.New("RestPerf", &o, node.NewS("Fcp"), nil, "fcp", nil)}
f.SLogger = slog.Default()

_, _, err = f.Run(map[string]*matrix.Matrix{"fcp": data})
assert.Nil(t, err)

got := func(name string) float64 {
v, ok := data.GetMetric(name).GetValueFloat64(inst)
assert.True(t, ok)
return v
}
assert.Equal(t, got("read_percent"), 0.1)
assert.Equal(t, got("write_percent"), 0.3)
assert.Equal(t, got("util_percent"), 0.3)
assert.Equal(t, inst.GetLabel("port"), "0a")
}
4 changes: 2 additions & 2 deletions cmd/collectors/restperf/plugins/fcvi/fcvi.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ func (f *FCVI) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *collec
port := adapterData.Get("port_name").ClonedString()

// Fetch instance and add port label
// StatPerf uses "node:kernel:adapter" format while RestPerf uses "node:adapter"
// StatPerf and CmPerf use "node:kernel:adapter" format while RestPerf uses "node:adapter"
var instanceKey string
if f.IsStatPerfCollector() {
if f.IsStatPerfCollector() || f.IsCmPerfCollector() {
instanceKey = node + ":kernel:" + adapter
} else {
instanceKey = node + ":" + adapter
Expand Down
7 changes: 3 additions & 4 deletions cmd/collectors/zapiperf/plugins/fcp/fcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,23 @@ func (f *Fcp) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *collect
instance.SetLabel("port", strings.TrimPrefix(instance.GetLabel("port"), "port."))

var speed int
var s string
var err error

if speed, err = strconv.Atoi(instance.GetLabel("speed")); err != nil {
f.SLogger.Warn("skip, can't convert speed to numeric", slog.String("s", s))
f.SLogger.Warn("skip, can't convert speed to numeric", slog.String("speed", instance.GetLabel("speed")))
}

if speed != 0 {

var rxBytes, txBytes, rxPercent, txPercent float64
var rxOk, txOk bool

if rxBytes, rxOk = write.GetValueFloat64(instance); rxOk {
if rxBytes, rxOk = read.GetValueFloat64(instance); rxOk {
rxPercent = rxBytes / float64(speed)
rx.SetValueFloat64(instance, rxPercent)
}

if txBytes, txOk = read.GetValueFloat64(instance); txOk {
if txBytes, txOk = write.GetValueFloat64(instance); txOk {
txPercent = txBytes / float64(speed)
tx.SetValueFloat64(instance, txPercent)
}
Expand Down
43 changes: 43 additions & 0 deletions cmd/collectors/zapiperf/plugins/fcp/fcp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package fcp

import (
"github.com/netapp/harvest/v2/assert"
"github.com/netapp/harvest/v2/cmd/poller/options"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/tree/node"
"log/slog"
"testing"
)

func TestRunPercents(t *testing.T) {
data := matrix.New("fcp", "fcp", "fcp")
read, err := data.NewMetricFloat64("read_data")
assert.Nil(t, err)
write, err := data.NewMetricFloat64("write_data")
assert.Nil(t, err)

inst, err := data.NewInstance("node1:0a")
assert.Nil(t, err)
inst.SetLabel("port", "port.0a")
inst.SetLabel("speed", "1000")
read.SetValueFloat64(inst, 100)
write.SetValueFloat64(inst, 300)

o := options.Options{IsTest: true}
f := &Fcp{AbstractPlugin: plugin.New("ZapiPerf", &o, node.NewS("Fcp"), nil, "fcp", nil)}
f.SLogger = slog.Default()

_, _, err = f.Run(map[string]*matrix.Matrix{"fcp": data})
assert.Nil(t, err)

got := func(name string) float64 {
v, ok := data.GetMetric(name).GetValueFloat64(inst)
assert.True(t, ok)
return v
}
assert.Equal(t, got("read_percent"), 0.1)
assert.Equal(t, got("write_percent"), 0.3)
assert.Equal(t, got("util_percent"), 0.3)
assert.Equal(t, inst.GetLabel("port"), "0a")
}
2 changes: 1 addition & 1 deletion conf/cmperf/9.19.1/disk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ counters:
- ^^instance_name => partition
- ^^node_name => node
- ^^physical_disk_name => disk
- ^disk_speed => speed
- ^physical_disk_uuid => disk_uuid
- ^raid_group
- ^raid_type
Expand All @@ -14,7 +15,6 @@ counters:
- cp_reads
- disk_busy
- disk_capacity
- disk_speed
- io_pending
- io_queued
- total_data
Expand Down
2 changes: 1 addition & 1 deletion conf/cmperf/9.19.1/path.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object: path

counters:
- ^^instance_uuid
- ^instance_name
- ^instance_name => path
- ^node_name => node
- read_data
- read_iops
Expand Down
2 changes: 1 addition & 1 deletion conf/cmperf/9.19.1/resource_headroom_aggr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ query: resource_headroom_aggr
object: headroom_aggr

counters:
- ^^instance_name => aggr
- ^^instance_name
- ^^node_name => node
- current_latency
- current_ops
Expand Down
51 changes: 0 additions & 51 deletions conf/cmperf/9.19.1/volume_node.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion conf/cmperf/9.19.1/wafl_comp_aggr_vol_bin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ counters:
- ^^vol_name => volume
- ^^vserver_name => svm
- ^comp_aggr_name
- ^instance_name
- ^instance_name => fabricpool
- cloud_bin_op_latency_average
- cloud_bin_operation
plugins:
Expand Down
Loading