├── CHANGELOG.md ├── README.md ├── VMPerf-Sample-Batchfile.cmd ├── VMPerf-Sample-Dashboard.json └── VMPerf-To-Graphite.ps1 /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v1.5.2 (2016-11-30) 2 | * **[FIXED]** Fixed a problem with PowerCLI 6.5. Fixed [#8] (https://github.com/mothe-at/VMPerf-To-Graphite-PowerShell-Script/issues/8) 3 | * **[ADDED]** Ability to omit the "-User" and "-Password" switches to log in to the vCenter server using current credentials. Fixed [#9] (https://github.com/mothe-at/VMPerf-To-Graphite-PowerShell-Script/issues/9) 4 | 5 | # v1.5.1 (2016-09-29) 6 | * **[FIXED]** Changed Encoding of Script to UTF-8 7 | * **[FIXED]** Fixed a bug that causes wrong number of IOPS and KBs with multiple vDisks 8 | * **[FIXED]** Calculate the weighted average of the read and write latency of all disks instead of the simple average 9 | 10 | # v1.5.0 (2016-06-04) 11 | * **[ADDED]** Added feature to send metrics to more than one carbon host at a time. Fixed [#2] (https://github.com/mothe-at/VMPerf-To-Graphite-PowerShell-Script/issues/2) 12 | * **[ADDED]** Ability to add portnumber for carbon server with the hostname (`-Graphiteserver [:][,[:][,...]]`) 13 | 14 | # v1.4.0 (2016-05-20) 15 | * **[FIXED]** Parameter "-EventLogLevel None" could lead to an error message. 16 | * **[ADDED]** Parameter "-FromLastPoll ". If this parameter is set, the script will try to receive all metrics from the VCenter Server starting at the date and time of the last poll up to the most recent data (Real-Time). Best practice if you are using a scheduler to run the script with only one iteration. Check help for more information. 17 | 18 | # v1.3.1 (2016-01-13) 19 | * **[ADDED]** Check for Powershell Version. Script will abort if it is below Version 4.0 20 | 21 | # v1.3.0 (2015-09-05) 22 | * Initial published Release 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #VMPerf-To-Graphite 2 | A comprehensive PowerShell Script to read Virtual Machine statistics from vCenter and send the results to Graphite/Grafana. It pulls Disk and CPU metrics from the "Realtime" statistics in VCenter, aggregates the data and sends them to carbon (which is the data-receiver for Graphite). 3 | The script is easy to setup and maintain, should be running in one minute. 4 | 5 | ![](http://rettl.org/scripts/VMPerf-Grafana-Screenshot.png) 6 | 7 | ## Prerequisites 8 | - Make sure you have installed [VMWare PowerCLI] (https://www.vmware.com/support/developer/PowerCLI/) v5.8 or above on the machine where the script will run. 9 | - Check the [Version of PowerShell] (http://stackoverflow.com/questions/1825585/determine-installed-powershell-version) and update it to [PowerShell v4] (https://www.microsoft.com/en-US/download/details.aspx?id=40855) or above (POSH 2.x will cause problems, the Script will abort if the PowerShell Version is <4). 10 | - Check if the ["Statistics Level" in VCenter] (http://rettl.org/scripts/vcenter.png) for the shortest period is set to "Level 2" or higher. 11 | - Download the VMPerf-To-Graphite.ps1 script and save it on your server. 12 | - **DO NOT RUN THE SCRIPT FROM PowerShell ISE, IT WILL FAIL!** Open a PowerShell Prompt and run the script from there. 13 | - Open a new PowerShell Window, read the documentation of the script carefully and discover all the various options and parameters (call `PS C:\PS> Get-Help VMPerf-To-Graphite.ps1 -full`). 14 | - The script is not signed, if you receive an Execution Policy Error, just execute `PS C:\PS> Set-ExecutionPolicy Unrestricted` and it should work. 15 | 16 | ## How to use the script? 17 | ### Modes of Operation 18 | Usually you would like to collect statistics 24/7, having the most accurate numbers in Graphite/Grafana. Remember that collecting data from VSphere and feeding them into Graphite a) takes some time, depending on the size of your deployment, the performance of your VCenter Server, the network connection speed, etc. and b) takes some resources, CPU, memory, storage. 19 | 20 | Pulling data from VCenter is done by an API which is good, but not really ultra-fast. A collection of 1.000 VMs can take a few minutes, running the script every 10 seconds makes no sense. But this is not a big problem, even if you pull data just every 30 minutes, you will find statistics data much more granular in your graphs. If the values are collected, sending them to Carbon is just a matter of seconds or even less, even over slow WAN links. 21 | 22 | A good practice could be pulling data every 15 minutes for small/medium deployments (500 VMs or below) or 30 minutes for larger scale enterprises. 23 | 24 | There are two ways you can infinitely run the script: 25 | 26 | #### Method 1: Use Windows Task Scheduler to call the script every n minutes 27 | This is the best practice. You call the script in your desired interval with Windows Task Scheduler or any other scheduling service of your choice. Calling it with the appropriate parameters will let the script run forever, even if something went wrong with PowerShell, PowerCLI or something else. 28 | 29 | To achive this, the script must "know" about the last time statistics were successfully collected from VCenter. If so, the script will try to pull all statistics data from the time of the last run up till now. To remember date and time of the last poll the script will save this information in an XML file. You have to specify the path and filename of this XLM file with the parameter `-FromLastPoll `. Lets say you are pulling data from several different VCenter Servers, you have to specify a unique filename for each job. 30 | 31 | You also have to tell the script just to run once and then quit using the `-Iterations 1` parameter. 32 | 33 | 34 | Calling the script could look something like this: 35 | 36 | `PS C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass 37 | -Graphiteserver graphite1.it.acme.com -Iterations 1 -FromLastPoll Vienna_Poll.xml` 38 | 39 | It does not matter if you wait 5 minutes or 30 minutes until you run the script the next time, it will gather all metrics starting at the time of the last succesfull poll. But remember that VCenter only stores real-time data for the last hour! 40 | 41 | #### Method 2: Call the script and let it control the iterations and sleep-times 42 | This is the second way, you call the script once without the `-Iterations` parameter and it will run forever (or until you cancel it). Here you can specify the `-Sleepseconds ` parameter which controls the time it waits after each iteration. 43 | 44 | The script has extensive error handling but nevertheless it could happen that a PowerShell or PowerCLI process unexpetedly stopps or, even worse, hangs and does not return control back to the script. It could take hours until you realize that no data is collected for a certain amount of time and, murphy sais, you will for sure need this data desperately. 45 | 46 | To call the script to run infinitely, waiting 5 minutes between each iteration, call this: 47 | 48 | `PS C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass 49 | -Sleepseconds 300 -Graphiteserver graphite1.it.acme.com -Group Vienna` 50 | 51 | ## Some additional notes 52 | - By design principles a PowerShell Script should not generate any output, unless an error orrurs. We follow this principle and if you want to see what the script is doing, add the `-Verbose` parameter to your call. 53 | - For the user who will access VCenter, read-only permissions are enough. 54 | 55 | ## To-Do List 56 | - [ ] Ability to read from non-clustered ESX implementations. 57 | 58 | ## Syntax 59 | `VMPerf-To-Graphite.ps1 [[-Server] ] [[-User] ] [[-Password] ] [[-Protocol] ] [[-Datacenter] ] [[-Cluster] ] [[-Graphiteserver] ] [[-Graphiteserverport] ] [[-Group] ] [[-Iterations] ] [[-FromLastPoll] ] [[-Sleepseconds] ] [-Whatif] [[-EventLogLevel] ] []` 60 | 61 | ### Parameters and Description 62 | ``` 63 | -Server 64 | Specifies the IP address or the DNS name of the vCenter server to which you want to connect. 65 | 66 | Required? false 67 | Position? 1 68 | Default value your_default_vcenter_server 69 | Accept pipeline input? false 70 | Accept wildcard characters? false 71 | 72 | -User 73 | Specifies the user name you want to use for authenticating with the vCenter server. 74 | If this parameter is omitted, the currently logged on user will be used to authenticate with vCenter server. 75 | Required? false 76 | Position? 2 77 | Default value vcenter_user 78 | Accept pipeline input? false 79 | Accept wildcard characters? false 80 | 81 | -Password 82 | Specifies the password you want to use for authenticating with the vCenter server. 83 | 84 | Required? false 85 | Position? 3 86 | Default value vcenter_password 87 | Accept pipeline input? false 88 | Accept wildcard characters? false 89 | 90 | -Protocol 91 | Specifies the Internet protocol you want to use for the connection. It can be either http or https. 92 | 93 | Required? false 94 | Position? 4 95 | Default value https 96 | Accept pipeline input? false 97 | Accept wildcard characters? false 98 | 99 | -Datacenter 100 | Specifies the VMWare Datacenters you want to receive data from. Default is to read all Clusters 101 | managed by VCenter server. 102 | 103 | Required? false 104 | Position? 5 105 | Default value * 106 | Accept pipeline input? false 107 | Accept wildcard characters? false 108 | 109 | -Cluster 110 | Specifies the VMWare Clusters you want to receive data from. Default is to read all Clusters managed 111 | by VCenter server or, if -Datacenter is specified, all Clusters in this Datacenter. 112 | 113 | Required? false 114 | Position? 6 115 | Default value * 116 | Accept pipeline input? false 117 | Accept wildcard characters? false 118 | 119 | -Graphiteserver 120 | Specifies one or more (separated by comma) IP addresses or the DNS names of the Graphite servers 121 | which you want to connect to. 122 | You can also add the Portnumber to each Server like "grafana.acme.com:2003" 123 | 124 | Required? false 125 | Position? 7 126 | Default value your_default_grafana_server 127 | Accept pipeline input? false 128 | Accept wildcard characters? false 129 | 130 | -Graphiteserverport 131 | Specifies the port on the Graphite server you want to use for the connection. Defaults to 2003. 132 | You can also add the portnumber to the servers hostname or IP address in the -Graphiteserver parameter. 133 | 134 | Required? false 135 | Position? 8 136 | Default value 2003 137 | Accept pipeline input? false 138 | Accept wildcard characters? false 139 | 140 | -Group 141 | Specifies the Group, an additional prefix for the metrics path in Graphite. 142 | The metrics path will be "vmperf.." 143 | 144 | Required? false 145 | Position? 9 146 | Default value Default 147 | Accept pipeline input? false 148 | Accept wildcard characters? false 149 | 150 | -Iterations 151 | Specifies the number of iterations. 0 = indefinitely. 152 | 153 | Required? false 154 | Position? 10 155 | Default value 0 156 | Accept pipeline input? false 157 | Accept wildcard characters? false 158 | 159 | -FromLastPoll 160 | Optional path and name of an .xml file where the date and time of the last poll will be saved. If the 161 | file does not exist, it will be created and overwritten after each poll. 162 | If this parameter is set, the script will try to receive all metrics from the VCenter Server starting 163 | at the date and time of the last poll up to the most recent data (Real-Time). 164 | This is useful if you want to schedule the script externally (with Task Scheduler, for instance) and you 165 | want to use the "-Iterations 1" parameter. But be careful, VCenter stores the Real-Time statistics just 166 | for a limited number of time (1 hour per default). 167 | 168 | Required? false 169 | Position? 11 170 | Default value 171 | Accept pipeline input? false 172 | Accept wildcard characters? false 173 | 174 | -Sleepseconds 175 | Specifies the number of seconds to wait between iterations. The counter starts after the last statistics 176 | have been sent to Graphite. 177 | Note that VCenter is collecting its performance statistics every 20 seconds and saves an average of the 178 | collected counters. It makes no sense to specify a value below 20 seconds here. The script reads the so 179 | called "Realtime" counters from VCenter which will be kept there for one hour. So do not use anything 180 | above 3600 seconds. 181 | The script requests all statistics data from VCenter server since the last time they were requested, 182 | regardless of how long the Sleepseconds parameter was set. You wont miss any data. 183 | 184 | Required? false 185 | Position? 12 186 | Default value 60 187 | Accept pipeline input? false 188 | Accept wildcard characters? false 189 | 190 | -Whatif [] 191 | Indicate that the cmdlet will process but will NOT send any metrics to Graphite, instead display a list 192 | of metrics that would be sent to Graphite. 193 | 194 | Required? false 195 | Position? named 196 | Default value False 197 | Accept pipeline input? false 198 | Accept wildcard characters? false 199 | 200 | -EventLogLevel 201 | Set the Log-Level for writing events to the Windows Aplication log. Valid values are Error, Warning, 202 | Information, and None. The default value is Warning. 203 | Note that if you like to use logging to the Windows Event Log, you have to run this script at least once 204 | with administrative privileges on this computer! 205 | 206 | Required? false 207 | Position? 13 208 | Default value Warning 209 | Accept pipeline input? false 210 | Accept wildcard characters? false 211 | 212 | 213 | This cmdlet supports the common parameters: Verbose, Debug, ErrorAction, ErrorVariable, 214 | WarningAction, WarningVariable, 215 | OutBuffer, PipelineVariable, and OutVariable. For more information, see about_CommonParameters 216 | (http://go.microsoft.com/fwlink/?LinkID=113216). 217 | ``` 218 | 219 | ## Examples 220 | ### Example 1 221 | `C:\PS> VMPerf-To-Graphite.ps1 -Verbose` 222 | Use default values from within this script and display the status output on the screen. 223 | ### Example 2 224 | `C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Graphiteserver graphite1.it.acme.com -Iterations 1 -FromLastPoll Vienna_Poll.xml` 225 | Run the cmdlet just once. Write the date and time of the Poll to Vienna_Poll.xml. The next time the script runs, it will read the file and gather the metrics from VCenter starting at the last poll. 226 | ### Example 3 227 | `C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Graphiteserver graphite1.it.acme.com,graphdev.it.acme.com:62033 -Iterations 1 -FromLastPoll Vienna_Poll.xml` 228 | Same as above but send the metrics to two servers, graphite1.it.acme.com at (default) port 2003 and graphdev.it.acme.com on port 62033. 229 | ### Example 4 230 | `C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Sleepseconds 300 -Graphiteserver graphite1.it.acme.com -Group Vienna` 231 | Read the counters from the VCenter server myvcenter.vienna.acme.com, send the metrics to graphite1.it.acme.com with a metrics path of "vmperf.Vienna." and then wait 5 minutes before the next iteration. 232 | ### Example 5 233 | `C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Sleepseconds 300 -Graphiteserver graphite1.it.acme.com -Group Vienna -Cluster TESTDEV` 234 | Read the counters from Cluster TESTDEV in the VCenter server myvcenter.vienna.acme.com, send the metrics to graphite1.it.acme.com with a metrics path of "vmperf.Vienna." and then wait 5 minutes before the next iteration. 235 | ### Example 6 236 | `C:\PS> VMPerf-To-Graphite.ps1 -Verbose -Iterations 1 -WhatIf | Out-GridView` 237 | Run the cmdlet just once, but do not send the metrics to Graphite, instead open a window and display the results. 238 | 239 | ## Licensing 240 | This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License] (http://creativecommons.org/licenses/by-nc-sa/4.0/). 241 | 242 | It is free-of-charge and it comes without any warranty, to the extent permitted by applicable law. 243 | 244 | 245 | -------------------------------------------------------------------------------- /VMPerf-Sample-Batchfile.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM ============================================================================================================= 3 | REM VMPerf-To-Graphite-PowerShell-Script 4 | REM 5 | REM Sample Batch-File you can run from Windows Scheduled Tasks. (Every 10 minues, for instance) 6 | REM Please adjust the SET Variables accordingly 7 | REM PLEASE AVOID ANY SPECIAL CHARACTERS, ESPECIALLY IN THE "VMP_GROUP" FIELD (Use a-z0-9, no Blanks, no Periods!) 8 | REM 9 | REM ============================================================================================================= 10 | REM https://github.com/mothe-at/VMPerf-To-Graphite-PowerShell-Script 11 | REM ============================================================================================================= 12 | 13 | cd /D C:\VMPerf 14 | 15 | SET VMP_VCENTER_SERVER = YOUR_VCENTER_SERVER 16 | SET VMP_VCENTER_USER = YOUR_VCENTER_USER 17 | SET VMP_VCENTER_PASS = YOUR_VCENTER_PASSWORD 18 | SET VMP_GRAPHITE_SERVER = YOUR_GRAPHITE_SERVER[:PORT] 19 | SET VMP_GROUP = YOUR_GROUP 20 | 21 | powershell.exe .\VMPerf-To-Graphite.ps1 -server %VMP_VCENTER_SERVER% -user %VMP_VCENTER_USER% -password %VMP_VCENTER_PASS% -Graphiteserver %VMP_GRAPHITE_SERVER% -Iterations 1 -Group %VMP_GROUP% -EventLogLevel Warning -FromLastPoll VMPerf_%VMP_GROUP%.xml -Verbose >> VMPerf_%VMP_GROUP%.log 2>&1 22 | 23 | -------------------------------------------------------------------------------- /VMPerf-Sample-Dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "VMPerf Virtual Machines", 3 | "originalTitle": "VMPerf Virtual Machines", 4 | "tags": [ 5 | "MatthiasR", 6 | "VMPerf" 7 | ], 8 | "style": "dark", 9 | "timezone": "browser", 10 | "editable": true, 11 | "hideControls": false, 12 | "sharedCrosshair": true, 13 | "rows": [ 14 | { 15 | "collapse": true, 16 | "editable": true, 17 | "height": "350px", 18 | "panels": [ 19 | { 20 | "columns": [ 21 | { 22 | "text": "Current", 23 | "value": "current" 24 | } 25 | ], 26 | "editable": true, 27 | "error": false, 28 | "fontSize": "90%", 29 | "height": "200", 30 | "id": 29, 31 | "isNew": true, 32 | "links": [], 33 | "pageSize": null, 34 | "scroll": false, 35 | "showHeader": true, 36 | "sort": { 37 | "col": 1, 38 | "desc": true 39 | }, 40 | "span": 2, 41 | "styles": [ 42 | { 43 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 44 | "pattern": "Time", 45 | "type": "date" 46 | }, 47 | { 48 | "colorMode": "row", 49 | "colors": [ 50 | "rgba(50, 172, 45, 0.78)", 51 | "rgba(237, 129, 40, 0.89)", 52 | "rgba(245, 54, 54, 0.49)" 53 | ], 54 | "decimals": 0, 55 | "pattern": "/.*/", 56 | "thresholds": [ 57 | "1000", 58 | "2000" 59 | ], 60 | "type": "number", 61 | "unit": "short" 62 | } 63 | ], 64 | "targets": [ 65 | { 66 | "refId": "A", 67 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.TotalIOPS, $TopResources), 2)" 68 | } 69 | ], 70 | "title": "Current IOPS", 71 | "transform": "timeseries_aggregations", 72 | "type": "table" 73 | }, 74 | { 75 | "columns": [ 76 | { 77 | "text": "Current", 78 | "value": "current" 79 | } 80 | ], 81 | "editable": true, 82 | "error": false, 83 | "fontSize": "90%", 84 | "height": "200", 85 | "id": 30, 86 | "isNew": true, 87 | "links": [], 88 | "pageSize": null, 89 | "scroll": false, 90 | "showHeader": true, 91 | "sort": { 92 | "col": 1, 93 | "desc": true 94 | }, 95 | "span": 2, 96 | "styles": [ 97 | { 98 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 99 | "pattern": "Time", 100 | "type": "date" 101 | }, 102 | { 103 | "colorMode": "row", 104 | "colors": [ 105 | "rgba(50, 172, 45, 0.78)", 106 | "rgba(237, 129, 40, 0.89)", 107 | "rgba(245, 54, 54, 0.49)" 108 | ], 109 | "decimals": 0, 110 | "pattern": "/.*/", 111 | "thresholds": [ 112 | "10000", 113 | "20000" 114 | ], 115 | "type": "number", 116 | "unit": "KBs" 117 | } 118 | ], 119 | "targets": [ 120 | { 121 | "refId": "A", 122 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.TotalKBps, $TopResources), 2)" 123 | } 124 | ], 125 | "title": "Current Throughput", 126 | "transform": "timeseries_aggregations", 127 | "type": "table" 128 | }, 129 | { 130 | "columns": [ 131 | { 132 | "text": "Current", 133 | "value": "current" 134 | } 135 | ], 136 | "editable": true, 137 | "error": false, 138 | "fontSize": "90%", 139 | "height": "200", 140 | "id": 31, 141 | "isNew": true, 142 | "links": [], 143 | "pageSize": null, 144 | "scroll": false, 145 | "showHeader": true, 146 | "sort": { 147 | "col": 1, 148 | "desc": true 149 | }, 150 | "span": 2, 151 | "styles": [ 152 | { 153 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 154 | "pattern": "Time", 155 | "type": "date" 156 | }, 157 | { 158 | "colorMode": "row", 159 | "colors": [ 160 | "rgba(50, 172, 45, 0.78)", 161 | "rgba(237, 129, 40, 0.89)", 162 | "rgba(245, 54, 54, 0.49)" 163 | ], 164 | "decimals": 0, 165 | "pattern": "/.*/", 166 | "thresholds": [ 167 | "60", 168 | "80" 169 | ], 170 | "type": "number", 171 | "unit": "percent" 172 | } 173 | ], 174 | "targets": [ 175 | { 176 | "refId": "A", 177 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.CPU, $TopResources), 2)" 178 | } 179 | ], 180 | "title": "Current CPU", 181 | "transform": "timeseries_aggregations", 182 | "type": "table" 183 | }, 184 | { 185 | "columns": [ 186 | { 187 | "text": "Current", 188 | "value": "current" 189 | } 190 | ], 191 | "editable": true, 192 | "error": false, 193 | "fontSize": "90%", 194 | "height": "200", 195 | "id": 32, 196 | "isNew": true, 197 | "links": [], 198 | "pageSize": null, 199 | "scroll": false, 200 | "showHeader": true, 201 | "sort": { 202 | "col": 1, 203 | "desc": true 204 | }, 205 | "span": 3, 206 | "styles": [ 207 | { 208 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 209 | "pattern": "Time", 210 | "type": "date" 211 | }, 212 | { 213 | "colorMode": "row", 214 | "colors": [ 215 | "rgba(50, 172, 45, 0.78)", 216 | "rgba(237, 129, 40, 0.89)", 217 | "rgba(245, 54, 54, 0.49)" 218 | ], 219 | "decimals": 1, 220 | "pattern": "/.*/", 221 | "thresholds": [ 222 | "15", 223 | "30" 224 | ], 225 | "type": "number", 226 | "unit": "ms" 227 | } 228 | ], 229 | "targets": [ 230 | { 231 | "refId": "A", 232 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.ReadLatency, $TopResources), 2)" 233 | } 234 | ], 235 | "title": "Current Read Latency", 236 | "transform": "timeseries_aggregations", 237 | "type": "table" 238 | }, 239 | { 240 | "columns": [ 241 | { 242 | "text": "Current", 243 | "value": "current" 244 | } 245 | ], 246 | "editable": true, 247 | "error": false, 248 | "fontSize": "90%", 249 | "height": "200", 250 | "id": 33, 251 | "isNew": true, 252 | "links": [], 253 | "pageSize": null, 254 | "scroll": false, 255 | "showHeader": true, 256 | "sort": { 257 | "col": 1, 258 | "desc": true 259 | }, 260 | "span": 3, 261 | "styles": [ 262 | { 263 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 264 | "pattern": "VM", 265 | "type": "string" 266 | }, 267 | { 268 | "colorMode": "row", 269 | "colors": [ 270 | "rgba(50, 172, 45, 0.78)", 271 | "rgba(237, 129, 40, 0.89)", 272 | "rgba(245, 54, 54, 0.49)" 273 | ], 274 | "decimals": 1, 275 | "pattern": "/.*/", 276 | "thresholds": [ 277 | "15", 278 | "30" 279 | ], 280 | "type": "number", 281 | "unit": "ms" 282 | } 283 | ], 284 | "targets": [ 285 | { 286 | "refId": "A", 287 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.WriteLatency, $TopResources), 2)" 288 | } 289 | ], 290 | "title": "Current Write Latency", 291 | "transform": "timeseries_aggregations", 292 | "type": "table" 293 | }, 294 | { 295 | "aliasColors": {}, 296 | "bars": false, 297 | "datasource": null, 298 | "editable": true, 299 | "error": false, 300 | "fill": 1, 301 | "grid": { 302 | "threshold1": null, 303 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 304 | "threshold2": null, 305 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 306 | }, 307 | "height": "", 308 | "id": 24, 309 | "legend": { 310 | "alignAsTable": true, 311 | "avg": true, 312 | "current": true, 313 | "max": true, 314 | "min": false, 315 | "rightSide": false, 316 | "show": true, 317 | "sort": "current", 318 | "sortDesc": true, 319 | "total": false, 320 | "values": true 321 | }, 322 | "lines": true, 323 | "linewidth": 2, 324 | "links": [], 325 | "nullPointMode": "connected", 326 | "percentage": false, 327 | "pointradius": 5, 328 | "points": false, 329 | "renderer": "flot", 330 | "seriesOverrides": [], 331 | "span": 4, 332 | "stack": false, 333 | "steppedLine": false, 334 | "targets": [ 335 | { 336 | "refId": "A", 337 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.TotalIOPS, $TopResources), 2)" 338 | } 339 | ], 340 | "timeFrom": null, 341 | "timeShift": null, 342 | "title": "TOP $TopResources VM Current IOPS", 343 | "tooltip": { 344 | "msResolution": false, 345 | "shared": true, 346 | "value_type": "cumulative" 347 | }, 348 | "type": "graph", 349 | "xaxis": { 350 | "show": true 351 | }, 352 | "yaxes": [ 353 | { 354 | "format": "short", 355 | "logBase": 1, 356 | "max": null, 357 | "min": null, 358 | "show": true 359 | }, 360 | { 361 | "format": "short", 362 | "logBase": 1, 363 | "max": null, 364 | "min": null, 365 | "show": true 366 | } 367 | ] 368 | }, 369 | { 370 | "aliasColors": {}, 371 | "bars": false, 372 | "datasource": null, 373 | "decimals": 0, 374 | "editable": true, 375 | "error": false, 376 | "fill": 1, 377 | "grid": { 378 | "threshold1": null, 379 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 380 | "threshold2": null, 381 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 382 | }, 383 | "height": "", 384 | "id": 25, 385 | "legend": { 386 | "alignAsTable": true, 387 | "avg": true, 388 | "current": true, 389 | "max": true, 390 | "min": false, 391 | "rightSide": false, 392 | "show": true, 393 | "sort": "current", 394 | "sortDesc": true, 395 | "total": false, 396 | "values": true 397 | }, 398 | "lines": true, 399 | "linewidth": 2, 400 | "links": [], 401 | "nullPointMode": "connected", 402 | "percentage": false, 403 | "pointradius": 5, 404 | "points": false, 405 | "renderer": "flot", 406 | "seriesOverrides": [], 407 | "span": 4, 408 | "stack": false, 409 | "steppedLine": false, 410 | "targets": [ 411 | { 412 | "refId": "A", 413 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.TotalKBps, $TopResources), 2)" 414 | } 415 | ], 416 | "timeFrom": null, 417 | "timeShift": null, 418 | "title": "TOP $TopResources VM Current Throughput", 419 | "tooltip": { 420 | "msResolution": false, 421 | "shared": true, 422 | "value_type": "cumulative" 423 | }, 424 | "type": "graph", 425 | "xaxis": { 426 | "show": true 427 | }, 428 | "yaxes": [ 429 | { 430 | "format": "kbytes", 431 | "logBase": 1, 432 | "max": null, 433 | "min": null, 434 | "show": true 435 | }, 436 | { 437 | "format": "short", 438 | "logBase": 1, 439 | "max": null, 440 | "min": null, 441 | "show": true 442 | } 443 | ] 444 | }, 445 | { 446 | "aliasColors": {}, 447 | "bars": false, 448 | "datasource": null, 449 | "editable": true, 450 | "error": false, 451 | "fill": 1, 452 | "grid": { 453 | "threshold1": null, 454 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 455 | "threshold2": null, 456 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 457 | }, 458 | "height": "", 459 | "id": 26, 460 | "legend": { 461 | "alignAsTable": true, 462 | "avg": true, 463 | "current": true, 464 | "max": true, 465 | "min": false, 466 | "rightSide": false, 467 | "show": true, 468 | "sort": "current", 469 | "sortDesc": true, 470 | "total": false, 471 | "values": true 472 | }, 473 | "lines": true, 474 | "linewidth": 2, 475 | "links": [], 476 | "nullPointMode": "connected", 477 | "percentage": false, 478 | "pointradius": 5, 479 | "points": false, 480 | "renderer": "flot", 481 | "seriesOverrides": [], 482 | "span": 4, 483 | "stack": false, 484 | "steppedLine": false, 485 | "targets": [ 486 | { 487 | "refId": "A", 488 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.CPU, $TopResources), 2)" 489 | } 490 | ], 491 | "timeFrom": null, 492 | "timeShift": null, 493 | "title": "TOP $TopResources VM Current CPU", 494 | "tooltip": { 495 | "msResolution": false, 496 | "shared": true, 497 | "value_type": "cumulative" 498 | }, 499 | "type": "graph", 500 | "xaxis": { 501 | "show": true 502 | }, 503 | "yaxes": [ 504 | { 505 | "format": "percent", 506 | "logBase": 1, 507 | "max": 100, 508 | "min": null, 509 | "show": true 510 | }, 511 | { 512 | "format": "short", 513 | "logBase": 1, 514 | "max": null, 515 | "min": null, 516 | "show": true 517 | } 518 | ] 519 | }, 520 | { 521 | "aliasColors": {}, 522 | "bars": false, 523 | "datasource": null, 524 | "decimals": 1, 525 | "editable": true, 526 | "error": false, 527 | "fill": 1, 528 | "grid": { 529 | "threshold1": 20, 530 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 531 | "threshold2": 50, 532 | "threshold2Color": "rgba(234, 112, 112, 0.22)", 533 | "thresholdLine": false 534 | }, 535 | "height": "", 536 | "id": 27, 537 | "legend": { 538 | "alignAsTable": true, 539 | "avg": true, 540 | "current": true, 541 | "max": true, 542 | "min": false, 543 | "rightSide": false, 544 | "show": true, 545 | "sort": "max", 546 | "sortDesc": true, 547 | "total": false, 548 | "values": true 549 | }, 550 | "lines": true, 551 | "linewidth": 1, 552 | "links": [], 553 | "nullPointMode": "connected", 554 | "percentage": false, 555 | "pointradius": 5, 556 | "points": false, 557 | "renderer": "flot", 558 | "seriesOverrides": [], 559 | "span": 6, 560 | "stack": false, 561 | "steppedLine": false, 562 | "targets": [ 563 | { 564 | "refId": "A", 565 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.ReadLatency, $TopResources), 2)" 566 | } 567 | ], 568 | "timeFrom": null, 569 | "timeShift": null, 570 | "title": "TOP $TopResources VM Current Read Latencies", 571 | "tooltip": { 572 | "msResolution": false, 573 | "shared": true, 574 | "value_type": "cumulative" 575 | }, 576 | "type": "graph", 577 | "xaxis": { 578 | "show": true 579 | }, 580 | "yaxes": [ 581 | { 582 | "format": "ms", 583 | "logBase": 1, 584 | "max": null, 585 | "min": null, 586 | "show": true 587 | }, 588 | { 589 | "format": "short", 590 | "logBase": 1, 591 | "max": null, 592 | "min": null, 593 | "show": true 594 | } 595 | ] 596 | }, 597 | { 598 | "aliasColors": {}, 599 | "bars": false, 600 | "datasource": null, 601 | "decimals": null, 602 | "editable": true, 603 | "error": false, 604 | "fill": 1, 605 | "grid": { 606 | "threshold1": 20, 607 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 608 | "threshold2": 50, 609 | "threshold2Color": "rgba(234, 112, 112, 0.22)", 610 | "thresholdLine": false 611 | }, 612 | "height": "", 613 | "id": 28, 614 | "legend": { 615 | "alignAsTable": true, 616 | "avg": true, 617 | "current": true, 618 | "max": true, 619 | "min": false, 620 | "rightSide": false, 621 | "show": true, 622 | "sort": "current", 623 | "sortDesc": true, 624 | "total": false, 625 | "values": true 626 | }, 627 | "lines": true, 628 | "linewidth": 1, 629 | "links": [], 630 | "nullPointMode": "connected", 631 | "percentage": false, 632 | "pointradius": 5, 633 | "points": false, 634 | "renderer": "flot", 635 | "seriesOverrides": [], 636 | "span": 6, 637 | "stack": false, 638 | "steppedLine": false, 639 | "targets": [ 640 | { 641 | "refId": "A", 642 | "target": "aliasByNode(highestCurrent(vmperf.$Group.$VM.WriteLatency, $TopResources), 2)" 643 | } 644 | ], 645 | "timeFrom": null, 646 | "timeShift": null, 647 | "title": "TOP $TopResources VM Current Write Latencies", 648 | "tooltip": { 649 | "msResolution": false, 650 | "shared": true, 651 | "value_type": "cumulative" 652 | }, 653 | "transparent": false, 654 | "type": "graph", 655 | "xaxis": { 656 | "show": true 657 | }, 658 | "yaxes": [ 659 | { 660 | "format": "ms", 661 | "logBase": 1, 662 | "max": null, 663 | "min": null, 664 | "show": true 665 | }, 666 | { 667 | "format": "short", 668 | "logBase": 1, 669 | "max": null, 670 | "min": null, 671 | "show": true 672 | } 673 | ] 674 | } 675 | ], 676 | "showTitle": true, 677 | "title": "Virtual Machines by Current Values" 678 | }, 679 | { 680 | "collapse": true, 681 | "editable": true, 682 | "height": "350px", 683 | "panels": [ 684 | { 685 | "columns": [ 686 | { 687 | "text": "Max", 688 | "value": "max" 689 | } 690 | ], 691 | "editable": true, 692 | "error": false, 693 | "fontSize": "90%", 694 | "id": 29, 695 | "isNew": true, 696 | "links": [], 697 | "pageSize": null, 698 | "scroll": false, 699 | "showHeader": true, 700 | "sort": { 701 | "col": 1, 702 | "desc": true 703 | }, 704 | "span": 2, 705 | "styles": [ 706 | { 707 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 708 | "pattern": "Time", 709 | "type": "date" 710 | }, 711 | { 712 | "colorMode": "row", 713 | "colors": [ 714 | "rgba(50, 172, 45, 0.78)", 715 | "rgba(237, 129, 40, 0.89)", 716 | "rgba(245, 54, 54, 0.49)" 717 | ], 718 | "decimals": 0, 719 | "pattern": "/.*/", 720 | "thresholds": [ 721 | "1000", 722 | "2000" 723 | ], 724 | "type": "number", 725 | "unit": "short" 726 | } 727 | ], 728 | "targets": [ 729 | { 730 | "refId": "A", 731 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.TotalIOPS, $TopResources), 2)" 732 | } 733 | ], 734 | "title": "Maximum IOPS", 735 | "transform": "timeseries_aggregations", 736 | "type": "table", 737 | "height": "200" 738 | }, 739 | { 740 | "columns": [ 741 | { 742 | "text": "Max", 743 | "value": "max" 744 | } 745 | ], 746 | "editable": true, 747 | "error": false, 748 | "fontSize": "90%", 749 | "id": 30, 750 | "isNew": true, 751 | "links": [], 752 | "pageSize": null, 753 | "scroll": false, 754 | "showHeader": true, 755 | "sort": { 756 | "col": 1, 757 | "desc": true 758 | }, 759 | "span": 2, 760 | "styles": [ 761 | { 762 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 763 | "pattern": "Time", 764 | "type": "date" 765 | }, 766 | { 767 | "colorMode": "row", 768 | "colors": [ 769 | "rgba(50, 172, 45, 0.78)", 770 | "rgba(237, 129, 40, 0.89)", 771 | "rgba(245, 54, 54, 0.49)" 772 | ], 773 | "decimals": 0, 774 | "pattern": "/.*/", 775 | "thresholds": [ 776 | "10000", 777 | "20000" 778 | ], 779 | "type": "number", 780 | "unit": "KBs" 781 | } 782 | ], 783 | "targets": [ 784 | { 785 | "refId": "A", 786 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.TotalKBps, $TopResources), 2)" 787 | } 788 | ], 789 | "title": "Maximum Throughput", 790 | "transform": "timeseries_aggregations", 791 | "type": "table", 792 | "height": "200" 793 | }, 794 | { 795 | "columns": [ 796 | { 797 | "text": "Max", 798 | "value": "max" 799 | } 800 | ], 801 | "editable": true, 802 | "error": false, 803 | "fontSize": "90%", 804 | "id": 31, 805 | "isNew": true, 806 | "links": [], 807 | "pageSize": null, 808 | "scroll": false, 809 | "showHeader": true, 810 | "sort": { 811 | "col": 1, 812 | "desc": true 813 | }, 814 | "span": 2, 815 | "styles": [ 816 | { 817 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 818 | "pattern": "Time", 819 | "type": "date" 820 | }, 821 | { 822 | "colorMode": "row", 823 | "colors": [ 824 | "rgba(50, 172, 45, 0.78)", 825 | "rgba(237, 129, 40, 0.89)", 826 | "rgba(245, 54, 54, 0.49)" 827 | ], 828 | "decimals": 0, 829 | "pattern": "/.*/", 830 | "thresholds": [ 831 | "60", 832 | "80" 833 | ], 834 | "type": "number", 835 | "unit": "percent" 836 | } 837 | ], 838 | "targets": [ 839 | { 840 | "refId": "A", 841 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.CPU, $TopResources), 2)" 842 | } 843 | ], 844 | "title": "Maximum CPU", 845 | "transform": "timeseries_aggregations", 846 | "type": "table", 847 | "height": "200" 848 | }, 849 | { 850 | "columns": [ 851 | { 852 | "text": "Max", 853 | "value": "max" 854 | } 855 | ], 856 | "editable": true, 857 | "error": false, 858 | "fontSize": "90%", 859 | "id": 32, 860 | "isNew": true, 861 | "links": [], 862 | "pageSize": null, 863 | "scroll": false, 864 | "showHeader": true, 865 | "sort": { 866 | "col": 1, 867 | "desc": true 868 | }, 869 | "span": 3, 870 | "styles": [ 871 | { 872 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 873 | "pattern": "Time", 874 | "type": "date" 875 | }, 876 | { 877 | "colorMode": "row", 878 | "colors": [ 879 | "rgba(50, 172, 45, 0.78)", 880 | "rgba(237, 129, 40, 0.89)", 881 | "rgba(245, 54, 54, 0.49)" 882 | ], 883 | "decimals": 1, 884 | "pattern": "/.*/", 885 | "thresholds": [ 886 | "15", 887 | "30" 888 | ], 889 | "type": "number", 890 | "unit": "ms" 891 | } 892 | ], 893 | "targets": [ 894 | { 895 | "refId": "A", 896 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.ReadLatency, $TopResources), 2)" 897 | } 898 | ], 899 | "title": "Maximum Read Latency", 900 | "transform": "timeseries_aggregations", 901 | "type": "table", 902 | "height": "200" 903 | }, 904 | { 905 | "columns": [ 906 | { 907 | "text": "Max", 908 | "value": "max" 909 | } 910 | ], 911 | "editable": true, 912 | "error": false, 913 | "fontSize": "90%", 914 | "id": 33, 915 | "isNew": true, 916 | "links": [], 917 | "pageSize": null, 918 | "scroll": false, 919 | "showHeader": true, 920 | "sort": { 921 | "col": 1, 922 | "desc": true 923 | }, 924 | "span": 3, 925 | "styles": [ 926 | { 927 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 928 | "pattern": "VM", 929 | "type": "string" 930 | }, 931 | { 932 | "colorMode": "row", 933 | "colors": [ 934 | "rgba(50, 172, 45, 0.78)", 935 | "rgba(237, 129, 40, 0.89)", 936 | "rgba(245, 54, 54, 0.49)" 937 | ], 938 | "decimals": 1, 939 | "pattern": "/.*/", 940 | "thresholds": [ 941 | "15", 942 | "30" 943 | ], 944 | "type": "number", 945 | "unit": "ms" 946 | } 947 | ], 948 | "targets": [ 949 | { 950 | "refId": "A", 951 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.WriteLatency, $TopResources), 2)" 952 | } 953 | ], 954 | "title": "Maximum Write Latency", 955 | "transform": "timeseries_aggregations", 956 | "type": "table", 957 | "height": "200" 958 | }, 959 | { 960 | "aliasColors": {}, 961 | "bars": false, 962 | "datasource": null, 963 | "editable": true, 964 | "error": false, 965 | "fill": 1, 966 | "grid": { 967 | "threshold1": null, 968 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 969 | "threshold2": null, 970 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 971 | }, 972 | "height": "", 973 | "id": 24, 974 | "legend": { 975 | "alignAsTable": true, 976 | "avg": true, 977 | "current": true, 978 | "max": true, 979 | "min": false, 980 | "rightSide": false, 981 | "show": true, 982 | "sort": "max", 983 | "sortDesc": true, 984 | "total": false, 985 | "values": true 986 | }, 987 | "lines": true, 988 | "linewidth": 2, 989 | "links": [], 990 | "nullPointMode": "connected", 991 | "percentage": false, 992 | "pointradius": 5, 993 | "points": false, 994 | "renderer": "flot", 995 | "seriesOverrides": [], 996 | "span": 4, 997 | "stack": false, 998 | "steppedLine": false, 999 | "targets": [ 1000 | { 1001 | "refId": "A", 1002 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.TotalIOPS, $TopResources), 2)" 1003 | } 1004 | ], 1005 | "timeFrom": null, 1006 | "timeShift": null, 1007 | "title": "TOP $TopResources VM Maximum IOPS", 1008 | "tooltip": { 1009 | "msResolution": false, 1010 | "shared": true, 1011 | "value_type": "cumulative" 1012 | }, 1013 | "type": "graph", 1014 | "xaxis": { 1015 | "show": true 1016 | }, 1017 | "yaxes": [ 1018 | { 1019 | "format": "short", 1020 | "logBase": 1, 1021 | "max": null, 1022 | "min": null, 1023 | "show": true 1024 | }, 1025 | { 1026 | "format": "short", 1027 | "logBase": 1, 1028 | "max": null, 1029 | "min": null, 1030 | "show": true 1031 | } 1032 | ] 1033 | }, 1034 | { 1035 | "aliasColors": {}, 1036 | "bars": false, 1037 | "datasource": null, 1038 | "decimals": 0, 1039 | "editable": true, 1040 | "error": false, 1041 | "fill": 1, 1042 | "grid": { 1043 | "threshold1": null, 1044 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1045 | "threshold2": null, 1046 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 1047 | }, 1048 | "height": "", 1049 | "id": 25, 1050 | "legend": { 1051 | "alignAsTable": true, 1052 | "avg": true, 1053 | "current": true, 1054 | "max": true, 1055 | "min": false, 1056 | "rightSide": false, 1057 | "show": true, 1058 | "sort": "max", 1059 | "sortDesc": true, 1060 | "total": false, 1061 | "values": true 1062 | }, 1063 | "lines": true, 1064 | "linewidth": 2, 1065 | "links": [], 1066 | "nullPointMode": "connected", 1067 | "percentage": false, 1068 | "pointradius": 5, 1069 | "points": false, 1070 | "renderer": "flot", 1071 | "seriesOverrides": [], 1072 | "span": 4, 1073 | "stack": false, 1074 | "steppedLine": false, 1075 | "targets": [ 1076 | { 1077 | "refId": "A", 1078 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.TotalKBps, $TopResources), 2)" 1079 | } 1080 | ], 1081 | "timeFrom": null, 1082 | "timeShift": null, 1083 | "title": "TOP $TopResources VM Maximum Throughput", 1084 | "tooltip": { 1085 | "msResolution": false, 1086 | "shared": true, 1087 | "value_type": "cumulative" 1088 | }, 1089 | "type": "graph", 1090 | "xaxis": { 1091 | "show": true 1092 | }, 1093 | "yaxes": [ 1094 | { 1095 | "format": "kbytes", 1096 | "logBase": 1, 1097 | "max": null, 1098 | "min": null, 1099 | "show": true 1100 | }, 1101 | { 1102 | "format": "short", 1103 | "logBase": 1, 1104 | "max": null, 1105 | "min": null, 1106 | "show": true 1107 | } 1108 | ] 1109 | }, 1110 | { 1111 | "aliasColors": {}, 1112 | "bars": false, 1113 | "datasource": null, 1114 | "editable": true, 1115 | "error": false, 1116 | "fill": 1, 1117 | "grid": { 1118 | "threshold1": null, 1119 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1120 | "threshold2": null, 1121 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 1122 | }, 1123 | "height": "", 1124 | "id": 26, 1125 | "legend": { 1126 | "alignAsTable": true, 1127 | "avg": true, 1128 | "current": true, 1129 | "max": true, 1130 | "min": false, 1131 | "rightSide": false, 1132 | "show": true, 1133 | "sort": "max", 1134 | "sortDesc": true, 1135 | "total": false, 1136 | "values": true 1137 | }, 1138 | "lines": true, 1139 | "linewidth": 2, 1140 | "links": [], 1141 | "nullPointMode": "connected", 1142 | "percentage": false, 1143 | "pointradius": 5, 1144 | "points": false, 1145 | "renderer": "flot", 1146 | "seriesOverrides": [], 1147 | "span": 4, 1148 | "stack": false, 1149 | "steppedLine": false, 1150 | "targets": [ 1151 | { 1152 | "refId": "A", 1153 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.CPU, $TopResources), 2)" 1154 | } 1155 | ], 1156 | "timeFrom": null, 1157 | "timeShift": null, 1158 | "title": "TOP $TopResources VM Maximum CPU", 1159 | "tooltip": { 1160 | "msResolution": false, 1161 | "shared": true, 1162 | "value_type": "cumulative" 1163 | }, 1164 | "type": "graph", 1165 | "xaxis": { 1166 | "show": true 1167 | }, 1168 | "yaxes": [ 1169 | { 1170 | "format": "percent", 1171 | "logBase": 1, 1172 | "max": 100, 1173 | "min": null, 1174 | "show": true 1175 | }, 1176 | { 1177 | "format": "short", 1178 | "logBase": 1, 1179 | "max": null, 1180 | "min": null, 1181 | "show": true 1182 | } 1183 | ] 1184 | }, 1185 | { 1186 | "aliasColors": {}, 1187 | "bars": false, 1188 | "datasource": null, 1189 | "decimals": 1, 1190 | "editable": true, 1191 | "error": false, 1192 | "fill": 1, 1193 | "grid": { 1194 | "threshold1": 20, 1195 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1196 | "threshold2": 50, 1197 | "threshold2Color": "rgba(234, 112, 112, 0.22)", 1198 | "thresholdLine": false 1199 | }, 1200 | "height": "", 1201 | "id": 27, 1202 | "legend": { 1203 | "alignAsTable": true, 1204 | "avg": true, 1205 | "current": true, 1206 | "max": true, 1207 | "min": false, 1208 | "rightSide": false, 1209 | "show": true, 1210 | "sort": "max", 1211 | "sortDesc": true, 1212 | "total": false, 1213 | "values": true 1214 | }, 1215 | "lines": true, 1216 | "linewidth": 1, 1217 | "links": [], 1218 | "nullPointMode": "connected", 1219 | "percentage": false, 1220 | "pointradius": 5, 1221 | "points": false, 1222 | "renderer": "flot", 1223 | "seriesOverrides": [], 1224 | "span": 6, 1225 | "stack": false, 1226 | "steppedLine": false, 1227 | "targets": [ 1228 | { 1229 | "refId": "A", 1230 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.ReadLatency, $TopResources), 2)" 1231 | } 1232 | ], 1233 | "timeFrom": null, 1234 | "timeShift": null, 1235 | "title": "TOP $TopResources VM Maximum Read Latencies", 1236 | "tooltip": { 1237 | "msResolution": false, 1238 | "shared": true, 1239 | "value_type": "cumulative" 1240 | }, 1241 | "type": "graph", 1242 | "xaxis": { 1243 | "show": true 1244 | }, 1245 | "yaxes": [ 1246 | { 1247 | "format": "ms", 1248 | "logBase": 1, 1249 | "max": null, 1250 | "min": null, 1251 | "show": true 1252 | }, 1253 | { 1254 | "format": "short", 1255 | "logBase": 1, 1256 | "max": null, 1257 | "min": null, 1258 | "show": true 1259 | } 1260 | ] 1261 | }, 1262 | { 1263 | "aliasColors": {}, 1264 | "bars": false, 1265 | "datasource": null, 1266 | "decimals": null, 1267 | "editable": true, 1268 | "error": false, 1269 | "fill": 1, 1270 | "grid": { 1271 | "threshold1": 20, 1272 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1273 | "threshold2": 50, 1274 | "threshold2Color": "rgba(234, 112, 112, 0.22)", 1275 | "thresholdLine": false 1276 | }, 1277 | "height": "", 1278 | "id": 28, 1279 | "legend": { 1280 | "alignAsTable": true, 1281 | "avg": true, 1282 | "current": true, 1283 | "max": true, 1284 | "min": false, 1285 | "rightSide": false, 1286 | "show": true, 1287 | "sort": "max", 1288 | "sortDesc": true, 1289 | "total": false, 1290 | "values": true 1291 | }, 1292 | "lines": true, 1293 | "linewidth": 1, 1294 | "links": [], 1295 | "nullPointMode": "connected", 1296 | "percentage": false, 1297 | "pointradius": 5, 1298 | "points": false, 1299 | "renderer": "flot", 1300 | "seriesOverrides": [], 1301 | "span": 6, 1302 | "stack": false, 1303 | "steppedLine": false, 1304 | "targets": [ 1305 | { 1306 | "refId": "A", 1307 | "target": "aliasByNode(highestMax(vmperf.$Group.$VM.WriteLatency, $TopResources), 2)" 1308 | } 1309 | ], 1310 | "timeFrom": null, 1311 | "timeShift": null, 1312 | "title": "TOP $TopResources VM Maximum Write Latencies", 1313 | "tooltip": { 1314 | "msResolution": false, 1315 | "shared": true, 1316 | "value_type": "cumulative" 1317 | }, 1318 | "transparent": false, 1319 | "type": "graph", 1320 | "xaxis": { 1321 | "show": true 1322 | }, 1323 | "yaxes": [ 1324 | { 1325 | "format": "ms", 1326 | "logBase": 1, 1327 | "max": null, 1328 | "min": null, 1329 | "show": true 1330 | }, 1331 | { 1332 | "format": "short", 1333 | "logBase": 1, 1334 | "max": null, 1335 | "min": null, 1336 | "show": true 1337 | } 1338 | ] 1339 | } 1340 | ], 1341 | "showTitle": true, 1342 | "title": "Virtual Machines by Maximum Values" 1343 | }, 1344 | { 1345 | "collapse": true, 1346 | "editable": true, 1347 | "height": "350px", 1348 | "panels": [ 1349 | { 1350 | "columns": [ 1351 | { 1352 | "text": "Average", 1353 | "value": "avg" 1354 | } 1355 | ], 1356 | "editable": true, 1357 | "error": false, 1358 | "fontSize": "90%", 1359 | "id": 29, 1360 | "isNew": true, 1361 | "links": [], 1362 | "pageSize": null, 1363 | "scroll": false, 1364 | "showHeader": true, 1365 | "sort": { 1366 | "col": 1, 1367 | "desc": true 1368 | }, 1369 | "span": 2, 1370 | "styles": [ 1371 | { 1372 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1373 | "pattern": "Time", 1374 | "type": "date" 1375 | }, 1376 | { 1377 | "colorMode": "row", 1378 | "colors": [ 1379 | "rgba(50, 172, 45, 0.78)", 1380 | "rgba(237, 129, 40, 0.89)", 1381 | "rgba(245, 54, 54, 0.49)" 1382 | ], 1383 | "decimals": 0, 1384 | "pattern": "/.*/", 1385 | "thresholds": [ 1386 | "1000", 1387 | "2000" 1388 | ], 1389 | "type": "number", 1390 | "unit": "short" 1391 | } 1392 | ], 1393 | "targets": [ 1394 | { 1395 | "refId": "A", 1396 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.TotalIOPS, $TopResources), 2)" 1397 | } 1398 | ], 1399 | "title": "Average IOPS", 1400 | "transform": "timeseries_aggregations", 1401 | "type": "table", 1402 | "height": "200" 1403 | }, 1404 | { 1405 | "columns": [ 1406 | { 1407 | "text": "Average", 1408 | "value": "avg" 1409 | } 1410 | ], 1411 | "editable": true, 1412 | "error": false, 1413 | "fontSize": "90%", 1414 | "id": 30, 1415 | "isNew": true, 1416 | "links": [], 1417 | "pageSize": null, 1418 | "scroll": false, 1419 | "showHeader": true, 1420 | "sort": { 1421 | "col": 1, 1422 | "desc": true 1423 | }, 1424 | "span": 2, 1425 | "styles": [ 1426 | { 1427 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1428 | "pattern": "Time", 1429 | "type": "date" 1430 | }, 1431 | { 1432 | "colorMode": "row", 1433 | "colors": [ 1434 | "rgba(50, 172, 45, 0.78)", 1435 | "rgba(237, 129, 40, 0.89)", 1436 | "rgba(245, 54, 54, 0.49)" 1437 | ], 1438 | "decimals": 0, 1439 | "pattern": "/.*/", 1440 | "thresholds": [ 1441 | "10000", 1442 | "20000" 1443 | ], 1444 | "type": "number", 1445 | "unit": "KBs" 1446 | } 1447 | ], 1448 | "targets": [ 1449 | { 1450 | "refId": "A", 1451 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.TotalKBps, $TopResources), 2)" 1452 | } 1453 | ], 1454 | "title": "Average Throughput", 1455 | "transform": "timeseries_aggregations", 1456 | "type": "table", 1457 | "height": "200" 1458 | }, 1459 | { 1460 | "columns": [ 1461 | { 1462 | "text": "Average", 1463 | "value": "avg" 1464 | } 1465 | ], 1466 | "editable": true, 1467 | "error": false, 1468 | "fontSize": "90%", 1469 | "id": 31, 1470 | "isNew": true, 1471 | "links": [], 1472 | "pageSize": null, 1473 | "scroll": false, 1474 | "showHeader": true, 1475 | "sort": { 1476 | "col": 1, 1477 | "desc": true 1478 | }, 1479 | "span": 2, 1480 | "styles": [ 1481 | { 1482 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1483 | "pattern": "Time", 1484 | "type": "date" 1485 | }, 1486 | { 1487 | "colorMode": "row", 1488 | "colors": [ 1489 | "rgba(50, 172, 45, 0.78)", 1490 | "rgba(237, 129, 40, 0.89)", 1491 | "rgba(245, 54, 54, 0.49)" 1492 | ], 1493 | "decimals": 0, 1494 | "pattern": "/.*/", 1495 | "thresholds": [ 1496 | "60", 1497 | "80" 1498 | ], 1499 | "type": "number", 1500 | "unit": "percent" 1501 | } 1502 | ], 1503 | "targets": [ 1504 | { 1505 | "refId": "A", 1506 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.CPU, $TopResources), 2)" 1507 | } 1508 | ], 1509 | "title": "Average CPU", 1510 | "transform": "timeseries_aggregations", 1511 | "type": "table", 1512 | "height": "200" 1513 | }, 1514 | { 1515 | "columns": [ 1516 | { 1517 | "text": "Average", 1518 | "value": "avg" 1519 | } 1520 | ], 1521 | "editable": true, 1522 | "error": false, 1523 | "fontSize": "90%", 1524 | "id": 32, 1525 | "isNew": true, 1526 | "links": [], 1527 | "pageSize": null, 1528 | "scroll": false, 1529 | "showHeader": true, 1530 | "sort": { 1531 | "col": 1, 1532 | "desc": true 1533 | }, 1534 | "span": 3, 1535 | "styles": [ 1536 | { 1537 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1538 | "pattern": "Time", 1539 | "type": "date" 1540 | }, 1541 | { 1542 | "colorMode": "row", 1543 | "colors": [ 1544 | "rgba(50, 172, 45, 0.78)", 1545 | "rgba(237, 129, 40, 0.89)", 1546 | "rgba(245, 54, 54, 0.49)" 1547 | ], 1548 | "decimals": 1, 1549 | "pattern": "/.*/", 1550 | "thresholds": [ 1551 | "15", 1552 | "30" 1553 | ], 1554 | "type": "number", 1555 | "unit": "ms" 1556 | } 1557 | ], 1558 | "targets": [ 1559 | { 1560 | "refId": "A", 1561 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.ReadLatency, $TopResources), 2)" 1562 | } 1563 | ], 1564 | "title": "Average Read Latency", 1565 | "transform": "timeseries_aggregations", 1566 | "type": "table", 1567 | "height": "200" 1568 | }, 1569 | { 1570 | "columns": [ 1571 | { 1572 | "text": "Average", 1573 | "value": "avg" 1574 | } 1575 | ], 1576 | "editable": true, 1577 | "error": false, 1578 | "fontSize": "90%", 1579 | "id": 33, 1580 | "isNew": true, 1581 | "links": [], 1582 | "pageSize": null, 1583 | "scroll": false, 1584 | "showHeader": true, 1585 | "sort": { 1586 | "col": 1, 1587 | "desc": true 1588 | }, 1589 | "span": 3, 1590 | "styles": [ 1591 | { 1592 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1593 | "pattern": "VM", 1594 | "type": "string" 1595 | }, 1596 | { 1597 | "colorMode": "row", 1598 | "colors": [ 1599 | "rgba(50, 172, 45, 0.78)", 1600 | "rgba(237, 129, 40, 0.89)", 1601 | "rgba(245, 54, 54, 0.49)" 1602 | ], 1603 | "decimals": 1, 1604 | "pattern": "/.*/", 1605 | "thresholds": [ 1606 | "15", 1607 | "30" 1608 | ], 1609 | "type": "number", 1610 | "unit": "ms" 1611 | } 1612 | ], 1613 | "targets": [ 1614 | { 1615 | "refId": "A", 1616 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.WriteLatency, $TopResources), 2)" 1617 | } 1618 | ], 1619 | "title": "Average Write Latency", 1620 | "transform": "timeseries_aggregations", 1621 | "type": "table", 1622 | "height": "200" 1623 | }, 1624 | { 1625 | "aliasColors": {}, 1626 | "bars": false, 1627 | "datasource": null, 1628 | "editable": true, 1629 | "error": false, 1630 | "fill": 1, 1631 | "grid": { 1632 | "threshold1": null, 1633 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1634 | "threshold2": null, 1635 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 1636 | }, 1637 | "height": "", 1638 | "id": 24, 1639 | "legend": { 1640 | "alignAsTable": true, 1641 | "avg": true, 1642 | "current": true, 1643 | "max": true, 1644 | "min": false, 1645 | "rightSide": false, 1646 | "show": true, 1647 | "sort": "avg", 1648 | "sortDesc": true, 1649 | "total": false, 1650 | "values": true 1651 | }, 1652 | "lines": true, 1653 | "linewidth": 2, 1654 | "links": [], 1655 | "nullPointMode": "connected", 1656 | "percentage": false, 1657 | "pointradius": 5, 1658 | "points": false, 1659 | "renderer": "flot", 1660 | "seriesOverrides": [], 1661 | "span": 4, 1662 | "stack": false, 1663 | "steppedLine": false, 1664 | "targets": [ 1665 | { 1666 | "refId": "A", 1667 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.TotalIOPS, $TopResources), 2)" 1668 | } 1669 | ], 1670 | "timeFrom": null, 1671 | "timeShift": null, 1672 | "title": "TOP $TopResources VM Average IOPS", 1673 | "tooltip": { 1674 | "msResolution": false, 1675 | "shared": true, 1676 | "value_type": "cumulative" 1677 | }, 1678 | "type": "graph", 1679 | "xaxis": { 1680 | "show": true 1681 | }, 1682 | "yaxes": [ 1683 | { 1684 | "format": "short", 1685 | "logBase": 1, 1686 | "max": null, 1687 | "min": null, 1688 | "show": true 1689 | }, 1690 | { 1691 | "format": "short", 1692 | "logBase": 1, 1693 | "max": null, 1694 | "min": null, 1695 | "show": true 1696 | } 1697 | ] 1698 | }, 1699 | { 1700 | "aliasColors": {}, 1701 | "bars": false, 1702 | "datasource": null, 1703 | "decimals": 0, 1704 | "editable": true, 1705 | "error": false, 1706 | "fill": 1, 1707 | "grid": { 1708 | "threshold1": null, 1709 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1710 | "threshold2": null, 1711 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 1712 | }, 1713 | "height": "", 1714 | "id": 25, 1715 | "legend": { 1716 | "alignAsTable": true, 1717 | "avg": true, 1718 | "current": true, 1719 | "max": true, 1720 | "min": false, 1721 | "rightSide": false, 1722 | "show": true, 1723 | "sort": "avg", 1724 | "sortDesc": true, 1725 | "total": false, 1726 | "values": true 1727 | }, 1728 | "lines": true, 1729 | "linewidth": 2, 1730 | "links": [], 1731 | "nullPointMode": "connected", 1732 | "percentage": false, 1733 | "pointradius": 5, 1734 | "points": false, 1735 | "renderer": "flot", 1736 | "seriesOverrides": [], 1737 | "span": 4, 1738 | "stack": false, 1739 | "steppedLine": false, 1740 | "targets": [ 1741 | { 1742 | "refId": "A", 1743 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.TotalKBps, $TopResources), 2)" 1744 | } 1745 | ], 1746 | "timeFrom": null, 1747 | "timeShift": null, 1748 | "title": "TOP $TopResources VM Average Throughput", 1749 | "tooltip": { 1750 | "msResolution": false, 1751 | "shared": true, 1752 | "value_type": "cumulative" 1753 | }, 1754 | "type": "graph", 1755 | "xaxis": { 1756 | "show": true 1757 | }, 1758 | "yaxes": [ 1759 | { 1760 | "format": "kbytes", 1761 | "logBase": 1, 1762 | "max": null, 1763 | "min": null, 1764 | "show": true 1765 | }, 1766 | { 1767 | "format": "short", 1768 | "logBase": 1, 1769 | "max": null, 1770 | "min": null, 1771 | "show": true 1772 | } 1773 | ] 1774 | }, 1775 | { 1776 | "aliasColors": {}, 1777 | "bars": false, 1778 | "datasource": null, 1779 | "editable": true, 1780 | "error": false, 1781 | "fill": 1, 1782 | "grid": { 1783 | "threshold1": null, 1784 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1785 | "threshold2": null, 1786 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 1787 | }, 1788 | "height": "", 1789 | "id": 26, 1790 | "legend": { 1791 | "alignAsTable": true, 1792 | "avg": true, 1793 | "current": true, 1794 | "max": true, 1795 | "min": false, 1796 | "rightSide": false, 1797 | "show": true, 1798 | "sort": "avg", 1799 | "sortDesc": true, 1800 | "total": false, 1801 | "values": true 1802 | }, 1803 | "lines": true, 1804 | "linewidth": 2, 1805 | "links": [], 1806 | "nullPointMode": "connected", 1807 | "percentage": false, 1808 | "pointradius": 5, 1809 | "points": false, 1810 | "renderer": "flot", 1811 | "seriesOverrides": [], 1812 | "span": 4, 1813 | "stack": false, 1814 | "steppedLine": false, 1815 | "targets": [ 1816 | { 1817 | "refId": "A", 1818 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.CPU, $TopResources), 2)" 1819 | } 1820 | ], 1821 | "timeFrom": null, 1822 | "timeShift": null, 1823 | "title": "TOP $TopResources VM Average CPU", 1824 | "tooltip": { 1825 | "msResolution": false, 1826 | "shared": true, 1827 | "value_type": "cumulative" 1828 | }, 1829 | "type": "graph", 1830 | "xaxis": { 1831 | "show": true 1832 | }, 1833 | "yaxes": [ 1834 | { 1835 | "format": "percent", 1836 | "logBase": 1, 1837 | "max": 100, 1838 | "min": null, 1839 | "show": true 1840 | }, 1841 | { 1842 | "format": "short", 1843 | "logBase": 1, 1844 | "max": null, 1845 | "min": null, 1846 | "show": true 1847 | } 1848 | ] 1849 | }, 1850 | { 1851 | "aliasColors": {}, 1852 | "bars": false, 1853 | "datasource": null, 1854 | "decimals": 1, 1855 | "editable": true, 1856 | "error": false, 1857 | "fill": 1, 1858 | "grid": { 1859 | "threshold1": 20, 1860 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1861 | "threshold2": 50, 1862 | "threshold2Color": "rgba(234, 112, 112, 0.22)", 1863 | "thresholdLine": false 1864 | }, 1865 | "height": "", 1866 | "id": 27, 1867 | "legend": { 1868 | "alignAsTable": true, 1869 | "avg": true, 1870 | "current": true, 1871 | "max": true, 1872 | "min": false, 1873 | "rightSide": false, 1874 | "show": true, 1875 | "sort": "avg", 1876 | "sortDesc": true, 1877 | "total": false, 1878 | "values": true 1879 | }, 1880 | "lines": true, 1881 | "linewidth": 1, 1882 | "links": [], 1883 | "nullPointMode": "connected", 1884 | "percentage": false, 1885 | "pointradius": 5, 1886 | "points": false, 1887 | "renderer": "flot", 1888 | "seriesOverrides": [], 1889 | "span": 6, 1890 | "stack": false, 1891 | "steppedLine": false, 1892 | "targets": [ 1893 | { 1894 | "refId": "A", 1895 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.ReadLatency, $TopResources), 2)" 1896 | } 1897 | ], 1898 | "timeFrom": null, 1899 | "timeShift": null, 1900 | "title": "TOP $TopResources VM Average Read Latencies", 1901 | "tooltip": { 1902 | "msResolution": false, 1903 | "shared": true, 1904 | "value_type": "cumulative" 1905 | }, 1906 | "type": "graph", 1907 | "xaxis": { 1908 | "show": true 1909 | }, 1910 | "yaxes": [ 1911 | { 1912 | "format": "ms", 1913 | "logBase": 1, 1914 | "max": null, 1915 | "min": null, 1916 | "show": true 1917 | }, 1918 | { 1919 | "format": "short", 1920 | "logBase": 1, 1921 | "max": null, 1922 | "min": null, 1923 | "show": true 1924 | } 1925 | ] 1926 | }, 1927 | { 1928 | "aliasColors": {}, 1929 | "bars": false, 1930 | "datasource": null, 1931 | "decimals": null, 1932 | "editable": true, 1933 | "error": false, 1934 | "fill": 1, 1935 | "grid": { 1936 | "threshold1": 20, 1937 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 1938 | "threshold2": 50, 1939 | "threshold2Color": "rgba(234, 112, 112, 0.22)", 1940 | "thresholdLine": false 1941 | }, 1942 | "height": "", 1943 | "id": 28, 1944 | "legend": { 1945 | "alignAsTable": true, 1946 | "avg": true, 1947 | "current": true, 1948 | "max": true, 1949 | "min": false, 1950 | "rightSide": false, 1951 | "show": true, 1952 | "sort": "avg", 1953 | "sortDesc": true, 1954 | "total": false, 1955 | "values": true 1956 | }, 1957 | "lines": true, 1958 | "linewidth": 1, 1959 | "links": [], 1960 | "nullPointMode": "connected", 1961 | "percentage": false, 1962 | "pointradius": 5, 1963 | "points": false, 1964 | "renderer": "flot", 1965 | "seriesOverrides": [], 1966 | "span": 6, 1967 | "stack": false, 1968 | "steppedLine": false, 1969 | "targets": [ 1970 | { 1971 | "refId": "A", 1972 | "target": "aliasByNode(highestAverage(vmperf.$Group.$VM.WriteLatency, $TopResources), 2)" 1973 | } 1974 | ], 1975 | "timeFrom": null, 1976 | "timeShift": null, 1977 | "title": "TOP $TopResources VM Average Write Latencies", 1978 | "tooltip": { 1979 | "msResolution": false, 1980 | "shared": true, 1981 | "value_type": "cumulative" 1982 | }, 1983 | "transparent": false, 1984 | "type": "graph", 1985 | "xaxis": { 1986 | "show": true 1987 | }, 1988 | "yaxes": [ 1989 | { 1990 | "format": "ms", 1991 | "logBase": 1, 1992 | "max": null, 1993 | "min": null, 1994 | "show": true 1995 | }, 1996 | { 1997 | "format": "short", 1998 | "logBase": 1, 1999 | "max": null, 2000 | "min": null, 2001 | "show": true 2002 | } 2003 | ] 2004 | } 2005 | ], 2006 | "showTitle": true, 2007 | "title": "Virtual Machines by Average Values" 2008 | } 2009 | ], 2010 | "time": { 2011 | "from": "now-1h", 2012 | "now": true, 2013 | "to": "now" 2014 | }, 2015 | "timepicker": { 2016 | "collapse": false, 2017 | "enable": true, 2018 | "notice": false, 2019 | "now": true, 2020 | "refresh_intervals": [ 2021 | "5s", 2022 | "10s", 2023 | "30s", 2024 | "1m", 2025 | "5m", 2026 | "15m", 2027 | "30m", 2028 | "1h", 2029 | "2h", 2030 | "1d" 2031 | ], 2032 | "status": "Stable", 2033 | "time_options": [ 2034 | "5m", 2035 | "15m", 2036 | "1h", 2037 | "6h", 2038 | "12h", 2039 | "24h", 2040 | "2d", 2041 | "7d", 2042 | "30d" 2043 | ], 2044 | "type": "timepicker" 2045 | }, 2046 | "templating": { 2047 | "enable": true, 2048 | "list": [ 2049 | { 2050 | "allFormat": "wildcard", 2051 | "current": { 2052 | "text": "All", 2053 | "value": "$__all" 2054 | }, 2055 | "datasource": null, 2056 | "hide": 0, 2057 | "includeAll": true, 2058 | "name": "Group", 2059 | "query": "vmperf.*", 2060 | "refresh": 1, 2061 | "refresh_on_load": false, 2062 | "regex": "", 2063 | "type": "query" 2064 | }, 2065 | { 2066 | "allFormat": "wildcard", 2067 | "current": { 2068 | "text": "All", 2069 | "value": "$__all" 2070 | }, 2071 | "datasource": null, 2072 | "hide": 0, 2073 | "includeAll": true, 2074 | "multi": true, 2075 | "multiFormat": "glob", 2076 | "name": "VM", 2077 | "query": "vmperf.$Group.*", 2078 | "refresh": 0, 2079 | "refresh_on_load": false, 2080 | "regex": "", 2081 | "type": "query" 2082 | }, 2083 | { 2084 | "allFormat": "glob", 2085 | "current": { 2086 | "tags": [], 2087 | "text": "5", 2088 | "value": "5" 2089 | }, 2090 | "datasource": null, 2091 | "hide": 0, 2092 | "includeAll": false, 2093 | "name": "TopResources", 2094 | "options": [ 2095 | { 2096 | "selected": false, 2097 | "text": "1", 2098 | "value": "1" 2099 | }, 2100 | { 2101 | "selected": false, 2102 | "text": "2", 2103 | "value": "2" 2104 | }, 2105 | { 2106 | "selected": false, 2107 | "text": "3", 2108 | "value": "3" 2109 | }, 2110 | { 2111 | "selected": false, 2112 | "text": "4", 2113 | "value": "4" 2114 | }, 2115 | { 2116 | "selected": true, 2117 | "text": "5", 2118 | "value": "5" 2119 | }, 2120 | { 2121 | "selected": false, 2122 | "text": "6", 2123 | "value": "6" 2124 | }, 2125 | { 2126 | "selected": false, 2127 | "text": "8", 2128 | "value": "8" 2129 | }, 2130 | { 2131 | "selected": false, 2132 | "text": "10", 2133 | "value": "10" 2134 | }, 2135 | { 2136 | "selected": false, 2137 | "text": "15", 2138 | "value": "15" 2139 | }, 2140 | { 2141 | "selected": false, 2142 | "text": "20", 2143 | "value": "20" 2144 | }, 2145 | { 2146 | "selected": false, 2147 | "text": "40", 2148 | "value": "40" 2149 | }, 2150 | { 2151 | "selected": false, 2152 | "text": "*", 2153 | "value": "*" 2154 | } 2155 | ], 2156 | "query": "1,2,3,4,5,6,8,10,15,20,40,*", 2157 | "refresh": 0, 2158 | "refresh_on_load": false, 2159 | "type": "custom" 2160 | } 2161 | ] 2162 | }, 2163 | "annotations": { 2164 | "list": [] 2165 | }, 2166 | "refresh": "5m", 2167 | "schemaVersion": 12, 2168 | "version": 4, 2169 | "links": [ 2170 | { 2171 | "asDropdown": true, 2172 | "icon": "external link", 2173 | "includeVars": true, 2174 | "keepTime": true, 2175 | "tags": [ 2176 | "VMPerf" 2177 | ], 2178 | "title": "VMPerf Dashboards", 2179 | "type": "dashboards" 2180 | } 2181 | ] 2182 | } 2183 | -------------------------------------------------------------------------------- /VMPerf-To-Graphite.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Read Virtual Machine statistics from vCenter and send the results to Graphite. 4 | .DESCRIPTION 5 | The script uses VMWare PowerCLI to connect to a vCenter Server, read certain performance metrics from all running virtual machines and sends the results to Graphite. 6 | Note that only IOs are measured which are performed on a Datastore. Neither RAW Disks nor iSCSI or NFS monuted devices from INSIDE a VM are counted. 7 | Without the "-Verbose" switch, no output is generated, except errors. 8 | Note that VMWare PowerCLI has to be installed properly on the system where the script runs. 9 | .EXAMPLE 10 | VMPerf-To-Graphite.ps1 -Verbose 11 | Use default values from within this script and display the status output on the screen. 12 | .EXAMPLE 13 | VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Graphiteserver graphite1.it.acme.com -Iterations 1 -FromLastPoll Vienna_Poll.xml 14 | Run the cmdlet just once. Write the date and time of the Poll to Vienna_Poll.xml. The next time the script runs, it will read the file and gather the metrics from VCenter starting at the last poll. 15 | .EXAMPLE 16 | VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Graphiteserver graphite1.it.acme.com,graphdev.it.acme.com:62033 -Iterations 1 -FromLastPoll Vienna_Poll.xml 17 | Same as above but send the metrics to two servers, graphite1.it.acme.com at (default) port 2003 and graphdev.it.acme.com on port 62033. 18 | .EXAMPLE 19 | VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Sleepseconds 300 -Graphiteserver graphite1.it.acme.com -Group Vienna 20 | Read the counters from the VCenter server myvcenter.vienna.acme.com, send the metrics to graphite1.it.acme.com with a metrics path of "vmperf.Vienna." and then wait 5 minutes before the next iteration. 21 | .EXAMPLE 22 | VMPerf-To-Graphite.ps1 -Verbose -Server myvcenter.vienna.acme.com -User ACME\StatsReader -Password mypass -Sleepseconds 300 -Graphiteserver graphite1.it.acme.com -Group Vienna -Cluster TESTDEV 23 | Read the counters from Cluster TESTDEV in the VCenter server myvcenter.vienna.acme.com, send the metrics to graphite1.it.acme.com with a metrics path of "vmperf.Vienna." and then wait 5 minutes before the next iteration. 24 | .EXAMPLE 25 | VMPerf-To-Graphite.ps1 -Verbose -Iterations 1 -WhatIf | Out-GridView 26 | Run the cmdlet just once, but do not send the metrics to Graphite, instead open a window and display the results. 27 | .NOTES 28 | This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. 29 | It is free-of-charge and it comes without any warranty, to the extent permitted by applicable law. 30 | Matthias Rettl, 2016 31 | Script Version 1.5.2 (2016-11-30) 32 | .LINK 33 | https://github.com/mothe-at/VMPerf-To-Graphite-PowerShell-Script 34 | http://rettl.org/scripts/ 35 | http://creativecommons.org/licenses/by-nc-sa/4.0/ 36 | #> 37 | [CmdletBinding()] 38 | param( 39 | # Specifies the IP address or the DNS name of the vCenter server to which you want to connect. 40 | [string]$Server = "your_default_vcenter_server", 41 | # Specifies the user name you want to use for authenticating with the vCenter server. 42 | # If this parameter is omitted, the currently logged on user will try to authenticate with the vCenter server. 43 | [string]$User = "", 44 | # Specifies the password you want to use for authenticating with the vCenter server. 45 | [string]$Password = "", 46 | # Specifies the Internet protocol you want to use for the connection. It can be either http or https. 47 | [ValidateSet("http","https")][string]$Protocol = "https", 48 | # Specifies the VMWare Datacenters you want to receive data from. Default is to read all Clusters managed by VCenter server. 49 | [string[]]$Datacenter = "*", 50 | # Specifies the VMWare Clusters you want to receive data from. Default is to read all Clusters managed by VCenter server or, if -Datacenter is specified, all Clusters in this Datacenter. 51 | [string[]]$Cluster = "*", 52 | # Specifies one or more (separated by comma) IP addresses or the DNS names of the Graphite servers to which you want to connect. 53 | # You can also add the Portnumber to each Server like "grafana.acme.com:2003" 54 | [string[]]$Graphiteserver = "your_default_grafana_server", 55 | # Specifies the port on the Graphite server you want to use for the connection. Defaults to 2003. 56 | # You can also add the portnumber to the servers hostname or IP address in the -Graphiteserver parameter. 57 | [ValidateRange(1024,65536)][int]$Graphiteserverport = 2003, 58 | # Specifies the Group, an additional prefix for the metrics path in Graphite. The metrics path will be "vmperf.." 59 | [string]$Group = "Default", 60 | # Specifies the number of iterations. 0 = indefinitely. 61 | [ValidateRange(0,65536)][int]$Iterations = 0, 62 | # Optional path and name of an .xml file where the date and time of the last poll will be saved. 63 | # If the file does not exist, it will be created and overwritten after each poll. 64 | # If this parameter is set, the script will try to receive all metrics from the VCenter Server starting at the date and time of the last poll up to the most recent data (Real-Time). 65 | # This is useful if you want to schedule the script externally (with Task Scheduler, for instance) and you want to use the "-Iterations 1" parameter. 66 | # But be careful, VCenter stores the Real-Time statistics just for a limited number of time (1 day per default). 67 | [string]$FromLastPoll = "", 68 | # Specifies the number of seconds to wait between iterations. The counter starts after the last statistics have been sent to Graphite. 69 | # Note that VCenter is collecting its performance statistics every 20 seconds and saves an average of the collected counters. It makes no sense to specify a value below 20 seconds here. The script reads the so called "Realtime" counters from VCenter which will be kept there for one hour. So do not use anything above 3600 seconds. 70 | # The script requests all statistics data from VCenter server since the last time they were requested, regardless of how long the Sleepseconds parameter was set. You wont miss any data. 71 | [ValidateRange(0,3600)][int]$Sleepseconds = 60, 72 | # Indicate that the cmdlet will process but will NOT send any metrics to Graphite, instead display a list of metrics that would be sent to Graphite. 73 | [Switch]$Whatif, 74 | # Set the Log-Level for writing events to the Windows Aplication log. Valid values are Error, Warning, Information, and None. The default value is Warning. 75 | # Note that if you like to use logging to the Windows Event Log, you have to run this script at least once with administrative privileges on this computer! 76 | [ValidateSet("None","Information","Warning","Error")][String]$EventLogLevel = "Warning" 77 | ) 78 | 79 | 80 | 81 | # --------------------------------------- 82 | # Write Events to the Windows Event Log 83 | # --------------------------------------- 84 | function Write-To-Windows-EventLog ($severity, $id, $message) { 85 | $levels="None","Information","Warning","Error" 86 | $ell=[array]::IndexOf($levels,$EventLogLevel) 87 | $sev=[array]::IndexOf($levels,$severity) 88 | $logsouce="" 89 | 90 | if (($ell -ne 0) -AND ($sev -ge $ell)) { 91 | $myscriptname = split-path $MyInvocation.PSCommandPath -Leaf 92 | $myscriptfull = $MyInvocation.ScriptName 93 | $l = [Environment]::NewLine 94 | 95 | New-EventLog –LogName Application –Source $myscriptname -ErrorAction SilentlyContinue 96 | 97 | $msg = $message + $l+$l + "Called by:" + $l + "$myscriptfull -Server $server -User $user -Password [**HIDDEN**] -Protocol $protocol -Datacenter $datacenter -Cluster $cluster -Group $Group -Graphiteserver $Graphiteserver -Graphiteserverport $Graphiteserverport -Sleepseconds $Sleepseconds -Iterations $Iterations -FromLastPoll $FromLastPoll -WhatIf:`$$Whatif -EventLogLevel $EventLogLevel" 98 | Write-EventLog –LogName Application –Source $myscriptname –EntryType $severity –EventID $id –Message $msg -Category 0 99 | 100 | } 101 | 102 | 103 | } 104 | 105 | function checkiporhostname($Name,$ipho,$stoponerror) { 106 | 107 | try { 108 | $ip = [System.Net.Dns]::GetHostAddresses($ipho) | select-object IPAddressToString -expandproperty IPAddressToString 109 | if($ip.GetType().Name -eq "Object[]") 110 | { 111 | #If we have several ip's for that address, let's take first one 112 | $ip = $ip[0] 113 | return $ip 114 | } 115 | } catch 116 | { 117 | $msg = "Unable to resolve $Name hostname or IP address $ipho. Maybe $ipho is a wrong hostname or IP!" 118 | Write-Verbose "$(Get-Date -format G) $msg" 119 | Write-To-Windows-EventLog "Error" 3006 $msg 120 | if ($stoponerror) { Exit } Else { Return "" } 121 | } 122 | 123 | } 124 | 125 | 126 | 127 | # --------------------------------------- 128 | # Send and array with metrics to Graphite 129 | # --------------------------------------- 130 | function sendtographite ($metrics) 131 | { 132 | $maxretries = 10 # Maximum number of retries to connect to a Graphite server. Only applicable if multiple servers are specified. With only 1 server it will try forever. 133 | $aservers = $graphiteserver -split ' ' 134 | 135 | foreach($s in 0..($aservers.count-1)){ 136 | 137 | $cserver = $aservers[$s] 138 | if ($cserver.contains(":")) 139 | { 140 | $atmp = $cserver -split ':' 141 | $cserver = $atmp[0] 142 | $cport = $atmp[1] 143 | } 144 | else 145 | { 146 | $cport = $graphiteserverport 147 | } 148 | 149 | $msg = "Sending $scount metrics for $vcount VMs of iteration # $iteration to Graphite server $cserver`:$cport" 150 | Write-Verbose "$(Get-Date -format G) $msg" 151 | Write-To-Windows-EventLog "Information" 1005 $msg 152 | $trycount = 1 153 | do { 154 | $iserr = $false 155 | Try 156 | { 157 | $socket = new-object system.net.sockets.tcpclient 158 | 159 | $socket.connect($cserver, $cport) 160 | 161 | $stream = $socket.getstream() 162 | $writer = new-object system.io.streamwriter($stream) 163 | 164 | foreach($i in 0..($metrics.count-1)){ 165 | $writer.writeline($metrics[$i]) 166 | } 167 | 168 | $writer.flush() 169 | $writer.close() 170 | $stream.close() 171 | $socket.close() 172 | } 173 | Catch 174 | { 175 | $IsErr = $true 176 | $ErrorMessage = $_.Exception.Message 177 | $FailedItem = $_.Exception.ItemName 178 | $msg = "Connection to $cserver`:$cport failed with $ErrorMessage! Will retry in 10 seconds" 179 | Write-Warning "$(Get-Date -format G) $msg" 180 | Write-To-Windows-EventLog "Warning" 2007 $msg 181 | Start-Sleep -s 10 182 | 183 | if (($trycount -ge $maxretries) -and ($aservers.count -gt 1)) { 184 | # Giving up this Server, it does not work, lets try the other one(s) 185 | $msg = "Giving up connection to $cserver`:$cport after $trycount failed attempts" 186 | Write-Error "$(Get-Date -format G) $msg" 187 | Write-To-Windows-EventLog "Error" 2007 $msg 188 | $IsErr = $false 189 | } 190 | 191 | $trycount++ 192 | 193 | } 194 | 195 | } while ($IsErr) 196 | } 197 | 198 | } 199 | 200 | 201 | # ----------------------------- 202 | # Connect to the VCenter Server 203 | # ----------------------------- 204 | function connectviserver($stoponerror) 205 | { 206 | 207 | if ($stoponerror) { $erroraction = "Stop" } else { $erroraction = "Continue" } 208 | 209 | do { 210 | if ($user -ne "") { 211 | $msg = "Connecting to vCenter Server $server as $user" 212 | } else { 213 | $msg = "Connecting to vCenter Server $server as currently logged on user " + [Environment]::UserDomainName + "\" + [Environment]::UserName 214 | } 215 | Write-Verbose "$(Get-Date -format G) $msg" 216 | Write-To-Windows-EventLog "Information" 1002 $msg 217 | 218 | if ($user -ne "") { 219 | [void] ( $vcc = Connect-VIServer -Server $server -User $user -Password $password -Protocol $protocol -ErrorAction $erroraction -ErrorVariable err -Verbose:$false ) 220 | } else { 221 | [void] ( $vcc = Connect-VIServer -Server $server -Protocol $protocol -ErrorAction $erroraction -ErrorVariable err -Verbose:$false ) 222 | } 223 | 224 | if ($err) { 225 | $msg = "Connection to $server failed! Will retry in 10 seconds" 226 | Write-Warning "$(Get-Date -format G) $msg" 227 | Write-To-Windows-EventLog "Error" 3002 $msg 228 | Start-Sleep -s 10 229 | } 230 | } while ($err) 231 | 232 | [void] ($global:vmdatacenter = Get-Datacenter -Server $vcc -Name $Datacenter -ErrorAction Stop -Verbose:$false) 233 | [void] ($global:vmcluster = Get-Cluster -Server $vcc -Name $Cluster -Location $global:vmdatacenter -ErrorAction Stop -Verbose:$false) 234 | 235 | return $vcc 236 | } 237 | 238 | # ------------------------------------------------------------------------------------- 239 | # Calculate the weighted average of the values in two arrays (IOPS and Latency, mostly) 240 | # ------------------------------------------------------------------------------------- 241 | function weighted_average($acount,$avalues) { 242 | for ($i=0; $i -lt $acount.Length; $i++) { 243 | $p += ($acount[$i]*$avalues[$i]) 244 | $s += $acount[$i] 245 | } 246 | 247 | if ($s -gt 0) { 248 | $wa = $p/$s 249 | } else { 250 | $wa = 0 251 | } 252 | return( $wa ) 253 | } 254 | 255 | # ----------------------------------------------------------------------------------------------------------------------------------------- 256 | # -- MAIN PROCEDURE ----------------------------------------------------------------------------------------------------------------------- 257 | # ----------------------------------------------------------------------------------------------------------------------------------------- 258 | 259 | if (!$Group.EndsWith(".")) {$Group = $Group+"."} 260 | $prefix = "vmperf." + $Group 261 | $global:vmdatacenter = $null 262 | $global:vmcluster = $null 263 | 264 | # Check PowerShell Version and exit if it is something below Version 4.0 265 | $psvermaj = $PSVersionTable.PSVersion.Major 266 | $psvermin = $PSVersionTable.PSVersion.Minor 267 | if ($psvermaj -lt 4) { 268 | $msg = "Unsupported PowerShell Version ($psvermaj.$psvermin). Please update your system to PowerShell Version 4.0 or above." 269 | Write-Error $msg 270 | Exit 271 | } 272 | 273 | # Initialize the PowerCLI environment if this is not already done. 274 | if ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { 275 | $msg = "Initializing VMware vSphere PowerCLI environment" 276 | Write-Verbose "$(Get-Date -format G) $msg" 277 | Write-To-Windows-EventLog "Information" 1001 $msg 278 | 279 | # Even is -Verbose switch is set, disable it while PowerCLI is initializing. 280 | $oldverbosepreference = $VerbosePreference 281 | $VerbosePreference = "SilentlyContinue" 282 | 283 | # Get the Install-Path of PowerCLI. If null then PowerCLI may not be installed. 284 | $idir = (Get-Module -ListAvailable -Name VMware.VimAutomation.Core).ModuleBase # Usually something like "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Modules\VMware.VimAutomation.Core" 285 | 286 | if ($idir -eq $null) { 287 | $msg="Error initializing VMWare PowerCLI environment. Cannot find path to VMWare PowerCLI in Registry. Make sure VMWare PowerCLI is installed on this host!" 288 | Write-Error $msg 289 | Write-To-Windows-EventLog "Error" 3001 $msg 290 | Exit 291 | } 292 | 293 | . "$idir\..\..\Scripts\Initialize-PowerCLIEnvironment.ps1" 294 | 295 | # Reset the Verbose setting to its previously value 296 | $VerbosePreference = $oldverbosepreference 297 | 298 | } 299 | 300 | # Try to resolve VCenter and Graphite Hostname(s) and Quit script if unsuccessful. 301 | checkiporhostname "VCenter server" $Server True 302 | 303 | $aservers = $graphiteserver -split ' ' 304 | foreach($s in 0..($aservers.count-1)){ 305 | 306 | $cserver = $aservers[$s] 307 | if ($cserver.contains(":")) 308 | { 309 | $atmp = $cserver -split ':' 310 | $cserver = $atmp[0] 311 | } 312 | checkiporhostname "Graphite" $cserver True 313 | } 314 | 315 | # First attempt to connect to the VCenter server. Stop immediately if the connection fails. 316 | $vcc = connectviserver True 317 | 318 | $dsTab = @{} 319 | Get-Datastore -Verbose:$false | where {$_.Type -eq "NFS"} | %{ 320 | $dsName = $_.Name 321 | $_.ExtensionData.Host | %{ 322 | $NfsUuid = $_.MountInfo.Path.Split('/')[3] 323 | if(!$dsTab.ContainsKey($NfsUuid)){ 324 | $dsTab.Add($NfsUuid,$dsName) 325 | } 326 | } 327 | } 328 | 329 | $metrics = "datastore.numberreadaveraged.average", 330 | "datastore.numberwriteaveraged.average", 331 | "datastore.write.average", 332 | "datastore.read.average", 333 | "datastore.totalreadlatency.average", 334 | "datastore.totalwritelatency.average", 335 | "cpu.usage.average" 336 | 337 | $iteration = 1 338 | 339 | # For the very first iteration, receive the last stats from VCenter 340 | $timespan = New-TimeSpan -Seconds $sleepseconds 341 | $starttime = (Get-Date)-$timespan 342 | 343 | if ($FromLastPoll -ne "") { 344 | $FromLastPoll = [System.IO.Path]::GetFullPath($FromLastPoll) 345 | if (Test-Path $FromLastPoll) { 346 | Write-Verbose "Reading last polling time from $FromLastPoll" 347 | $starttime = Import-Clixml $FromLastPoll 348 | Write-Verbose "Last polling time was $starttime" 349 | } 350 | } 351 | 352 | :crawlerloop while(($iteration -le $iterations) -OR ($iterations -eq 0)) { 353 | 354 | $msg = "Receiving list of VMs from vCenter server $server" 355 | Write-Verbose "$(Get-Date -format G) $msg" 356 | Write-To-Windows-EventLog "Information" 1003 $msg 357 | 358 | $errorcounter = 0 359 | do { 360 | $vms = Get-VM -Location $global:vmcluster -ErrorAction SilentlyContinue -ErrorVariable err -Verbose:$false | Sort -Unique | where-object {$_.ExtensionData.Config.ManagedBy.extensionKey -NotLike "com.vmware.vcDr*" -and $_.PowerState -eq "PoweredOn"} 361 | if ($err) { 362 | $errorcounter = $errorcounter +1 363 | if ($errorcounter % 10 -eq 0) 364 | # The connection failed for 10 consecutive times. Seems the connection to VCenter server got lost. Maybe the server was rebooted? 365 | # Try to reconnect to the server, do not Stop the script if the reconnect fails, try indefinitely. 366 | { $vcc = connectviserver False } 367 | else 368 | # The Get-VM function failed. Wait for 10 seconds and try again. Don't Panic. 369 | { 370 | $msg = "Connection to $server failed! Will retry in 10 seconds" 371 | Write-Warning "$(Get-Date -format G) $msg" 372 | Write-To-Windows-EventLog "Warning" 2003 $msg 373 | Start-Sleep -s 10 374 | } 375 | } 376 | } while ($err) 377 | 378 | $vcount = $vms.count 379 | 380 | # Remember the time where the last statistics-collection started. 381 | # For the next iteration, get the stats from this time until now, regardless how long the last iteration took. 382 | $laststart = Get-Date 383 | 384 | if ($vcount -gt 0) 385 | { 386 | 387 | $msg = "Receiving metrics for $vcount VMs from vCenter server $server" 388 | Write-Verbose "$(Get-Date -format G) $msg" 389 | Write-To-Windows-EventLog "Information" 1004 $msg 390 | 391 | # Receive the statistics for all running VMs, remove duplicates and create an array nice to step through. 392 | $i = 0; 393 | [System.Collections.ArrayList]$stats = @() 394 | foreach ($vmc in $vms) { 395 | 396 | $i = $i + 1 397 | Write-Progress -Activity "Receiving metrics..." -CurrentOperation "Virtual Machine ($i/$vcount): $($vmc.Name)" -Id 666 -PercentComplete ($i / $vcount * 100) 398 | 399 | $stat = Get-Stat -Entity $vmc -Stat $metrics -Realtime -Start $starttime -ErrorAction SilentlyContinue -Verbose:$false | 400 | Group-Object -Property {$_.Entity.Name+$_.Timestamp} | %{ 401 | New-Object PSObject -Property @{ 402 | VM = $_.Group[0].Entity.Name 403 | Timestamp = $_.Group[0].Timestamp 404 | Datastore = $dsTab[$_.Group[0].Instance] 405 | ReadIOPS = $_.Group | where {$_.MetricId -eq "datastore.numberreadaveraged.average"} | 406 | Measure-Object -Property Value -Sum | 407 | select -ExpandProperty Sum 408 | WriteIOPS = $_.Group | where {$_.MetricId -eq "datastore.numberwriteaveraged.average"} | 409 | Measure-Object -Property Value -Sum | 410 | select -ExpandProperty Sum 411 | ReadKBps = $_.Group | where {$_.MetricId -eq "datastore.read.average"} | 412 | Measure-Object -Property Value -Sum | 413 | select -ExpandProperty Sum 414 | WriteKBps = $_.Group | where {$_.MetricId -eq "datastore.write.average"} | 415 | Measure-Object -Property Value -Sum | 416 | select -ExpandProperty Sum 417 | ReadLat = weighted_average ($_.Group | where {$_.MetricId -eq "datastore.numberreadaveraged.average"} | Sort-Object Instance, Timestamp).Value ($_.Group | where {$_.MetricId -eq "datastore.totalreadlatency.average"} | Sort-Object Instance, Timestamp).Value 418 | WriteLat = weighted_average ($_.Group | where {$_.MetricId -eq "datastore.numberwriteaveraged.average"} | Sort-Object Instance, Timestamp).Value ($_.Group | where {$_.MetricId -eq "datastore.totalwritelatency.average"} | Sort-Object Instance, Timestamp).Value 419 | CPU = $_.Group | where {$_.MetricId -eq "cpu.usage.average"} | 420 | Measure-Object -Property Value -Average | 421 | select -ExpandProperty Average 422 | } 423 | } 424 | 425 | [void] ($stats.add($stat)) 426 | 427 | } 428 | Write-Progress -Activity "Receiving metrics..." -Completed -Id 666 429 | 430 | $starttime = $laststart 431 | 432 | if ($FromLastPoll -ne "") { 433 | Write-Verbose "Writing last Poll date and time ($starttime) to $FromLastPoll" 434 | $starttime | Export-Clixml $FromLastPoll 435 | } 436 | 437 | $scount = $stats.count 438 | $results = @{} 439 | foreach ($statx in $stats){ 440 | 441 | if ($statx -ne $null) { 442 | 443 | foreach ($stat in $statx){ 444 | 445 | # Replace characters not allowed and with an underscore and then any trailing and repeating underscores 446 | $vm = ($stat.VM) -replace '[^a-zA-Z0-9_\-]','_' -replace '[_]+','_' 447 | while ($vm.EndsWith("_")) { $vm = $vm.Substring(0,$vm.Length-1) } 448 | 449 | $totaliops = $stat.ReadIOPS + $stat.WriteIOPS 450 | $totalkbps = $stat.ReadKBps + $stat.WriteKBps 451 | 452 | $result = $prefix + $vm + ".ReadIOPS " + [int]$stat.ReadIOPS + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 453 | $results.add($results.count, $result) 454 | $result = $prefix + $vm + ".WriteIOPS " + [int]$stat.WriteIOPS + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 455 | $results.add($results.count, $result) 456 | $result = $prefix + $vm + ".TotalIOPS " + [int]$totaliops + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 457 | $results.add($results.count, $result) 458 | $result = $prefix + $vm + ".ReadKBps " + [int]$stat.ReadKBps + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 459 | $results.add($results.count, $result) 460 | $result = $prefix + $vm + ".WriteKBps " + [int]$stat.WriteKBps + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 461 | $results.add($results.count, $result) 462 | $result = $prefix + $vm + ".TotalKBps " + [int]$totalkbps + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 463 | $results.add($results.count, $result) 464 | $result = $prefix + $vm + ".ReadLatency " + $stat.ReadLat + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 465 | $results.add($results.count, $result) 466 | $result = $prefix + $vm + ".WriteLatency " + $stat.WriteLat + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 467 | $results.add($results.count, $result) 468 | $result = $prefix + $vm + ".CPU " + [int]$stat.CPU + " " + (get-date(($stat.Timestamp).touniversaltime()) -uformat "%s") 469 | $results.add($results.count, $result) 470 | 471 | } 472 | } 473 | } 474 | 475 | $scount = $results.count 476 | 477 | if (!$Whatif) 478 | { 479 | # Sends the metrics to Graphite. 480 | sendtographite $results 481 | } 482 | else 483 | { 484 | # Instead of sending the metrics to Graphite, send them to the console or pipe. 485 | $results.Values 486 | } 487 | } 488 | 489 | if(($iteration -lt $iterations) -OR ($iterations -eq 0)) { 490 | $msg = "$(Get-Date -format G) Sleeping for $sleepseconds seconds. Hit ENTER to stop sleeping or ESC to abort the script." 491 | Write-Verbose $msg 492 | 493 | # Sleep for $sleepseconds but let the user abort sleeping or the entire script 494 | $wakeuptime = (Get-Date)+$timespan 495 | $Host.UI.RawUI.FlushInputBuffer() 496 | :sleepmode while($true) { 497 | 498 | do { 499 | Start-Sleep -milliseconds 250 500 | } until ($Host.UI.RawUI.KeyAvailable -or (Get-Date) -ge $wakeuptime) 501 | 502 | if ((Get-Date) -ge $wakeuptime) { break sleepmode } 503 | 504 | $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") 505 | 506 | switch ($key.VirtualKeyCode) { 507 | 508 | 13 { break sleepmode } 509 | 27 { 510 | $title = "Abort Script" 511 | $message = "Do you really want to abort the script?" 512 | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Aborts the script." 513 | $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Continues with the script." 514 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) 515 | $result = $host.ui.PromptForChoice($title, $message, $options, 1) 516 | switch ($result) 517 | { 518 | 0 {break crawlerloop} 519 | 1 {continue sleepmode} 520 | } 521 | } 522 | default { 523 | $Host.UI.RawUI.FlushInputBuffer() 524 | continue sleepmode 525 | } 526 | } 527 | 528 | } 529 | $Host.UI.RawUI.FlushInputBuffer() 530 | } 531 | 532 | $iteration += 1 533 | } 534 | 535 | # Disconnect the VCenter server connection after the last iteration 536 | Disconnect-VIServer -Server $vcc -Force -Confirm:$false -Verbose:$false 537 | --------------------------------------------------------------------------------