Skip to content
Open
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
42 changes: 30 additions & 12 deletions cmd/poller/plugin/metricagent/metric_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package metricagent

import (
"errors"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/collector"
"github.com/netapp/harvest/v2/pkg/conf"
Expand All @@ -18,7 +19,7 @@ import (

type MetricAgent struct {
*plugin.AbstractPlugin
actions []func(*matrix.Matrix) error
actions []func(map[string]*matrix.Matrix) error
computeMetricRules []computeMetricRule
}

Expand Down Expand Up @@ -48,40 +49,54 @@ func (a *MetricAgent) Init(remote conf.Remote) error {

func (a *MetricAgent) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *collector.Metadata, error) {

var err error
data := dataMap[a.Object]
ee := make([]error, 0, len(a.actions))

for _, foo := range a.actions {
_ = foo(data)
err := foo(dataMap)
ee = append(ee, err)
}

return nil, nil, err
return nil, nil, errors.Join(ee...)
}

func (a *MetricAgent) computeMetrics(m *matrix.Matrix) error {
func (a *MetricAgent) computeMetrics(dataMap map[string]*matrix.Matrix) error {

var (
metric *matrix.Metric
metricVal, firstMetricVal *matrix.Metric
m []*matrix.Matrix
err error
metricNotFound []error
)

data := dataMap[a.Object]

// map values for compute_metric mapping rules
for _, r := range a.computeMetricRules {
if metric = a.getMetric(m, r.metric); metric == nil {
if metric, err = m.NewMetricFloat64(r.metric); err != nil {
m = make([]*matrix.Matrix, len(r.metricNames))
for i := range r.metricNames {
if data == nil {
m[i] = dataMap[r.metricNames[i]]
} else {
m[i] = data
}
}
if m[0] == nil {
return errs.New(errs.ErrMissingMetric, "matrix not found for metric "+r.metricNames[0])
}
if metric = a.getMetric(m[0], r.metric); metric == nil {
if metric, err = m[0].NewMetricFloat64(r.metric); err != nil {
Comment thread
Hardikl marked this conversation as resolved.
a.SLogger.Error("Failed to create metric", slogx.Err(err), slog.String("metric", r.metric))
return err
}
metric.SetProperty("compute_metric mapping")
}

for _, instance := range m.GetInstances() {
for iKey, instance := range m[0].GetInstances() {
var result float64

// Parse first operand and store in result for further processing
if firstMetricVal = a.getMetric(m, r.metricNames[0]); firstMetricVal != nil {
if firstMetricVal = a.getMetric(m[0], r.metricNames[0]); firstMetricVal != nil {
if val, ok := firstMetricVal.GetValueFloat64(instance); ok {
result = val
} else {
Expand All @@ -97,9 +112,12 @@ func (a *MetricAgent) computeMetrics(m *matrix.Matrix) error {
if value, err := strconv.Atoi(r.metricNames[i]); err == nil {
v = float64(value)
} else {
metricVal = a.getMetric(m, r.metricNames[i])
if m[i] == nil || m[i].GetInstance(iKey) == nil {
return errs.New(errs.ErrMissingMetric, "matrix or instance not found for metric "+r.metricNames[i])
}
metricVal = a.getMetric(m[i], r.metricNames[i])
if metricVal != nil {
v, _ = metricVal.GetValueFloat64(instance)
v, _ = metricVal.GetValueFloat64(m[i].GetInstance(iKey))
} else {
metricNotFound = append(metricNotFound, err)
break
Expand Down
54 changes: 52 additions & 2 deletions cmd/poller/plugin/metricagent/metric_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func newAgent() *MetricAgent {
return p
}

func TestComputeMetricsRule(t *testing.T) {
func TestComputeMetricsRuleWithSingleMatrix(t *testing.T) {

var (
instanceA, instanceB *matrix.Instance
Expand Down Expand Up @@ -112,7 +112,9 @@ func TestComputeMetricsRule(t *testing.T) {
assert.Nil(t, err)
metricTotalDuration.SetValueFloat64(instanceB, 3600)

err = p.computeMetrics(m)
dataMap := make(map[string]*matrix.Matrix)
dataMap[p.Object] = m
_, _, err = p.Run(dataMap)
Comment thread
Hardikl marked this conversation as resolved.
assert.Nil(t, err)

// check "space_total" for instanceA
Expand Down Expand Up @@ -154,3 +156,51 @@ func TestComputeMetricsRule(t *testing.T) {
assert.True(t, ok)
assert.Equal(t, metricTransmissionRateVal, expected)
}

func TestComputeMetricsRuleWithMultiMatrix(t *testing.T) {

var (
instanceA, instanceB *matrix.Instance
metricDataBytes, metricTotalSpaceBytes, metricUsedPerc *matrix.Metric
expected float64
err error
)

params := node.NewS("MetricAgent")
// create metric "storagegrid_storage_utilization_used_percent", which is percent of the metric value of storagegrid_storage_utilization_data_bytes by storagegrid_storage_utilization_total_space_bytes
params.NewChildS("compute_metric", "").NewChildS("", "storagegrid_storage_utilization_used_percent PERCENT storagegrid_storage_utilization_data_bytes storagegrid_storage_utilization_total_space_bytes")
abc := plugin.New("Test", nil, params, nil, "", nil)
p := &MetricAgent{AbstractPlugin: abc}
if err := p.Init(conf.Remote{}); err != nil {
panic(err)
}

m1 := matrix.New("Matrix1", "", "Prometheus")
m2 := matrix.New("Matrix2", "", "Prometheus")

instanceA, err = m1.NewInstance("A")
assert.Nil(t, err)

instanceB, err = m2.NewInstance("A")
assert.Nil(t, err)

metricDataBytes, err = m1.NewMetricFloat64("storagegrid_storage_utilization_data_bytes")
assert.Nil(t, err)
metricDataBytes.SetValueFloat64(instanceA, 9000000)

metricTotalSpaceBytes, err = m2.NewMetricFloat64("storagegrid_storage_utilization_total_space_bytes")
assert.Nil(t, err)
metricTotalSpaceBytes.SetValueFloat64(instanceB, 36000000)

dataMap := make(map[string]*matrix.Matrix)
dataMap["storagegrid_storage_utilization_data_bytes"] = m1
dataMap["storagegrid_storage_utilization_total_space_bytes"] = m2
_, _, err = p.Run(dataMap)
assert.Nil(t, err)

expected = 25
metricUsedPerc = m1.GetMetric("storagegrid_storage_utilization_used_percent")
metricUsedPercVal, ok := metricUsedPerc.GetValueFloat64(instanceA)
assert.True(t, ok)
assert.Equal(t, metricUsedPercVal, expected)
}
2 changes: 1 addition & 1 deletion cmd/poller/plugin/metricagent/parse_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (a *MetricAgent) parseRules() int {
}
}

a.actions = make([]func(matrix *matrix.Matrix) error, 0)
a.actions = make([]func(map[string]*matrix.Matrix) error, 0)
count := 0

for _, c := range a.Params.GetChildren() {
Expand Down
Loading