├── README.md └── metrics-vmware.ps /README.md: -------------------------------------------------------------------------------- 1 | Installing 2 | ============= 3 | 4 | Drop this file onto a server that has access to vmware powershell tools. 5 | 6 | 7 | If using telegraf exec 8 | ---------------------- 9 | requires telegraf >= v1.2 with patch (https://github.com/influxdata/telegraf/commit/4886109d9caab081f64b46e7c87d50824f4ead6b) 10 | ``` 11 | [agent] 12 | # make large because vmware powershell script can fill a small buffer passed limit 13 | metric_buffer_limit = 10000 14 | 15 | [[inputs.exec]] 16 | commands = [ 17 | '"C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe" -File "C:\Program Files\Telegraf\vmware_collect_stats.ps1"', 18 | ] 19 | data_format = "influx" 20 | timeout = "25m" 21 | interval = "30m" 22 | ``` 23 | 24 | 25 | If using a windows task 26 | ----------------------- 27 | 28 | setup a windows task to run the powershell program every ~30min 29 | 30 | ``` 31 | schtasks /create /sc minute /mo 30 /tn "metrics-vmware" /tr "\"c:\metrics-vmware.ps" \"http://127.0.0.1:8086/write?db=vmware&u=user&p=password&precision=s\"" 32 | ``` 33 | -------------------------------------------------------------------------------- /metrics-vmware.ps: -------------------------------------------------------------------------------- 1 | <# 2 | .DESCRIPTION 3 | 4 | Use VMware module to connect to vCenter and output all metrics on systems in influxdb line format 5 | 6 | .EXAMPLE 7 | 8 | CI: 9 | metrics-vmware.ps 'https://influxdb.example.ca:8086/write?db=math&u=telegraf&p=???????&precision=s' 10 | 11 | telegraf.cfg: 12 | [[inputs.exec]] 13 | commands = [ 14 | '"C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe" -File "C:\Program Files\Telegraf\vmware_collect_stats.ps1"', 15 | ] 16 | data_format = "influx" 17 | timeout = "25m" 18 | interval = "30m" 19 | 20 | #> 21 | # Allow common parameters 22 | [CmdletBinding()] 23 | 24 | ## if uri is set, send metrics directly to influx not to stdout 25 | # 'https://influxdb.example.ca:8086/write?db=math&u=telegraf&p=???????&precision=s' 26 | $uri=$args[0] 27 | $vc_host=$(hostname) 28 | 29 | # Requirements 30 | try { 31 | $powercli = Get-PSSnapin -Name VMware.VimAutomation.Core -Registered 32 | if ($powercli.Version.Major -ge 6) { 33 | Import-Module -Name VMware.VimAutomation.Core -ErrorAction Stop 34 | } else { 35 | Add-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction Stop 36 | Write-Warning -Message 'PowerCLI 5 snapin added; recommend upgrading your PowerCLI version' 37 | } 38 | } 39 | catch { 40 | write-eventlog -logname Application -source "Telegraf - VMware collect" -eventID 404 -entrytype Error -message 'missing modules vCenter' 41 | throw 'missing modules vCenter' 42 | } 43 | 44 | 45 | # Ignore self-signed SSL certificates for vCenter Server (optional) 46 | $null = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -DisplayDeprecationWarnings:$false -Scope User -Confirm:$false 47 | # Connect to vCenter 48 | $null = Connect-VIServer $vc_host -ErrorAction Stop 49 | # default server mode 50 | 51 | 52 | function handle_stat($h) { 53 | $name = $h.Name -replace ' ', '_' 54 | Write-Debug -Message "Working on: $name" 55 | if ($h.PowerState -eq 'PoweredOff') { 56 | Write-Debug -Message '* skip PoweredOff' 57 | return 58 | } 59 | $fb = "" 60 | 61 | if ($h.VMHost) { 62 | $fb = $fb + "vmware_guest,host=$name,esxi_host=$($h.VMHost.Name) " 63 | $fb = $fb + "cpu_NumCpu=$($h.NumCpu)," 64 | $fb = $fb + "mem_MemoryMB=$([math]::round($h.MemoryMB,0))," 65 | $fb = $fb + "disk_ProvisionedSpaceGB=$([math]::round($h.ProvisionedSpaceGB,2))," 66 | $fb = $fb + "disk_UsedSpaceGB=$([math]::round($h.UsedSpaceGB,2)) `n" 67 | } else { 68 | # is esxi host 69 | $fb = $fb + "vmware_esxi,host=$name " 70 | $fb = $fb + "cpu_NumCpu=$($h.NumCpu)," 71 | $fb = $fb + "cpu_CpuTotalMhz=$($h.CpuTotalMhz)," 72 | $fb = $fb + "cpu_CpuUsageMhz=$($h.CpuUsageMhz)," 73 | $fb = $fb + "mem_MemoryTotalMB=$([math]::round($h.MemoryTotalMB,0))," 74 | $fb = $fb + "mem_MemoryUsageMB=$([math]::round($h.MemoryUsageMB,0)) `n" 75 | } 76 | $trust = 20 77 | $stats_map = @{} 78 | $stats = Get-Stat -Entity $h -Stat '*' -Instance '' -Realtime -MaxSamples 1 79 | foreach ($m in $stats) { 80 | $mi = $m.MetricId 81 | $mv = $m.Value 82 | if ($mv -eq 1) { 83 | # some trust issues when value is one... if tomany ones dont trust. 84 | $trust = $trust - 1 85 | } 86 | if ($mv -is [float] -or $mv -is [double]) { 87 | $mv = $([math]::round($mv,5)) 88 | } else { 89 | $mv = "$([math]::floor($mv))" 90 | } 91 | $mia = $mi.Split('.', 2) 92 | if ($stats_map.ContainsKey($mia[0])) { 93 | $stats_map.Item($mia[0]).add($mia[1], $mv) 94 | } else { 95 | $stats_map.add($mia[0], @{}) 96 | $stats_map.Item($mia[0]).add($mia[1], $mv) 97 | } 98 | if ($mi -eq 'cpu.usage.average') { 99 | $stats_map.Item($mia[0]).add("$($mia[1])_cores", $([math]::round($mv * $h.NumCpu, 3))) 100 | } 101 | } 102 | if ($trust -lt 0) { 103 | # stats with tomany values of one, smells of error 104 | Write-Debug -Message $fb 105 | Write-Debug -Message '* data not trusted' 106 | return 1 107 | } 108 | foreach ($k in $stats_map.Keys) { 109 | $fb = $fb + "vmware_$k,host=$name " 110 | foreach ($s in $stats_map[$k].Keys) { 111 | $sname = $s 112 | #$sname = $sname.Replace('.', '_') 113 | $sname = $sname.Replace(' ', '_') 114 | $sname = $sname.Replace('[', '_') 115 | $sname = $sname.Replace(']', '_') 116 | $fb = $fb + "$sname=$($stats_map["$k"]["$s"])," 117 | } 118 | $fb = $fb.TrimEnd(',') + " `n" 119 | } 120 | 121 | if ($uri) { 122 | $r = Invoke-WebRequest -Uri $uri -Body $fb -Method Post -UseBasicParsing -ErrorAction:Stop 123 | } else { 124 | Write-Host -NoNewline $fb 125 | } 126 | return 0 127 | } 128 | 129 | 130 | function handle_stat_safe($h, $pfix) { 131 | # preform a retry if error code 1 132 | $r = handle_stat $h $pfix 133 | if ($r -eq 1) { 134 | $r = handle_stat $h $pfix 135 | } 136 | } 137 | 138 | 139 | try { 140 | # Collect host and vm stats 141 | $vmhosts = Get-VMHost 142 | foreach ($vmhost in $vmhosts) { 143 | handle_stat_safe $vmhost 144 | } 145 | $vms = Get-VM 146 | foreach ($vm in $vms) { 147 | handle_stat_safe $vm 148 | } 149 | } 150 | catch { 151 | write-eventlog -logname Application -source "Telegraf - VMware collect" -eventID 404 -entrytype Error -message $_.Exception.Message 152 | } 153 | Finally { 154 | Disconnect-VIServer -Confirm:$false 155 | } 156 | --------------------------------------------------------------------------------