Skip to content

Commit

Permalink
feat: Adding status and validation metrics in cluster software
Browse files Browse the repository at this point in the history
  • Loading branch information
Hardikl committed Nov 21, 2024
1 parent 7bd59fe commit 063f106
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 108 deletions.
255 changes: 255 additions & 0 deletions cmd/collectors/rest/plugins/clustersoftware/clustersoftware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
package clustersoftware

import (
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/conf"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/slogx"
"github.com/netapp/harvest/v2/pkg/tree/node"
"github.com/netapp/harvest/v2/pkg/util"
"github.com/tidwall/gjson"

Check failure on line 10 in cmd/collectors/rest/plugins/clustersoftware/clustersoftware.go

View workflow job for this annotation

GitHub Actions / Analyze (go)

cannot find module providing package github.com/tidwall/gjson: import lookup disabled by -mod=vendor

Check failure on line 10 in cmd/collectors/rest/plugins/clustersoftware/clustersoftware.go

View workflow job for this annotation

GitHub Actions / build

cannot find module providing package github.com/tidwall/gjson: import lookup disabled by -mod=vendor
"log/slog"
)

const updateMatrix = "cluster_software_update"
const StatusMatrix = "cluster_software_status"
const validationMatrix = "cluster_software_validation"
const labels = "labels"

type ClusterSoftware struct {
*plugin.AbstractPlugin
data map[string]*matrix.Matrix
}

func New(p *plugin.AbstractPlugin) plugin.Plugin {
return &ClusterSoftware{AbstractPlugin: p}
}

func (c *ClusterSoftware) Init(conf.Remote) error {
if err := c.InitAbc(); err != nil {
return err
}

c.data = make(map[string]*matrix.Matrix)
if err := c.createUpdateMetrics(); err != nil {
return err
}
if err := c.createStatusMetrics(); err != nil {
return err
}
if err := c.createValidationMetrics(); err != nil {
return err
}

return nil
}

func (c *ClusterSoftware) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *util.Metadata, error) {
data := dataMap[c.Object]
globalLabels := data.GetGlobalLabels()

for _, instance := range data.GetInstances() {
instance.SetExportable(false)
// generate update details metrics
updateDetails := instance.GetLabel("update_details")
updateDetailsJSON := gjson.Result{Type: gjson.JSON, Raw: "[" + updateDetails + "]"}
c.handleUpdateDetails(updateDetailsJSON, globalLabels)

// generate status details metrics
statusDetails := instance.GetLabel("status_details")
statusDetailsJSON := gjson.Result{Type: gjson.JSON, Raw: "[" + statusDetails + "]"}
c.handleStatusDetails(statusDetailsJSON, globalLabels)

// generate update details metrics
validationResults := instance.GetLabel("validation_results")
validationResultsJSON := gjson.Result{Type: gjson.JSON, Raw: "[" + validationResults + "]"}
c.handleValidationDetails(validationResultsJSON, globalLabels)
}

softwareMetrics := make([]*matrix.Matrix, 0, len(c.data))
for _, val := range c.data {
softwareMetrics = append(softwareMetrics, val)
}

return softwareMetrics, nil, nil
}

func (c *ClusterSoftware) createUpdateMetrics() error {
mat := matrix.New(c.Parent+".ClusterSoftware", updateMatrix, updateMatrix)
exportOptions := node.NewS("export_options")
instanceKeys := exportOptions.NewChildS("instance_keys", "")
instanceKeys.NewChildS("", "phase")
instanceKeys.NewChildS("", "state")
instanceKeys.NewChildS("", "node")

mat.SetExportOptions(exportOptions)

if _, err := mat.NewMetricFloat64(labels, labels); err != nil {
c.SLogger.Error("Failed to create metric", slogx.Err(err), slog.String("metric", labels))
return err
}

c.data[updateMatrix] = mat
return nil
}

func (c *ClusterSoftware) createStatusMetrics() error {
mat := matrix.New(c.Parent+".ClusterUpdate", StatusMatrix, StatusMatrix)
exportOptions := node.NewS("export_options")
instanceKeys := exportOptions.NewChildS("instance_keys", "")
instanceKeys.NewChildS("", "state")
instanceKeys.NewChildS("", "node")
instanceKeys.NewChildS("", "name")

mat.SetExportOptions(exportOptions)

if _, err := mat.NewMetricFloat64(labels, labels); err != nil {
c.SLogger.Error("Failed to create metric", slogx.Err(err), slog.String("metric", labels))
return err
}

c.data[StatusMatrix] = mat
return nil
}

func (c *ClusterSoftware) createValidationMetrics() error {
mat := matrix.New(c.Parent+".ClusterUpdate", validationMatrix, validationMatrix)
exportOptions := node.NewS("export_options")
instanceKeys := exportOptions.NewChildS("instance_keys", "")
instanceKeys.NewChildS("", "status")
instanceKeys.NewChildS("", "update_check")

mat.SetExportOptions(exportOptions)

if _, err := mat.NewMetricFloat64(labels, labels); err != nil {
c.SLogger.Error("Failed to create metric", slogx.Err(err), slog.String("metric", labels))
return err
}

c.data[validationMatrix] = mat
return nil
}

func (c *ClusterSoftware) handleUpdateDetails(updateDetailsJSON gjson.Result, globalLabels map[string]string) {
var (
clusterUpdateInstance *matrix.Instance
key string
err error
)
// Purge and reset data
c.data[updateMatrix].PurgeInstances()
c.data[updateMatrix].Reset()

// Set all global labels
c.data[updateMatrix].SetGlobalLabels(globalLabels)

for _, updateDetail := range updateDetailsJSON.Array() {
phase := updateDetail.Get("phase").String()
state := updateDetail.Get("state").String()
nodeName := updateDetail.Get("node.name").String()
key = phase + state + nodeName

if clusterUpdateInstance, err = c.data[updateMatrix].NewInstance(key); err != nil {
c.SLogger.Error("Failed to create instance", slogx.Err(err), slog.String("key", key))
continue
}
clusterUpdateInstance.SetLabel("node", nodeName)
clusterUpdateInstance.SetLabel("state", state)
clusterUpdateInstance.SetLabel("phase", phase)

// populate numeric data
value := 0.0
if state == "completed" {
value = 1.0
}

met := c.data[updateMatrix].GetMetric(labels)
if err := met.SetValueFloat64(clusterUpdateInstance, value); err != nil {
c.SLogger.Error("Failed to parse value", slogx.Err(err), slog.Float64("value", value))
} else {
c.SLogger.Debug("added value", slog.Float64("value", value))
}
}
}

func (c *ClusterSoftware) handleStatusDetails(statusDetailsJSON gjson.Result, globalLabels map[string]string) {
var (
clusterStatusInstance *matrix.Instance
key string
err error
)
// Purge and reset data
c.data[StatusMatrix].PurgeInstances()
c.data[StatusMatrix].Reset()

// Set all global labels
c.data[StatusMatrix].SetGlobalLabels(globalLabels)

for _, updateDetail := range statusDetailsJSON.Array() {
name := updateDetail.Get("name").String()
state := updateDetail.Get("state").String()
nodeName := updateDetail.Get("node.name").String()
key = name + state + nodeName

if clusterStatusInstance, err = c.data[StatusMatrix].NewInstance(key); err != nil {
c.SLogger.Error("Failed to create instance", slogx.Err(err), slog.String("key", key))
continue
}
clusterStatusInstance.SetLabel("node", nodeName)
clusterStatusInstance.SetLabel("state", state)
clusterStatusInstance.SetLabel("name", name)

// populate numeric data
value := 0.0
if state == "completed" {
value = 1.0
}

met := c.data[StatusMatrix].GetMetric(labels)
if err := met.SetValueFloat64(clusterStatusInstance, value); err != nil {
c.SLogger.Error("Failed to parse value", slogx.Err(err), slog.Float64("value", value))
} else {
c.SLogger.Debug("added value", slog.Float64("value", value))
}
}
}

func (c *ClusterSoftware) handleValidationDetails(validationDetailsJSON gjson.Result, globalLabels map[string]string) {
var (
clusterValidationInstance *matrix.Instance
key string
err error
)
// Purge and reset data
c.data[validationMatrix].PurgeInstances()
c.data[validationMatrix].Reset()

// Set all global labels
c.data[validationMatrix].SetGlobalLabels(globalLabels)

for _, updateDetail := range validationDetailsJSON.Array() {
updateCheck := updateDetail.Get("update_check").String()
status := updateDetail.Get("status").String()
key = updateCheck + status

if clusterValidationInstance, err = c.data[validationMatrix].NewInstance(key); err != nil {
c.SLogger.Error("Failed to create instance", slogx.Err(err), slog.String("key", key))
continue
}
clusterValidationInstance.SetLabel("update_check", updateCheck)
clusterValidationInstance.SetLabel("status", status)

// populate numeric data
value := 0.0
if status == "warning" {
value = 1.0
}

met := c.data[validationMatrix].GetMetric(labels)
if err := met.SetValueFloat64(clusterValidationInstance, value); err != nil {
c.SLogger.Error("Failed to parse value", slogx.Err(err), slog.Float64("value", value))
} else {
c.SLogger.Debug("added value", slog.Float64("value", value))
}
}
}
92 changes: 0 additions & 92 deletions cmd/collectors/rest/plugins/clusterupdate/clusterupdate.go

This file was deleted.

6 changes: 3 additions & 3 deletions cmd/collectors/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/aggregate"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/certificate"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/cluster"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/clusterupdate"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/clustersoftware"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/disk"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/health"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/metroclustercheck"
Expand Down Expand Up @@ -488,8 +488,8 @@ func (r *Rest) LoadPlugin(kind string, abc *plugin.AbstractPlugin) plugin.Plugin
return aggregate.New(abc)
case "Cluster":
return cluster.New(abc)
case "ClusterUpdate":
return clusterupdate.New(abc)
case "ClusterSoftware":
return clustersoftware.New(abc)
case "Disk":
return disk.New(abc)
case "Health":
Expand Down
14 changes: 14 additions & 0 deletions conf/rest/9.6.0/clustersoftware.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

name: ClusterSoftware
query: api/cluster/software
object: cluster_software

counters:
- ^status_details => status_details
- ^update_details => update_details
- ^validation_results => validation_results

plugins:
- ClusterSoftware


12 changes: 0 additions & 12 deletions conf/rest/9.6.0/clusterupdate.yaml

This file was deleted.

Loading

0 comments on commit 063f106

Please sign in to comment.