src/go/plugin/go.d/modules/scaleio/collect_system.go
// SPDX-License-Identifier: GPL-3.0-or-later
package scaleio
import "github.com/netdata/netdata/go/plugins/plugin/go.d/modules/scaleio/client"
func (s *ScaleIO) collectSystem(ss client.SystemStatistics) systemMetrics {
var sm systemMetrics
collectSystemCapacity(&sm, ss)
collectSystemWorkload(&sm, ss)
collectSystemRebalance(&sm, ss)
collectSystemRebuild(&sm, ss)
collectSystemComponents(&sm, ss)
return sm
}
func collectSystemCapacity(sm *systemMetrics, ss client.SystemStatistics) {
collectCapacity(&sm.Capacity, ss.CapacityStatistics)
}
func collectCapacity(m *capacity, ss client.CapacityStatistics) {
// Health
m.Protected = ss.ProtectedCapacityInKb
m.InMaintenance = ss.InMaintenanceCapacityInKb
m.Degraded = sum(ss.DegradedFailedCapacityInKb, ss.DegradedHealthyCapacityInKb)
m.Failed = ss.FailedCapacityInKb
m.UnreachableUnused = ss.UnreachableUnusedCapacityInKb
// Capacity
m.MaxCapacity = ss.MaxCapacityInKb
m.ThickInUse = ss.ThickCapacityInUseInKb
m.ThinInUse = ss.ThinCapacityInUseInKb
m.Snapshot = ss.SnapCapacityInUseOccupiedInKb
m.Spare = ss.SpareCapacityInKb
m.Decreased = sum(ss.MaxCapacityInKb, -ss.CapacityLimitInKb) // TODO: probably wrong
// Note: can't use 'UnusedCapacityInKb' directly, dashboard shows calculated value
used := sum(
ss.ProtectedCapacityInKb,
ss.InMaintenanceCapacityInKb,
m.Decreased,
m.Degraded,
ss.FailedCapacityInKb,
ss.SpareCapacityInKb,
ss.UnreachableUnusedCapacityInKb,
ss.SnapCapacityInUseOccupiedInKb,
)
m.Unused = sum(ss.MaxCapacityInKb, -used)
// Other
m.InUse = ss.CapacityInUseInKb
m.AvailableForVolumeAllocation = ss.CapacityAvailableForVolumeAllocationInKb
}
func collectSystemComponents(sm *systemMetrics, ss client.SystemStatistics) {
m := &sm.Components
m.Devices = ss.NumOfDevices
m.FaultSets = ss.NumOfFaultSets
m.MappedToAllVolumes = ss.NumOfMappedToAllVolumes
m.ProtectionDomains = ss.NumOfProtectionDomains
m.RfcacheDevices = ss.NumOfRfcacheDevices
m.Sdc = ss.NumOfSdc
m.Sds = ss.NumOfSds
m.Snapshots = ss.NumOfSnapshots
m.StoragePools = ss.NumOfStoragePools
m.VTrees = ss.NumOfVtrees
m.Volumes = ss.NumOfVolumes
m.ThickBaseVolumes = ss.NumOfThickBaseVolumes
m.ThinBaseVolumes = ss.NumOfThinBaseVolumes
m.UnmappedVolumes = ss.NumOfUnmappedVolumes
m.MappedVolumes = sum(ss.NumOfVolumes, -ss.NumOfUnmappedVolumes)
}
func collectSystemWorkload(sm *systemMetrics, ss client.SystemStatistics) {
m := &sm.Workload
m.Total.BW.set(
calcBW(ss.TotalReadBwc),
calcBW(ss.TotalWriteBwc),
)
m.Frontend.BW.set(
calcBW(ss.UserDataReadBwc),
calcBW(ss.UserDataWriteBwc),
)
m.Backend.Primary.BW.set(
calcBW(ss.PrimaryReadBwc),
calcBW(ss.PrimaryWriteBwc),
)
m.Backend.Secondary.BW.set(
calcBW(ss.SecondaryReadBwc),
calcBW(ss.SecondaryWriteBwc),
)
m.Backend.Total.BW.set(
sumFloat(m.Backend.Primary.BW.Read, m.Backend.Secondary.BW.Read),
sumFloat(m.Backend.Primary.BW.Write, m.Backend.Secondary.BW.Write),
)
m.Total.IOPS.set(
calcIOPS(ss.TotalReadBwc),
calcIOPS(ss.TotalWriteBwc),
)
m.Frontend.IOPS.set(
calcIOPS(ss.UserDataReadBwc),
calcIOPS(ss.UserDataWriteBwc),
)
m.Backend.Primary.IOPS.set(
calcIOPS(ss.PrimaryReadBwc),
calcIOPS(ss.PrimaryWriteBwc),
)
m.Backend.Secondary.IOPS.set(
calcIOPS(ss.SecondaryReadBwc),
calcIOPS(ss.SecondaryWriteBwc),
)
m.Backend.Total.IOPS.set(
sumFloat(m.Backend.Primary.IOPS.Read, m.Backend.Secondary.IOPS.Read),
sumFloat(m.Backend.Primary.IOPS.Write, m.Backend.Secondary.IOPS.Write),
)
m.Total.IOSize.set(
calcIOSize(ss.TotalReadBwc),
calcIOSize(ss.TotalWriteBwc),
)
m.Frontend.IOSize.set(
calcIOSize(ss.UserDataReadBwc),
calcIOSize(ss.UserDataWriteBwc),
)
m.Backend.Primary.IOSize.set(
calcIOSize(ss.PrimaryReadBwc),
calcIOSize(ss.PrimaryWriteBwc),
)
m.Backend.Secondary.IOSize.set(
calcIOSize(ss.SecondaryReadBwc),
calcIOSize(ss.SecondaryWriteBwc),
)
m.Backend.Total.IOSize.set(
sumFloat(m.Backend.Primary.IOSize.Read, m.Backend.Secondary.IOSize.Read),
sumFloat(m.Backend.Primary.IOSize.Write, m.Backend.Secondary.IOSize.Write),
)
}
func collectSystemRebuild(sm *systemMetrics, ss client.SystemStatistics) {
m := &sm.Rebuild
m.Forward.BW.set(
calcBW(ss.FwdRebuildReadBwc),
calcBW(ss.FwdRebuildWriteBwc),
)
m.Backward.BW.set(
calcBW(ss.BckRebuildReadBwc),
calcBW(ss.BckRebuildWriteBwc),
)
m.Normal.BW.set(
calcBW(ss.NormRebuildReadBwc),
calcBW(ss.NormRebuildWriteBwc),
)
m.Total.BW.set(
sumFloat(m.Forward.BW.Read, m.Backward.BW.Read, m.Normal.BW.Read),
sumFloat(m.Forward.BW.Write, m.Backward.BW.Write, m.Normal.BW.Write),
)
m.Forward.IOPS.set(
calcIOPS(ss.FwdRebuildReadBwc),
calcIOPS(ss.FwdRebuildWriteBwc),
)
m.Backward.IOPS.set(
calcIOPS(ss.BckRebuildReadBwc),
calcIOPS(ss.BckRebuildWriteBwc),
)
m.Normal.IOPS.set(
calcIOPS(ss.NormRebuildReadBwc),
calcIOPS(ss.NormRebuildWriteBwc),
)
m.Total.IOPS.set(
sumFloat(m.Forward.IOPS.Read, m.Backward.IOPS.Read, m.Normal.IOPS.Read),
sumFloat(m.Forward.IOPS.Write, m.Backward.IOPS.Write, m.Normal.IOPS.Write),
)
m.Forward.IOSize.set(
calcIOSize(ss.FwdRebuildReadBwc),
calcIOSize(ss.FwdRebuildWriteBwc),
)
m.Backward.IOSize.set(
calcIOSize(ss.BckRebuildReadBwc),
calcIOSize(ss.BckRebuildWriteBwc),
)
m.Normal.IOSize.set(
calcIOSize(ss.NormRebuildReadBwc),
calcIOSize(ss.NormRebuildWriteBwc),
)
m.Total.IOSize.set(
sumFloat(m.Forward.IOSize.Read, m.Backward.IOSize.Read, m.Normal.IOSize.Read),
sumFloat(m.Forward.IOSize.Write, m.Backward.IOSize.Write, m.Normal.IOSize.Write),
)
m.Forward.Pending = ss.PendingFwdRebuildCapacityInKb
m.Backward.Pending = ss.PendingBckRebuildCapacityInKb
m.Normal.Pending = ss.PendingNormRebuildCapacityInKb
m.Total.Pending = sum(m.Forward.Pending, m.Backward.Pending, m.Normal.Pending)
}
func collectSystemRebalance(sm *systemMetrics, ss client.SystemStatistics) {
m := &sm.Rebalance
m.BW.set(
calcBW(ss.RebalanceReadBwc),
calcBW(ss.RebalanceWriteBwc),
)
m.IOPS.set(
calcIOPS(ss.RebalanceReadBwc),
calcIOPS(ss.RebalanceWriteBwc),
)
m.IOSize.set(
calcIOSize(ss.RebalanceReadBwc),
calcIOSize(ss.RebalanceWriteBwc),
)
m.Pending = ss.PendingRebalanceCapacityInKb
m.TimeUntilFinish = divFloat(float64(m.Pending), m.BW.ReadWrite)
}
func calcBW(bwc client.Bwc) float64 { return div(bwc.TotalWeightInKb, bwc.NumSeconds) }
func calcIOPS(bwc client.Bwc) float64 { return div(bwc.NumOccured, bwc.NumSeconds) }
func calcIOSize(bwc client.Bwc) float64 { return div(bwc.TotalWeightInKb, bwc.NumOccured) }
func sum(a, b int64, others ...int64) (res int64) {
for _, v := range others {
res += v
}
return res + a + b
}
func sumFloat(a, b float64, others ...float64) (res float64) {
for _, v := range others {
res += v
}
return res + a + b
}
func div(a, b int64) float64 {
return divFloat(float64(a), float64(b))
}
func divFloat(a, b float64) float64 {
if b == 0 {
return 0
}
return a / b
}