firehol/netdata

View on GitHub
src/go/plugin/go.d/modules/scaleio/collect_system.go

Summary

Maintainability
B
4 hrs
Test Coverage
// 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
}