alanrenouf / vCheck-vSphere

vCheck Daily Report for vSphere
MIT License
735 stars 325 forks source link

Issue - Capacity Planning - Attempted to divide by zero #234

Closed tiyab closed 8 years ago

tiyab commented 10 years ago

Hi, for the plugin 71-Capacity Planning, if there is a cluster with no host (for example when you create a new cluster and there is no new hosts yet) the plugin try to do a division by zero. it should have something like " if ($cluv.Summary.NumHosts -ne 0) " at line 12.

haripetrov commented 10 years ago

Recently I have noticed that there is another problem with this plugin (each "round" is 0, but has to be 2 at least for better results:

# Start of Settings 
# Max CPU usage for non HA cluster
$limitResourceCPUClusNonHA = 0.6 
# Max MEM usage for non HA cluster
$limitResourceMEMClusNonHA = 0.6 
# End of Settings

$capacityinfo = @()
foreach ($cluv in ($clusviews | Sort Name)) {
        $clucapacity = "" |Select ClusterName, "Estimated Num VM Left (CPU)", "Estimated Num VM Left (MEM)", "vCPU/pCPU ratio", "VM/VMHost ratio"
        if ( $cluv.Configuration.DasConfig.Enabled -eq $true ) {
            $DasRealCpuCapacity = $cluv.Summary.EffectiveCpu - (($cluv.Summary.EffectiveCpu * $cluv.Configuration.DasConfig.FailoverLevel)/$cluv.Summary.NumHosts)
            $DasRealMemCapacity = $cluv.Summary.EffectiveMemory - (($cluv.Summary.EffectiveMemory * $cluv.Configuration.DasConfig.FailoverLevel)/$cluv.Summary.NumHosts)
        } else {
            $DasRealCpuCapacity = $cluv.Summary.EffectiveCpu * $limitResourceCPUClusNonHA
            $DasRealMemCapacity = $cluv.Summary.EffectiveMemory * $limitResourceMEMClusNonHA
        }

        $cluvmlist = $VM | where { $cluv.Host -contains $_.Host.Id  }

        #CPU
            $CluCpuUsage = (get-view $cluv.ResourcePool).Summary.runtime.cpu.OverallUsage
        $CluCpuUsageAvg = $CluCpuUsage
        if ($cluvmlist -and $cluv.host -and $CluCpuUsageAvg -gt 0){
            $VmCpuAverage = $CluCpuUsageAvg/($cluvmlist.count)
            $CpuVmLeft = [math]::round(($DasRealCpuCapacity-$CluCpuUsageAvg)/$VmCpuAverage,2)
        }
        elseif ($CluCpuUsageAvg -eq 0) {$CpuVmLeft = "N/A"}
        else {$CpuVmLeft = 0}

        #MEM
            $CluMemUsage = (get-view $cluv.ResourcePool).Summary.runtime.memory.OverallUsage
        $CluMemUsageAvg = $CluMemUsage/1MB
        if ($cluvmlist -and $cluv.host -and $CluMemUsageAvg -gt 100){
            $VmMemAverage = $CluMemUsageAvg/(Get-Cluster $cluv.name|Get-VM).count
            $MemVmLeft = [math]::round(($DasRealMemCapacity-$CluMemUsageAvg)/$VmMemAverage,2)
        }
        elseif ($CluMemUsageAvg -lt 100) {$CluMemUsageAvg = "N/A"}
        else{$MemVmLeft = 0}

        $clucapacity.ClusterName = $cluv.name
        $clucapacity."Estimated Num VM Left (CPU)" = $CpuVmLeft
        $clucapacity."Estimated Num VM Left (MEM)" = $MemVmLeft
        if ($cluvmlist){
            $vCPUpCPUratio = [math]::round(($cluvmlist|Measure-Object -Sum -Property NumCpu).sum / $cluv.summary.NumCpuThreads,2)
            $clucapacity."vCPU/pCPU ratio" = $vCPUpCPUratio
        }
        else {$clucapacity."vCPU/pCPU ratio" = "0 (vCPU < pCPU)"}
        if ($cluvmlist){
            $clucapacity."VM/VMHost ratio" = [math]::round(($cluvmlist).count/$cluv.Summary.NumHosts,2)
        }
        else {$clucapacity."VM/VMHost ratio" = 0}

        $capacityinfo += $clucapacity
}

$capacityinfo | Sort ClusterName

$Title = "QuickStats Capacity Planning"
$Header = "QuickStats Capacity Planning"
$Comments = "The following gives brief capacity information for each cluster based on QuickStats CPU/Mem usage and counting for HA failover requirements"
$Display = "Table"
$Author = "Raphael Schitz, Frederic Martin"
$PluginVersion = 1.5
$PluginCategory = "vSphere"

Nevertheless it appears that there is something else (besides that) because I compare the results generated by this script:

param (
[string]$vcenter
)

if ($vcenter -eq "") 
{
                Write-host ""
                Write-host "Please specify the name of the vCenter Server as a parameter to the script like this:" # -ForegroundColor Red -Backgroundcolor Yellow
                Write-host "cpu_virt_ratio.ps1 vc-01.domain.internal" -ForegroundColor Blue -Backgroundcolor Yellow
                Write-host "Script cannot proceed. Bye!" -ForegroundColor Red -Backgroundcolor White
                Break
}
connect-viserver -server $vcenter
$clusters = get-cluster
foreach ($cluster in $clusters)
{
                $all_hosts = get-cluster -name $cluster | get-vmhost
                $all_vms = get-cluster -name $cluster | get-vm
                $pCPUs = 0
                $vCPUs = 0
                foreach ($hst in $all_hosts)
                                {
                                                $pCPUs = $pCPUs + $hst.NumCPU
                                }
                foreach ($vm in $all_vms)
                                {
                                                $vCPUs = $vCPUs + $vm.NumCPU
                                }
                if ($pCPUs -eq 0)
                                {
                                                Write-host "No hosts in cluster " $cluster
                                }
                else
                                {
                                                $ratio = [System.Math]::Round($vCPUs/$pCPUs,2)
                                                Write-host "The CPU virtualization ratio in cluster " $cluster " is " $ratio
                                }

}
disconnect-viserver -server $vcenter -confirm:$false -force

and the values are twice lower compared to the original script by vCheck. Currently with my knowledge I cannot find where the problem is. Any help will be appreciated.

vScripter commented 9 years ago

Without digging too deep, yet, I agree that it seems to be an issue with trying to divide by zero, which needs to be fixed by adding some value validation, as suggested.

vScripter commented 9 years ago

See Pull Request #383, which should have resolved this issue. As of today (5/5/15), please download the code from the Dev branch, or wait until a new release is pushed to the 'Master' branch.

Sneddo commented 9 years ago

@nevs55 reported another potential divide by zero issue - seems to be if a cluster has no VMs.

Attempted to divide by zero.
At D:\Scripts\vCheck\Plugins-virt\20 Cluster\71 Capacity Planning.ps1:25 char:39

$VmCpuAverage = $CluCpuUsageAvg/ <<<< ($cluvmlist.count)
CategoryInfo : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At D:\Scripts\vCheck\Plugins-virt\20 Cluster\71 Capacity Planning.ps1:35 char:39

$VmMemAverage = $CluMemUsageAvg/ <<<< (Get-Cluster $cluv.name|Get-VM).count
CategoryInfo : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException