├── LICENSE ├── README.md ├── dashboards ├── VSAN Backend-1523009729221.json ├── VSAN Diskgroup-1523009778902.json ├── VSAN Frontend-1523009720460.json └── VSAN Overview-1523009740260.json ├── host_performance_poller.ps1 ├── vcsa ├── appliance_backup.ps1 ├── appliance_health.ps1 ├── appliance_info.ps1 ├── appliance_monitoring.ps1 ├── appliance_storage.ps1 ├── appliance_update.ps1 ├── dashboards │ ├── VCSA Health-Repeating-rows.json │ └── VCSA health.json └── vcenter_services.ps1 ├── vm_performance_poller.ps1 ├── vsan_cluster_performance_poller.ps1 ├── vsan_cluster_performance_poller_withAuth.ps1 └── vsan_diskgroup_performance_poller.ps1 /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Rudi Martinsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vSpherePerfData 2 | 3 | A repository with the scripts used in my project on collecting and presenting performance data from vSphere / vCenter 4 | 5 | For more details on the project, checkout my blog series: https://www.rudimartinsen.com/vsphere-performance/ 6 | 7 | The VM and host scripts are explained in more details in http://www.rudimartinsen.com/2017/07/17/vsphere-performance-data-part-5-the-script/ 8 | 9 | The VSAN scripts are covered in http://www.rudimartinsen.com/2017/07/17/vsphere-performance-data-part-5-the-script/ 10 | 11 | The VCSA scripts and dashboard is explained in https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 12 | -------------------------------------------------------------------------------- /dashboards/VSAN Diskgroup-1523009778902.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_INFLUX", 5 | "label": "influx", 6 | "description": "", 7 | "type": "datasource", 8 | "pluginId": "influxdb", 9 | "pluginName": "InfluxDB" 10 | } 11 | ], 12 | "__requires": [ 13 | { 14 | "type": "grafana", 15 | "id": "grafana", 16 | "name": "Grafana", 17 | "version": "5.0.2" 18 | }, 19 | { 20 | "type": "panel", 21 | "id": "graph", 22 | "name": "Graph", 23 | "version": "5.0.0" 24 | }, 25 | { 26 | "type": "datasource", 27 | "id": "influxdb", 28 | "name": "InfluxDB", 29 | "version": "5.0.0" 30 | }, 31 | { 32 | "type": "panel", 33 | "id": "singlestat", 34 | "name": "Singlestat", 35 | "version": "5.0.0" 36 | } 37 | ], 38 | "annotations": { 39 | "list": [ 40 | { 41 | "builtIn": 1, 42 | "datasource": "-- Grafana --", 43 | "enable": true, 44 | "hide": true, 45 | "iconColor": "rgba(0, 211, 255, 1)", 46 | "name": "Annotations & Alerts", 47 | "type": "dashboard" 48 | } 49 | ] 50 | }, 51 | "editable": true, 52 | "gnetId": null, 53 | "graphTooltip": 0, 54 | "id": null, 55 | "iteration": 1523009742701, 56 | "links": [ 57 | { 58 | "icon": "external link", 59 | "tags": [ 60 | "vsan" 61 | ], 62 | "type": "dashboards" 63 | } 64 | ], 65 | "panels": [ 66 | { 67 | "cacheTimeout": null, 68 | "colorBackground": false, 69 | "colorValue": false, 70 | "colors": [ 71 | "#299c46", 72 | "rgba(237, 129, 40, 0.89)", 73 | "#d44a3a" 74 | ], 75 | "datasource": "${DS_INFLUX}", 76 | "format": "none", 77 | "gauge": { 78 | "maxValue": 100, 79 | "minValue": 0, 80 | "show": false, 81 | "thresholdLabels": false, 82 | "thresholdMarkers": true 83 | }, 84 | "gridPos": { 85 | "h": 3, 86 | "w": 5, 87 | "x": 0, 88 | "y": 0 89 | }, 90 | "id": 13, 91 | "interval": "5m", 92 | "links": [], 93 | "mappingType": 1, 94 | "mappingTypes": [ 95 | { 96 | "name": "value to text", 97 | "value": 1 98 | }, 99 | { 100 | "name": "range to text", 101 | "value": 2 102 | } 103 | ], 104 | "maxDataPoints": 100, 105 | "nullPointMode": "connected", 106 | "nullText": null, 107 | "postfix": "", 108 | "postfixFontSize": "50%", 109 | "prefix": "", 110 | "prefixFontSize": "50%", 111 | "rangeMaps": [ 112 | { 113 | "from": "null", 114 | "text": "N/A", 115 | "to": "null" 116 | } 117 | ], 118 | "sparkline": { 119 | "fillColor": "rgba(31, 118, 189, 0.18)", 120 | "full": false, 121 | "lineColor": "rgb(31, 120, 193)", 122 | "show": false 123 | }, 124 | "tableColumn": "", 125 | "targets": [ 126 | { 127 | "groupBy": [ 128 | { 129 | "params": [ 130 | "$__interval" 131 | ], 132 | "type": "time" 133 | } 134 | ], 135 | "measurement": "capacity", 136 | "orderByTime": "ASC", 137 | "policy": "default", 138 | "refId": "A", 139 | "resultFormat": "time_series", 140 | "select": [ 141 | [ 142 | { 143 | "params": [ 144 | "value" 145 | ], 146 | "type": "field" 147 | }, 148 | { 149 | "params": [], 150 | "type": "count" 151 | } 152 | ] 153 | ], 154 | "tags": [ 155 | { 156 | "key": "type", 157 | "operator": "=", 158 | "value": "vsan_diskgroup" 159 | }, 160 | { 161 | "condition": "AND", 162 | "key": "name", 163 | "operator": "=~", 164 | "value": "/^$diskgroup$/" 165 | }, 166 | { 167 | "condition": "AND", 168 | "key": "host", 169 | "operator": "=~", 170 | "value": "/^$host$/" 171 | } 172 | ] 173 | } 174 | ], 175 | "thresholds": "", 176 | "title": "Diskgroups", 177 | "type": "singlestat", 178 | "valueFontSize": "80%", 179 | "valueMaps": [ 180 | { 181 | "op": "=", 182 | "text": "N/A", 183 | "value": "null" 184 | } 185 | ], 186 | "valueName": "current" 187 | }, 188 | { 189 | "cacheTimeout": null, 190 | "colorBackground": false, 191 | "colorValue": false, 192 | "colors": [ 193 | "#299c46", 194 | "rgba(237, 129, 40, 0.89)", 195 | "#d44a3a" 196 | ], 197 | "datasource": "${DS_INFLUX}", 198 | "description": "VM count on the selected host(s)", 199 | "format": "short", 200 | "gauge": { 201 | "maxValue": 100, 202 | "minValue": 0, 203 | "show": false, 204 | "thresholdLabels": false, 205 | "thresholdMarkers": true 206 | }, 207 | "gridPos": { 208 | "h": 3, 209 | "w": 6, 210 | "x": 5, 211 | "y": 0 212 | }, 213 | "id": 14, 214 | "interval": null, 215 | "links": [], 216 | "mappingType": 1, 217 | "mappingTypes": [ 218 | { 219 | "name": "value to text", 220 | "value": 1 221 | }, 222 | { 223 | "name": "range to text", 224 | "value": 2 225 | } 226 | ], 227 | "maxDataPoints": 100, 228 | "nullPointMode": "connected", 229 | "nullText": null, 230 | "postfix": "", 231 | "postfixFontSize": "50%", 232 | "prefix": "", 233 | "prefixFontSize": "50%", 234 | "rangeMaps": [ 235 | { 236 | "from": "null", 237 | "text": "N/A", 238 | "to": "null" 239 | } 240 | ], 241 | "sparkline": { 242 | "fillColor": "rgba(31, 118, 189, 0.18)", 243 | "full": false, 244 | "lineColor": "rgb(31, 120, 193)", 245 | "show": false 246 | }, 247 | "tableColumn": "", 248 | "targets": [ 249 | { 250 | "groupBy": [ 251 | { 252 | "params": [ 253 | "$__interval" 254 | ], 255 | "type": "time" 256 | }, 257 | { 258 | "params": [ 259 | "null" 260 | ], 261 | "type": "fill" 262 | } 263 | ], 264 | "measurement": "cpu_usage", 265 | "orderByTime": "ASC", 266 | "policy": "default", 267 | "refId": "A", 268 | "resultFormat": "time_series", 269 | "select": [ 270 | [ 271 | { 272 | "params": [ 273 | "value" 274 | ], 275 | "type": "field" 276 | }, 277 | { 278 | "params": [], 279 | "type": "count" 280 | } 281 | ] 282 | ], 283 | "tags": [ 284 | { 285 | "key": "type", 286 | "operator": "=", 287 | "value": "vm" 288 | }, 289 | { 290 | "condition": "AND", 291 | "key": "host", 292 | "operator": "=~", 293 | "value": "/^$host$/" 294 | } 295 | ] 296 | } 297 | ], 298 | "thresholds": "", 299 | "title": "VMs", 300 | "transparent": false, 301 | "type": "singlestat", 302 | "valueFontSize": "80%", 303 | "valueMaps": [ 304 | { 305 | "op": "=", 306 | "text": "N/A", 307 | "value": "null" 308 | } 309 | ], 310 | "valueName": "current" 311 | }, 312 | { 313 | "cacheTimeout": null, 314 | "colorBackground": false, 315 | "colorValue": false, 316 | "colors": [ 317 | "#299c46", 318 | "rgba(237, 129, 40, 0.89)", 319 | "#d44a3a" 320 | ], 321 | "datasource": "${DS_INFLUX}", 322 | "description": "Average capacity of the diskgroup(s)", 323 | "format": "decgbytes", 324 | "gauge": { 325 | "maxValue": 100, 326 | "minValue": 0, 327 | "show": false, 328 | "thresholdLabels": false, 329 | "thresholdMarkers": true 330 | }, 331 | "gridPos": { 332 | "h": 3, 333 | "w": 10, 334 | "x": 11, 335 | "y": 0 336 | }, 337 | "id": 11, 338 | "interval": null, 339 | "links": [], 340 | "mappingType": 1, 341 | "mappingTypes": [ 342 | { 343 | "name": "value to text", 344 | "value": 1 345 | }, 346 | { 347 | "name": "range to text", 348 | "value": 2 349 | } 350 | ], 351 | "maxDataPoints": 100, 352 | "nullPointMode": "connected", 353 | "nullText": null, 354 | "postfix": "", 355 | "postfixFontSize": "50%", 356 | "prefix": "", 357 | "prefixFontSize": "50%", 358 | "rangeMaps": [ 359 | { 360 | "from": "null", 361 | "text": "N/A", 362 | "to": "null" 363 | } 364 | ], 365 | "sparkline": { 366 | "fillColor": "rgba(31, 118, 189, 0.18)", 367 | "full": false, 368 | "lineColor": "rgb(31, 120, 193)", 369 | "show": false 370 | }, 371 | "tableColumn": "", 372 | "targets": [ 373 | { 374 | "groupBy": [ 375 | { 376 | "params": [ 377 | "$__interval" 378 | ], 379 | "type": "time" 380 | }, 381 | { 382 | "params": [ 383 | "null" 384 | ], 385 | "type": "fill" 386 | } 387 | ], 388 | "measurement": "capacity", 389 | "orderByTime": "ASC", 390 | "policy": "default", 391 | "refId": "A", 392 | "resultFormat": "time_series", 393 | "select": [ 394 | [ 395 | { 396 | "params": [ 397 | "value" 398 | ], 399 | "type": "field" 400 | }, 401 | { 402 | "params": [], 403 | "type": "mean" 404 | } 405 | ] 406 | ], 407 | "tags": [ 408 | { 409 | "key": "type", 410 | "operator": "=", 411 | "value": "vsan_diskgroup" 412 | }, 413 | { 414 | "condition": "AND", 415 | "key": "name", 416 | "operator": "=~", 417 | "value": "/^$diskgroup$/" 418 | }, 419 | { 420 | "condition": "AND", 421 | "key": "host", 422 | "operator": "=~", 423 | "value": "/^$host$/" 424 | } 425 | ] 426 | } 427 | ], 428 | "thresholds": "", 429 | "title": "Capacity", 430 | "transparent": false, 431 | "type": "singlestat", 432 | "valueFontSize": "80%", 433 | "valueMaps": [ 434 | { 435 | "op": "=", 436 | "text": "N/A", 437 | "value": "null" 438 | } 439 | ], 440 | "valueName": "current" 441 | }, 442 | { 443 | "cacheTimeout": null, 444 | "colorBackground": false, 445 | "colorValue": false, 446 | "colors": [ 447 | "#299c46", 448 | "rgba(237, 129, 40, 0.89)", 449 | "#d44a3a" 450 | ], 451 | "datasource": "${DS_INFLUX}", 452 | "format": "KBs", 453 | "gauge": { 454 | "maxValue": 100, 455 | "minValue": 0, 456 | "show": false, 457 | "thresholdLabels": false, 458 | "thresholdMarkers": true 459 | }, 460 | "gridPos": { 461 | "h": 3, 462 | "w": 6, 463 | "x": 0, 464 | "y": 3 465 | }, 466 | "id": 16, 467 | "interval": "5m", 468 | "links": [], 469 | "mappingType": 1, 470 | "mappingTypes": [ 471 | { 472 | "name": "value to text", 473 | "value": 1 474 | }, 475 | { 476 | "name": "range to text", 477 | "value": 2 478 | } 479 | ], 480 | "maxDataPoints": 100, 481 | "nullPointMode": "connected", 482 | "nullText": null, 483 | "postfix": "", 484 | "postfixFontSize": "50%", 485 | "prefix": "", 486 | "prefixFontSize": "50%", 487 | "rangeMaps": [ 488 | { 489 | "from": "null", 490 | "text": "N/A", 491 | "to": "null" 492 | } 493 | ], 494 | "sparkline": { 495 | "fillColor": "rgba(31, 118, 189, 0.18)", 496 | "full": false, 497 | "lineColor": "rgb(31, 120, 193)", 498 | "show": false 499 | }, 500 | "tableColumn": "", 501 | "targets": [ 502 | { 503 | "groupBy": [], 504 | "measurement": "kB_read", 505 | "orderByTime": "ASC", 506 | "policy": "default", 507 | "refId": "A", 508 | "resultFormat": "time_series", 509 | "select": [ 510 | [ 511 | { 512 | "params": [ 513 | "value" 514 | ], 515 | "type": "field" 516 | } 517 | ] 518 | ], 519 | "tags": [ 520 | { 521 | "key": "type", 522 | "operator": "=", 523 | "value": "vsan_diskgroup" 524 | }, 525 | { 526 | "condition": "AND", 527 | "key": "host", 528 | "operator": "=~", 529 | "value": "/^$host$/" 530 | }, 531 | { 532 | "condition": "AND", 533 | "key": "name", 534 | "operator": "=~", 535 | "value": "/^$diskgroup$/" 536 | } 537 | ] 538 | } 539 | ], 540 | "thresholds": "", 541 | "title": "Read Throughput", 542 | "type": "singlestat", 543 | "valueFontSize": "80%", 544 | "valueMaps": [ 545 | { 546 | "op": "=", 547 | "text": "N/A", 548 | "value": "null" 549 | } 550 | ], 551 | "valueName": "max" 552 | }, 553 | { 554 | "cacheTimeout": null, 555 | "colorBackground": true, 556 | "colorValue": false, 557 | "colors": [ 558 | "#299c46", 559 | "rgba(237, 129, 40, 0.89)", 560 | "#d44a3a" 561 | ], 562 | "datasource": "${DS_INFLUX}", 563 | "format": "ms", 564 | "gauge": { 565 | "maxValue": 100, 566 | "minValue": 0, 567 | "show": false, 568 | "thresholdLabels": false, 569 | "thresholdMarkers": true 570 | }, 571 | "gridPos": { 572 | "h": 3, 573 | "w": 6, 574 | "x": 6, 575 | "y": 3 576 | }, 577 | "id": 18, 578 | "interval": "5m", 579 | "links": [], 580 | "mappingType": 1, 581 | "mappingTypes": [ 582 | { 583 | "name": "value to text", 584 | "value": 1 585 | }, 586 | { 587 | "name": "range to text", 588 | "value": 2 589 | } 590 | ], 591 | "maxDataPoints": 100, 592 | "nullPointMode": "connected", 593 | "nullText": null, 594 | "postfix": "", 595 | "postfixFontSize": "50%", 596 | "prefix": "", 597 | "prefixFontSize": "50%", 598 | "rangeMaps": [ 599 | { 600 | "from": "null", 601 | "text": "N/A", 602 | "to": "null" 603 | } 604 | ], 605 | "sparkline": { 606 | "fillColor": "rgba(31, 118, 189, 0.18)", 607 | "full": false, 608 | "lineColor": "rgb(31, 120, 193)", 609 | "show": false 610 | }, 611 | "tableColumn": "", 612 | "targets": [ 613 | { 614 | "groupBy": [], 615 | "measurement": "latency_read", 616 | "orderByTime": "ASC", 617 | "policy": "default", 618 | "refId": "A", 619 | "resultFormat": "time_series", 620 | "select": [ 621 | [ 622 | { 623 | "params": [ 624 | "value" 625 | ], 626 | "type": "field" 627 | } 628 | ] 629 | ], 630 | "tags": [ 631 | { 632 | "key": "type", 633 | "operator": "=", 634 | "value": "vsan_diskgroup" 635 | }, 636 | { 637 | "condition": "AND", 638 | "key": "host", 639 | "operator": "=~", 640 | "value": "/^$host$/" 641 | }, 642 | { 643 | "condition": "AND", 644 | "key": "name", 645 | "operator": "=~", 646 | "value": "/^$diskgroup$/" 647 | } 648 | ] 649 | } 650 | ], 651 | "thresholds": "10,20,30", 652 | "title": "Read Latency", 653 | "type": "singlestat", 654 | "valueFontSize": "80%", 655 | "valueMaps": [ 656 | { 657 | "op": "=", 658 | "text": "N/A", 659 | "value": "null" 660 | } 661 | ], 662 | "valueName": "max" 663 | }, 664 | { 665 | "cacheTimeout": null, 666 | "colorBackground": false, 667 | "colorValue": false, 668 | "colors": [ 669 | "#299c46", 670 | "rgba(237, 129, 40, 0.89)", 671 | "#d44a3a" 672 | ], 673 | "datasource": "${DS_INFLUX}", 674 | "format": "KBs", 675 | "gauge": { 676 | "maxValue": 100, 677 | "minValue": 0, 678 | "show": false, 679 | "thresholdLabels": false, 680 | "thresholdMarkers": true 681 | }, 682 | "gridPos": { 683 | "h": 3, 684 | "w": 6, 685 | "x": 12, 686 | "y": 3 687 | }, 688 | "id": 19, 689 | "interval": "5m", 690 | "links": [], 691 | "mappingType": 1, 692 | "mappingTypes": [ 693 | { 694 | "name": "value to text", 695 | "value": 1 696 | }, 697 | { 698 | "name": "range to text", 699 | "value": 2 700 | } 701 | ], 702 | "maxDataPoints": 100, 703 | "nullPointMode": "connected", 704 | "nullText": null, 705 | "postfix": "", 706 | "postfixFontSize": "50%", 707 | "prefix": "", 708 | "prefixFontSize": "50%", 709 | "rangeMaps": [ 710 | { 711 | "from": "null", 712 | "text": "N/A", 713 | "to": "null" 714 | } 715 | ], 716 | "sparkline": { 717 | "fillColor": "rgba(31, 118, 189, 0.18)", 718 | "full": false, 719 | "lineColor": "rgb(31, 120, 193)", 720 | "show": false 721 | }, 722 | "tableColumn": "", 723 | "targets": [ 724 | { 725 | "groupBy": [], 726 | "measurement": "kB_write", 727 | "orderByTime": "ASC", 728 | "policy": "default", 729 | "refId": "A", 730 | "resultFormat": "time_series", 731 | "select": [ 732 | [ 733 | { 734 | "params": [ 735 | "value" 736 | ], 737 | "type": "field" 738 | } 739 | ] 740 | ], 741 | "tags": [ 742 | { 743 | "key": "type", 744 | "operator": "=", 745 | "value": "vsan_diskgroup" 746 | }, 747 | { 748 | "condition": "AND", 749 | "key": "host", 750 | "operator": "=~", 751 | "value": "/^$host$/" 752 | }, 753 | { 754 | "condition": "AND", 755 | "key": "name", 756 | "operator": "=~", 757 | "value": "/^$diskgroup$/" 758 | } 759 | ] 760 | } 761 | ], 762 | "thresholds": "", 763 | "title": "Read Throughput", 764 | "type": "singlestat", 765 | "valueFontSize": "80%", 766 | "valueMaps": [ 767 | { 768 | "op": "=", 769 | "text": "N/A", 770 | "value": "null" 771 | } 772 | ], 773 | "valueName": "max" 774 | }, 775 | { 776 | "cacheTimeout": null, 777 | "colorBackground": true, 778 | "colorValue": false, 779 | "colors": [ 780 | "#299c46", 781 | "rgba(237, 129, 40, 0.89)", 782 | "#d44a3a" 783 | ], 784 | "datasource": "${DS_INFLUX}", 785 | "format": "ms", 786 | "gauge": { 787 | "maxValue": 100, 788 | "minValue": 0, 789 | "show": false, 790 | "thresholdLabels": false, 791 | "thresholdMarkers": true 792 | }, 793 | "gridPos": { 794 | "h": 3, 795 | "w": 6, 796 | "x": 18, 797 | "y": 3 798 | }, 799 | "id": 17, 800 | "interval": "5m", 801 | "links": [], 802 | "mappingType": 1, 803 | "mappingTypes": [ 804 | { 805 | "name": "value to text", 806 | "value": 1 807 | }, 808 | { 809 | "name": "range to text", 810 | "value": 2 811 | } 812 | ], 813 | "maxDataPoints": 100, 814 | "nullPointMode": "connected", 815 | "nullText": null, 816 | "postfix": "", 817 | "postfixFontSize": "50%", 818 | "prefix": "", 819 | "prefixFontSize": "50%", 820 | "rangeMaps": [ 821 | { 822 | "from": "null", 823 | "text": "N/A", 824 | "to": "null" 825 | } 826 | ], 827 | "sparkline": { 828 | "fillColor": "rgba(31, 118, 189, 0.18)", 829 | "full": false, 830 | "lineColor": "rgb(31, 120, 193)", 831 | "show": false 832 | }, 833 | "tableColumn": "", 834 | "targets": [ 835 | { 836 | "groupBy": [], 837 | "measurement": "latency_write", 838 | "orderByTime": "ASC", 839 | "policy": "default", 840 | "refId": "A", 841 | "resultFormat": "time_series", 842 | "select": [ 843 | [ 844 | { 845 | "params": [ 846 | "value" 847 | ], 848 | "type": "field" 849 | } 850 | ] 851 | ], 852 | "tags": [ 853 | { 854 | "key": "type", 855 | "operator": "=", 856 | "value": "vsan_diskgroup" 857 | }, 858 | { 859 | "condition": "AND", 860 | "key": "host", 861 | "operator": "=~", 862 | "value": "/^$host$/" 863 | }, 864 | { 865 | "condition": "AND", 866 | "key": "name", 867 | "operator": "=~", 868 | "value": "/^$diskgroup$/" 869 | } 870 | ] 871 | } 872 | ], 873 | "thresholds": "10,20,30", 874 | "title": "Write Latency", 875 | "type": "singlestat", 876 | "valueFontSize": "80%", 877 | "valueMaps": [ 878 | { 879 | "op": "=", 880 | "text": "N/A", 881 | "value": "null" 882 | } 883 | ], 884 | "valueName": "max" 885 | }, 886 | { 887 | "aliasColors": {}, 888 | "bars": false, 889 | "dashLength": 10, 890 | "dashes": false, 891 | "datasource": "${DS_INFLUX}", 892 | "fill": 1, 893 | "gridPos": { 894 | "h": 9, 895 | "w": 12, 896 | "x": 0, 897 | "y": 6 898 | }, 899 | "id": 2, 900 | "interval": "5m", 901 | "legend": { 902 | "avg": false, 903 | "current": false, 904 | "max": false, 905 | "min": false, 906 | "show": true, 907 | "total": false, 908 | "values": false 909 | }, 910 | "lines": true, 911 | "linewidth": 1, 912 | "links": [], 913 | "nullPointMode": "null", 914 | "percentage": false, 915 | "pointradius": 5, 916 | "points": false, 917 | "renderer": "flot", 918 | "seriesOverrides": [], 919 | "spaceLength": 10, 920 | "stack": false, 921 | "steppedLine": false, 922 | "targets": [ 923 | { 924 | "alias": "$tag_name", 925 | "groupBy": [ 926 | { 927 | "params": [ 928 | "$__interval" 929 | ], 930 | "type": "time" 931 | }, 932 | { 933 | "params": [ 934 | "name" 935 | ], 936 | "type": "tag" 937 | }, 938 | { 939 | "params": [ 940 | "null" 941 | ], 942 | "type": "fill" 943 | } 944 | ], 945 | "measurement": "kB_read", 946 | "orderByTime": "ASC", 947 | "policy": "default", 948 | "refId": "A", 949 | "resultFormat": "time_series", 950 | "select": [ 951 | [ 952 | { 953 | "params": [ 954 | "value" 955 | ], 956 | "type": "field" 957 | }, 958 | { 959 | "params": [], 960 | "type": "mean" 961 | } 962 | ] 963 | ], 964 | "tags": [ 965 | { 966 | "key": "type", 967 | "operator": "=", 968 | "value": "vsan_diskgroup" 969 | }, 970 | { 971 | "condition": "AND", 972 | "key": "host", 973 | "operator": "=~", 974 | "value": "/^$host$/" 975 | }, 976 | { 977 | "condition": "AND", 978 | "key": "name", 979 | "operator": "=~", 980 | "value": "/^$diskgroup$/" 981 | } 982 | ] 983 | } 984 | ], 985 | "thresholds": [], 986 | "timeFrom": null, 987 | "timeShift": null, 988 | "title": "Read Throughput", 989 | "tooltip": { 990 | "shared": true, 991 | "sort": 0, 992 | "value_type": "individual" 993 | }, 994 | "type": "graph", 995 | "xaxis": { 996 | "buckets": null, 997 | "mode": "time", 998 | "name": null, 999 | "show": true, 1000 | "values": [] 1001 | }, 1002 | "yaxes": [ 1003 | { 1004 | "format": "KBs", 1005 | "label": null, 1006 | "logBase": 1, 1007 | "max": null, 1008 | "min": null, 1009 | "show": true 1010 | }, 1011 | { 1012 | "format": "short", 1013 | "label": null, 1014 | "logBase": 1, 1015 | "max": null, 1016 | "min": null, 1017 | "show": true 1018 | } 1019 | ] 1020 | }, 1021 | { 1022 | "aliasColors": {}, 1023 | "bars": false, 1024 | "dashLength": 10, 1025 | "dashes": false, 1026 | "datasource": "${DS_INFLUX}", 1027 | "fill": 1, 1028 | "gridPos": { 1029 | "h": 9, 1030 | "w": 12, 1031 | "x": 12, 1032 | "y": 6 1033 | }, 1034 | "id": 3, 1035 | "interval": "5m", 1036 | "legend": { 1037 | "avg": false, 1038 | "current": false, 1039 | "max": false, 1040 | "min": false, 1041 | "show": true, 1042 | "total": false, 1043 | "values": false 1044 | }, 1045 | "lines": true, 1046 | "linewidth": 1, 1047 | "links": [], 1048 | "nullPointMode": "null", 1049 | "percentage": false, 1050 | "pointradius": 5, 1051 | "points": false, 1052 | "renderer": "flot", 1053 | "seriesOverrides": [], 1054 | "spaceLength": 10, 1055 | "stack": false, 1056 | "steppedLine": false, 1057 | "targets": [ 1058 | { 1059 | "alias": "$tag_name", 1060 | "groupBy": [ 1061 | { 1062 | "params": [ 1063 | "$__interval" 1064 | ], 1065 | "type": "time" 1066 | }, 1067 | { 1068 | "params": [ 1069 | "name" 1070 | ], 1071 | "type": "tag" 1072 | }, 1073 | { 1074 | "params": [ 1075 | "null" 1076 | ], 1077 | "type": "fill" 1078 | } 1079 | ], 1080 | "measurement": "kB_write", 1081 | "orderByTime": "ASC", 1082 | "policy": "default", 1083 | "refId": "A", 1084 | "resultFormat": "time_series", 1085 | "select": [ 1086 | [ 1087 | { 1088 | "params": [ 1089 | "value" 1090 | ], 1091 | "type": "field" 1092 | }, 1093 | { 1094 | "params": [], 1095 | "type": "mean" 1096 | } 1097 | ] 1098 | ], 1099 | "tags": [ 1100 | { 1101 | "key": "type", 1102 | "operator": "=", 1103 | "value": "vsan_diskgroup" 1104 | }, 1105 | { 1106 | "condition": "AND", 1107 | "key": "host", 1108 | "operator": "=~", 1109 | "value": "/^$host$/" 1110 | }, 1111 | { 1112 | "condition": "AND", 1113 | "key": "name", 1114 | "operator": "=~", 1115 | "value": "/^$diskgroup$/" 1116 | } 1117 | ] 1118 | } 1119 | ], 1120 | "thresholds": [], 1121 | "timeFrom": null, 1122 | "timeShift": null, 1123 | "title": "Write Throughput", 1124 | "tooltip": { 1125 | "shared": true, 1126 | "sort": 0, 1127 | "value_type": "individual" 1128 | }, 1129 | "type": "graph", 1130 | "xaxis": { 1131 | "buckets": null, 1132 | "mode": "time", 1133 | "name": null, 1134 | "show": true, 1135 | "values": [] 1136 | }, 1137 | "yaxes": [ 1138 | { 1139 | "format": "KBs", 1140 | "label": null, 1141 | "logBase": 1, 1142 | "max": null, 1143 | "min": null, 1144 | "show": true 1145 | }, 1146 | { 1147 | "format": "short", 1148 | "label": null, 1149 | "logBase": 1, 1150 | "max": null, 1151 | "min": null, 1152 | "show": true 1153 | } 1154 | ] 1155 | }, 1156 | { 1157 | "aliasColors": {}, 1158 | "bars": false, 1159 | "dashLength": 10, 1160 | "dashes": false, 1161 | "datasource": "${DS_INFLUX}", 1162 | "fill": 1, 1163 | "gridPos": { 1164 | "h": 9, 1165 | "w": 12, 1166 | "x": 0, 1167 | "y": 15 1168 | }, 1169 | "id": 8, 1170 | "interval": "5m", 1171 | "legend": { 1172 | "avg": false, 1173 | "current": false, 1174 | "max": false, 1175 | "min": false, 1176 | "show": true, 1177 | "total": false, 1178 | "values": false 1179 | }, 1180 | "lines": true, 1181 | "linewidth": 1, 1182 | "links": [], 1183 | "nullPointMode": "null", 1184 | "percentage": false, 1185 | "pointradius": 5, 1186 | "points": false, 1187 | "renderer": "flot", 1188 | "seriesOverrides": [], 1189 | "spaceLength": 10, 1190 | "stack": false, 1191 | "steppedLine": false, 1192 | "targets": [ 1193 | { 1194 | "alias": "$tag_name", 1195 | "groupBy": [ 1196 | { 1197 | "params": [ 1198 | "$__interval" 1199 | ], 1200 | "type": "time" 1201 | }, 1202 | { 1203 | "params": [ 1204 | "name" 1205 | ], 1206 | "type": "tag" 1207 | }, 1208 | { 1209 | "params": [ 1210 | "null" 1211 | ], 1212 | "type": "fill" 1213 | } 1214 | ], 1215 | "measurement": "io_read", 1216 | "orderByTime": "ASC", 1217 | "policy": "default", 1218 | "refId": "A", 1219 | "resultFormat": "time_series", 1220 | "select": [ 1221 | [ 1222 | { 1223 | "params": [ 1224 | "value" 1225 | ], 1226 | "type": "field" 1227 | }, 1228 | { 1229 | "params": [], 1230 | "type": "mean" 1231 | } 1232 | ] 1233 | ], 1234 | "tags": [ 1235 | { 1236 | "key": "type", 1237 | "operator": "=", 1238 | "value": "vsan_diskgroup" 1239 | }, 1240 | { 1241 | "condition": "AND", 1242 | "key": "host", 1243 | "operator": "=~", 1244 | "value": "/^$host$/" 1245 | }, 1246 | { 1247 | "condition": "AND", 1248 | "key": "name", 1249 | "operator": "=~", 1250 | "value": "/^$diskgroup$/" 1251 | } 1252 | ] 1253 | } 1254 | ], 1255 | "thresholds": [], 1256 | "timeFrom": null, 1257 | "timeShift": null, 1258 | "title": "Read IOps", 1259 | "tooltip": { 1260 | "shared": true, 1261 | "sort": 0, 1262 | "value_type": "individual" 1263 | }, 1264 | "type": "graph", 1265 | "xaxis": { 1266 | "buckets": null, 1267 | "mode": "time", 1268 | "name": null, 1269 | "show": true, 1270 | "values": [] 1271 | }, 1272 | "yaxes": [ 1273 | { 1274 | "format": "iops", 1275 | "label": null, 1276 | "logBase": 1, 1277 | "max": null, 1278 | "min": null, 1279 | "show": true 1280 | }, 1281 | { 1282 | "format": "short", 1283 | "label": null, 1284 | "logBase": 1, 1285 | "max": null, 1286 | "min": null, 1287 | "show": true 1288 | } 1289 | ] 1290 | }, 1291 | { 1292 | "aliasColors": {}, 1293 | "bars": false, 1294 | "dashLength": 10, 1295 | "dashes": false, 1296 | "datasource": "${DS_INFLUX}", 1297 | "fill": 1, 1298 | "gridPos": { 1299 | "h": 9, 1300 | "w": 12, 1301 | "x": 12, 1302 | "y": 15 1303 | }, 1304 | "id": 9, 1305 | "interval": "5m", 1306 | "legend": { 1307 | "avg": false, 1308 | "current": false, 1309 | "max": false, 1310 | "min": false, 1311 | "show": true, 1312 | "total": false, 1313 | "values": false 1314 | }, 1315 | "lines": true, 1316 | "linewidth": 1, 1317 | "links": [], 1318 | "nullPointMode": "null", 1319 | "percentage": false, 1320 | "pointradius": 5, 1321 | "points": false, 1322 | "renderer": "flot", 1323 | "seriesOverrides": [], 1324 | "spaceLength": 10, 1325 | "stack": false, 1326 | "steppedLine": false, 1327 | "targets": [ 1328 | { 1329 | "alias": "$tag_name", 1330 | "groupBy": [ 1331 | { 1332 | "params": [ 1333 | "$__interval" 1334 | ], 1335 | "type": "time" 1336 | }, 1337 | { 1338 | "params": [ 1339 | "name" 1340 | ], 1341 | "type": "tag" 1342 | }, 1343 | { 1344 | "params": [ 1345 | "null" 1346 | ], 1347 | "type": "fill" 1348 | } 1349 | ], 1350 | "measurement": "io_write", 1351 | "orderByTime": "ASC", 1352 | "policy": "default", 1353 | "refId": "A", 1354 | "resultFormat": "time_series", 1355 | "select": [ 1356 | [ 1357 | { 1358 | "params": [ 1359 | "value" 1360 | ], 1361 | "type": "field" 1362 | }, 1363 | { 1364 | "params": [], 1365 | "type": "mean" 1366 | } 1367 | ] 1368 | ], 1369 | "tags": [ 1370 | { 1371 | "key": "type", 1372 | "operator": "=", 1373 | "value": "vsan_diskgroup" 1374 | }, 1375 | { 1376 | "condition": "AND", 1377 | "key": "host", 1378 | "operator": "=~", 1379 | "value": "/^$host$/" 1380 | }, 1381 | { 1382 | "condition": "AND", 1383 | "key": "name", 1384 | "operator": "=~", 1385 | "value": "/^$diskgroup$/" 1386 | } 1387 | ] 1388 | } 1389 | ], 1390 | "thresholds": [], 1391 | "timeFrom": null, 1392 | "timeShift": null, 1393 | "title": "Write IOps", 1394 | "tooltip": { 1395 | "shared": true, 1396 | "sort": 0, 1397 | "value_type": "individual" 1398 | }, 1399 | "type": "graph", 1400 | "xaxis": { 1401 | "buckets": null, 1402 | "mode": "time", 1403 | "name": null, 1404 | "show": true, 1405 | "values": [] 1406 | }, 1407 | "yaxes": [ 1408 | { 1409 | "format": "iops", 1410 | "label": null, 1411 | "logBase": 1, 1412 | "max": null, 1413 | "min": null, 1414 | "show": true 1415 | }, 1416 | { 1417 | "format": "short", 1418 | "label": null, 1419 | "logBase": 1, 1420 | "max": null, 1421 | "min": null, 1422 | "show": true 1423 | } 1424 | ] 1425 | }, 1426 | { 1427 | "aliasColors": {}, 1428 | "bars": false, 1429 | "dashLength": 10, 1430 | "dashes": false, 1431 | "datasource": "${DS_INFLUX}", 1432 | "fill": 1, 1433 | "gridPos": { 1434 | "h": 9, 1435 | "w": 12, 1436 | "x": 0, 1437 | "y": 24 1438 | }, 1439 | "id": 4, 1440 | "interval": "5m", 1441 | "legend": { 1442 | "avg": false, 1443 | "current": false, 1444 | "max": false, 1445 | "min": false, 1446 | "show": true, 1447 | "total": false, 1448 | "values": false 1449 | }, 1450 | "lines": true, 1451 | "linewidth": 1, 1452 | "links": [], 1453 | "nullPointMode": "null", 1454 | "percentage": false, 1455 | "pointradius": 5, 1456 | "points": false, 1457 | "renderer": "flot", 1458 | "seriesOverrides": [], 1459 | "spaceLength": 10, 1460 | "stack": false, 1461 | "steppedLine": false, 1462 | "targets": [ 1463 | { 1464 | "alias": "$tag_name", 1465 | "groupBy": [ 1466 | { 1467 | "params": [ 1468 | "$__interval" 1469 | ], 1470 | "type": "time" 1471 | }, 1472 | { 1473 | "params": [ 1474 | "name" 1475 | ], 1476 | "type": "tag" 1477 | }, 1478 | { 1479 | "params": [ 1480 | "null" 1481 | ], 1482 | "type": "fill" 1483 | } 1484 | ], 1485 | "measurement": "latency_read", 1486 | "orderByTime": "ASC", 1487 | "policy": "default", 1488 | "refId": "A", 1489 | "resultFormat": "time_series", 1490 | "select": [ 1491 | [ 1492 | { 1493 | "params": [ 1494 | "value" 1495 | ], 1496 | "type": "field" 1497 | }, 1498 | { 1499 | "params": [], 1500 | "type": "mean" 1501 | } 1502 | ] 1503 | ], 1504 | "tags": [ 1505 | { 1506 | "key": "type", 1507 | "operator": "=", 1508 | "value": "vsan_diskgroup" 1509 | }, 1510 | { 1511 | "condition": "AND", 1512 | "key": "host", 1513 | "operator": "=~", 1514 | "value": "/^$host$/" 1515 | }, 1516 | { 1517 | "condition": "AND", 1518 | "key": "name", 1519 | "operator": "=~", 1520 | "value": "/^$diskgroup$/" 1521 | } 1522 | ] 1523 | } 1524 | ], 1525 | "thresholds": [], 1526 | "timeFrom": null, 1527 | "timeShift": null, 1528 | "title": "Read Latency", 1529 | "tooltip": { 1530 | "shared": true, 1531 | "sort": 0, 1532 | "value_type": "individual" 1533 | }, 1534 | "type": "graph", 1535 | "xaxis": { 1536 | "buckets": null, 1537 | "mode": "time", 1538 | "name": null, 1539 | "show": true, 1540 | "values": [] 1541 | }, 1542 | "yaxes": [ 1543 | { 1544 | "format": "ms", 1545 | "label": null, 1546 | "logBase": 1, 1547 | "max": null, 1548 | "min": null, 1549 | "show": true 1550 | }, 1551 | { 1552 | "format": "short", 1553 | "label": null, 1554 | "logBase": 1, 1555 | "max": null, 1556 | "min": null, 1557 | "show": true 1558 | } 1559 | ] 1560 | }, 1561 | { 1562 | "aliasColors": {}, 1563 | "bars": false, 1564 | "dashLength": 10, 1565 | "dashes": false, 1566 | "datasource": "${DS_INFLUX}", 1567 | "fill": 1, 1568 | "gridPos": { 1569 | "h": 9, 1570 | "w": 12, 1571 | "x": 12, 1572 | "y": 24 1573 | }, 1574 | "id": 5, 1575 | "interval": "5m", 1576 | "legend": { 1577 | "avg": false, 1578 | "current": false, 1579 | "max": false, 1580 | "min": false, 1581 | "show": true, 1582 | "total": false, 1583 | "values": false 1584 | }, 1585 | "lines": true, 1586 | "linewidth": 1, 1587 | "links": [], 1588 | "nullPointMode": "null", 1589 | "percentage": false, 1590 | "pointradius": 5, 1591 | "points": false, 1592 | "renderer": "flot", 1593 | "seriesOverrides": [], 1594 | "spaceLength": 10, 1595 | "stack": false, 1596 | "steppedLine": false, 1597 | "targets": [ 1598 | { 1599 | "alias": "$tag_name", 1600 | "groupBy": [ 1601 | { 1602 | "params": [ 1603 | "$__interval" 1604 | ], 1605 | "type": "time" 1606 | }, 1607 | { 1608 | "params": [ 1609 | "name" 1610 | ], 1611 | "type": "tag" 1612 | }, 1613 | { 1614 | "params": [ 1615 | "null" 1616 | ], 1617 | "type": "fill" 1618 | } 1619 | ], 1620 | "measurement": "latency_write", 1621 | "orderByTime": "ASC", 1622 | "policy": "default", 1623 | "refId": "A", 1624 | "resultFormat": "time_series", 1625 | "select": [ 1626 | [ 1627 | { 1628 | "params": [ 1629 | "value" 1630 | ], 1631 | "type": "field" 1632 | }, 1633 | { 1634 | "params": [], 1635 | "type": "mean" 1636 | } 1637 | ] 1638 | ], 1639 | "tags": [ 1640 | { 1641 | "key": "type", 1642 | "operator": "=", 1643 | "value": "vsan_diskgroup" 1644 | }, 1645 | { 1646 | "condition": "AND", 1647 | "key": "host", 1648 | "operator": "=~", 1649 | "value": "/^$host$/" 1650 | }, 1651 | { 1652 | "condition": "AND", 1653 | "key": "name", 1654 | "operator": "=~", 1655 | "value": "/^$diskgroup$/" 1656 | } 1657 | ] 1658 | } 1659 | ], 1660 | "thresholds": [], 1661 | "timeFrom": null, 1662 | "timeShift": null, 1663 | "title": "Write Latency", 1664 | "tooltip": { 1665 | "shared": true, 1666 | "sort": 0, 1667 | "value_type": "individual" 1668 | }, 1669 | "type": "graph", 1670 | "xaxis": { 1671 | "buckets": null, 1672 | "mode": "time", 1673 | "name": null, 1674 | "show": true, 1675 | "values": [] 1676 | }, 1677 | "yaxes": [ 1678 | { 1679 | "format": "ms", 1680 | "label": null, 1681 | "logBase": 1, 1682 | "max": null, 1683 | "min": null, 1684 | "show": true 1685 | }, 1686 | { 1687 | "format": "short", 1688 | "label": null, 1689 | "logBase": 1, 1690 | "max": null, 1691 | "min": null, 1692 | "show": true 1693 | } 1694 | ] 1695 | }, 1696 | { 1697 | "aliasColors": {}, 1698 | "bars": false, 1699 | "dashLength": 10, 1700 | "dashes": false, 1701 | "datasource": "${DS_INFLUX}", 1702 | "fill": 1, 1703 | "gridPos": { 1704 | "h": 9, 1705 | "w": 12, 1706 | "x": 0, 1707 | "y": 33 1708 | }, 1709 | "id": 6, 1710 | "interval": "5m", 1711 | "legend": { 1712 | "avg": false, 1713 | "current": false, 1714 | "max": false, 1715 | "min": false, 1716 | "show": true, 1717 | "total": false, 1718 | "values": false 1719 | }, 1720 | "lines": true, 1721 | "linewidth": 1, 1722 | "links": [], 1723 | "nullPointMode": "null", 1724 | "percentage": false, 1725 | "pointradius": 5, 1726 | "points": false, 1727 | "renderer": "flot", 1728 | "seriesOverrides": [], 1729 | "spaceLength": 10, 1730 | "stack": false, 1731 | "steppedLine": false, 1732 | "targets": [ 1733 | { 1734 | "alias": "$tag_name", 1735 | "groupBy": [ 1736 | { 1737 | "params": [ 1738 | "$__interval" 1739 | ], 1740 | "type": "time" 1741 | }, 1742 | { 1743 | "params": [ 1744 | "name" 1745 | ], 1746 | "type": "tag" 1747 | }, 1748 | { 1749 | "params": [ 1750 | "null" 1751 | ], 1752 | "type": "fill" 1753 | } 1754 | ], 1755 | "measurement": "latency_readcache_read", 1756 | "orderByTime": "ASC", 1757 | "policy": "default", 1758 | "refId": "A", 1759 | "resultFormat": "time_series", 1760 | "select": [ 1761 | [ 1762 | { 1763 | "params": [ 1764 | "value" 1765 | ], 1766 | "type": "field" 1767 | }, 1768 | { 1769 | "params": [], 1770 | "type": "mean" 1771 | } 1772 | ] 1773 | ], 1774 | "tags": [ 1775 | { 1776 | "key": "type", 1777 | "operator": "=", 1778 | "value": "vsan_diskgroup" 1779 | }, 1780 | { 1781 | "condition": "AND", 1782 | "key": "host", 1783 | "operator": "=~", 1784 | "value": "/^$host$/" 1785 | }, 1786 | { 1787 | "condition": "AND", 1788 | "key": "name", 1789 | "operator": "=~", 1790 | "value": "/^$diskgroup$/" 1791 | } 1792 | ] 1793 | } 1794 | ], 1795 | "thresholds": [], 1796 | "timeFrom": null, 1797 | "timeShift": null, 1798 | "title": "Read Cache Read Latency", 1799 | "tooltip": { 1800 | "shared": true, 1801 | "sort": 0, 1802 | "value_type": "individual" 1803 | }, 1804 | "type": "graph", 1805 | "xaxis": { 1806 | "buckets": null, 1807 | "mode": "time", 1808 | "name": null, 1809 | "show": true, 1810 | "values": [] 1811 | }, 1812 | "yaxes": [ 1813 | { 1814 | "format": "ms", 1815 | "label": null, 1816 | "logBase": 1, 1817 | "max": null, 1818 | "min": null, 1819 | "show": true 1820 | }, 1821 | { 1822 | "format": "short", 1823 | "label": null, 1824 | "logBase": 1, 1825 | "max": null, 1826 | "min": null, 1827 | "show": true 1828 | } 1829 | ] 1830 | }, 1831 | { 1832 | "aliasColors": {}, 1833 | "bars": false, 1834 | "dashLength": 10, 1835 | "dashes": false, 1836 | "datasource": "${DS_INFLUX}", 1837 | "fill": 1, 1838 | "gridPos": { 1839 | "h": 9, 1840 | "w": 12, 1841 | "x": 12, 1842 | "y": 33 1843 | }, 1844 | "id": 7, 1845 | "interval": "5m", 1846 | "legend": { 1847 | "avg": false, 1848 | "current": false, 1849 | "max": false, 1850 | "min": false, 1851 | "show": true, 1852 | "total": false, 1853 | "values": false 1854 | }, 1855 | "lines": true, 1856 | "linewidth": 1, 1857 | "links": [], 1858 | "nullPointMode": "null", 1859 | "percentage": false, 1860 | "pointradius": 5, 1861 | "points": false, 1862 | "renderer": "flot", 1863 | "seriesOverrides": [], 1864 | "spaceLength": 10, 1865 | "stack": false, 1866 | "steppedLine": false, 1867 | "targets": [ 1868 | { 1869 | "alias": "$tag_name", 1870 | "groupBy": [ 1871 | { 1872 | "params": [ 1873 | "$__interval" 1874 | ], 1875 | "type": "time" 1876 | }, 1877 | { 1878 | "params": [ 1879 | "name" 1880 | ], 1881 | "type": "tag" 1882 | }, 1883 | { 1884 | "params": [ 1885 | "null" 1886 | ], 1887 | "type": "fill" 1888 | } 1889 | ], 1890 | "measurement": "latency_writebuffer", 1891 | "orderByTime": "ASC", 1892 | "policy": "default", 1893 | "refId": "A", 1894 | "resultFormat": "time_series", 1895 | "select": [ 1896 | [ 1897 | { 1898 | "params": [ 1899 | "value" 1900 | ], 1901 | "type": "field" 1902 | }, 1903 | { 1904 | "params": [], 1905 | "type": "mean" 1906 | } 1907 | ] 1908 | ], 1909 | "tags": [ 1910 | { 1911 | "key": "type", 1912 | "operator": "=", 1913 | "value": "vsan_diskgroup" 1914 | }, 1915 | { 1916 | "condition": "AND", 1917 | "key": "host", 1918 | "operator": "=~", 1919 | "value": "/^$host$/" 1920 | }, 1921 | { 1922 | "condition": "AND", 1923 | "key": "name", 1924 | "operator": "=~", 1925 | "value": "/^$diskgroup$/" 1926 | } 1927 | ] 1928 | } 1929 | ], 1930 | "thresholds": [], 1931 | "timeFrom": null, 1932 | "timeShift": null, 1933 | "title": "Writebuffer Latency", 1934 | "tooltip": { 1935 | "shared": true, 1936 | "sort": 0, 1937 | "value_type": "individual" 1938 | }, 1939 | "type": "graph", 1940 | "xaxis": { 1941 | "buckets": null, 1942 | "mode": "time", 1943 | "name": null, 1944 | "show": true, 1945 | "values": [] 1946 | }, 1947 | "yaxes": [ 1948 | { 1949 | "format": "ms", 1950 | "label": null, 1951 | "logBase": 1, 1952 | "max": null, 1953 | "min": null, 1954 | "show": true 1955 | }, 1956 | { 1957 | "format": "short", 1958 | "label": null, 1959 | "logBase": 1, 1960 | "max": null, 1961 | "min": null, 1962 | "show": true 1963 | } 1964 | ] 1965 | } 1966 | ], 1967 | "refresh": "1m", 1968 | "schemaVersion": 16, 1969 | "style": "dark", 1970 | "tags": [ 1971 | "storage", 1972 | "vsphere", 1973 | "vsan" 1974 | ], 1975 | "templating": { 1976 | "list": [ 1977 | { 1978 | "allValue": null, 1979 | "current": {}, 1980 | "datasource": "${DS_INFLUX}", 1981 | "hide": 0, 1982 | "includeAll": true, 1983 | "label": "VSAN", 1984 | "multi": true, 1985 | "name": "san", 1986 | "options": [], 1987 | "query": "SHOW TAG VALUES WITH KEY = \"san\" WHERE \"type\" = 'vsan'", 1988 | "refresh": 1, 1989 | "regex": "", 1990 | "sort": 0, 1991 | "tagValuesQuery": "", 1992 | "tags": [], 1993 | "tagsQuery": "", 1994 | "type": "query", 1995 | "useTags": false 1996 | }, 1997 | { 1998 | "allValue": null, 1999 | "current": {}, 2000 | "datasource": "${DS_INFLUX}", 2001 | "hide": 0, 2002 | "includeAll": true, 2003 | "label": "Diskgroup", 2004 | "multi": true, 2005 | "name": "diskgroup", 2006 | "options": [], 2007 | "query": "SHOW TAG VALUES WITH KEY = \"name\" WHERE \"type\" = 'vsan_diskgroup' and \"host\" =~ /$host/", 2008 | "refresh": 1, 2009 | "regex": "", 2010 | "sort": 0, 2011 | "tagValuesQuery": "", 2012 | "tags": [], 2013 | "tagsQuery": "", 2014 | "type": "query", 2015 | "useTags": false 2016 | }, 2017 | { 2018 | "allValue": null, 2019 | "current": {}, 2020 | "datasource": "${DS_INFLUX}", 2021 | "hide": 0, 2022 | "includeAll": true, 2023 | "label": "Host", 2024 | "multi": true, 2025 | "name": "host", 2026 | "options": [], 2027 | "query": "SHOW TAG VALUES WITH KEY = \"host\" WHERE \"type\" = 'vsan_diskgroup' and \"san\" =~ /$san/", 2028 | "refresh": 1, 2029 | "regex": "", 2030 | "sort": 0, 2031 | "tagValuesQuery": "", 2032 | "tags": [], 2033 | "tagsQuery": "", 2034 | "type": "query", 2035 | "useTags": false 2036 | } 2037 | ] 2038 | }, 2039 | "time": { 2040 | "from": "now-1h", 2041 | "to": "now-5m" 2042 | }, 2043 | "timepicker": { 2044 | "refresh_intervals": [ 2045 | "5s", 2046 | "10s", 2047 | "30s", 2048 | "1m", 2049 | "5m", 2050 | "15m", 2051 | "30m", 2052 | "1h", 2053 | "2h", 2054 | "1d" 2055 | ], 2056 | "time_options": [ 2057 | "5m", 2058 | "15m", 2059 | "1h", 2060 | "6h", 2061 | "12h", 2062 | "24h", 2063 | "2d", 2064 | "7d", 2065 | "30d" 2066 | ] 2067 | }, 2068 | "timezone": "", 2069 | "title": "VSAN Diskgroup", 2070 | "uid": "uR49dKmmk", 2071 | "version": 2 2072 | } -------------------------------------------------------------------------------- /dashboards/VSAN Frontend-1523009720460.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_INFLUX", 5 | "label": "influx", 6 | "description": "", 7 | "type": "datasource", 8 | "pluginId": "influxdb", 9 | "pluginName": "InfluxDB" 10 | } 11 | ], 12 | "__requires": [ 13 | { 14 | "type": "grafana", 15 | "id": "grafana", 16 | "name": "Grafana", 17 | "version": "5.0.2" 18 | }, 19 | { 20 | "type": "panel", 21 | "id": "graph", 22 | "name": "Graph", 23 | "version": "5.0.0" 24 | }, 25 | { 26 | "type": "datasource", 27 | "id": "influxdb", 28 | "name": "InfluxDB", 29 | "version": "5.0.0" 30 | }, 31 | { 32 | "type": "panel", 33 | "id": "singlestat", 34 | "name": "Singlestat", 35 | "version": "5.0.0" 36 | } 37 | ], 38 | "annotations": { 39 | "list": [ 40 | { 41 | "builtIn": 1, 42 | "datasource": "-- Grafana --", 43 | "enable": true, 44 | "hide": true, 45 | "iconColor": "rgba(0, 211, 255, 1)", 46 | "name": "Annotations & Alerts", 47 | "type": "dashboard" 48 | } 49 | ] 50 | }, 51 | "editable": true, 52 | "gnetId": null, 53 | "graphTooltip": 1, 54 | "id": null, 55 | "iteration": 1523009708752, 56 | "links": [ 57 | { 58 | "icon": "external link", 59 | "tags": [ 60 | "vsan" 61 | ], 62 | "type": "dashboards" 63 | } 64 | ], 65 | "panels": [ 66 | { 67 | "cacheTimeout": null, 68 | "colorBackground": false, 69 | "colorValue": false, 70 | "colors": [ 71 | "#299c46", 72 | "rgba(237, 129, 40, 0.89)", 73 | "#d44a3a" 74 | ], 75 | "datasource": "${DS_INFLUX}", 76 | "format": "KBs", 77 | "gauge": { 78 | "maxValue": 100, 79 | "minValue": 0, 80 | "show": false, 81 | "thresholdLabels": false, 82 | "thresholdMarkers": true 83 | }, 84 | "gridPos": { 85 | "h": 3, 86 | "w": 6, 87 | "x": 0, 88 | "y": 0 89 | }, 90 | "id": 14, 91 | "interval": null, 92 | "links": [], 93 | "mappingType": 1, 94 | "mappingTypes": [ 95 | { 96 | "name": "value to text", 97 | "value": 1 98 | }, 99 | { 100 | "name": "range to text", 101 | "value": 2 102 | } 103 | ], 104 | "maxDataPoints": 100, 105 | "nullPointMode": "connected", 106 | "nullText": null, 107 | "postfix": "", 108 | "postfixFontSize": "50%", 109 | "prefix": "", 110 | "prefixFontSize": "50%", 111 | "rangeMaps": [ 112 | { 113 | "from": "null", 114 | "text": "N/A", 115 | "to": "null" 116 | } 117 | ], 118 | "sparkline": { 119 | "fillColor": "rgba(31, 118, 189, 0.18)", 120 | "full": false, 121 | "lineColor": "rgb(31, 120, 193)", 122 | "show": true 123 | }, 124 | "tableColumn": "", 125 | "targets": [ 126 | { 127 | "dsType": "influxdb", 128 | "groupBy": [], 129 | "measurement": "kB_read", 130 | "orderByTime": "ASC", 131 | "policy": "default", 132 | "refId": "A", 133 | "resultFormat": "time_series", 134 | "select": [ 135 | [ 136 | { 137 | "params": [ 138 | "value" 139 | ], 140 | "type": "field" 141 | } 142 | ] 143 | ], 144 | "tags": [ 145 | { 146 | "key": "type", 147 | "operator": "=", 148 | "value": "vsan" 149 | }, 150 | { 151 | "condition": "AND", 152 | "key": "san", 153 | "operator": "=~", 154 | "value": "/^$VSAN$/" 155 | } 156 | ] 157 | } 158 | ], 159 | "thresholds": "", 160 | "title": "Read Throughput", 161 | "type": "singlestat", 162 | "valueFontSize": "80%", 163 | "valueMaps": [ 164 | { 165 | "op": "=", 166 | "text": "N/A", 167 | "value": "null" 168 | } 169 | ], 170 | "valueName": "current" 171 | }, 172 | { 173 | "cacheTimeout": null, 174 | "colorBackground": true, 175 | "colorValue": false, 176 | "colors": [ 177 | "#299c46", 178 | "rgba(237, 129, 40, 0.89)", 179 | "#d44a3a" 180 | ], 181 | "datasource": "${DS_INFLUX}", 182 | "format": "ms", 183 | "gauge": { 184 | "maxValue": 100, 185 | "minValue": 0, 186 | "show": false, 187 | "thresholdLabels": false, 188 | "thresholdMarkers": true 189 | }, 190 | "gridPos": { 191 | "h": 3, 192 | "w": 6, 193 | "x": 6, 194 | "y": 0 195 | }, 196 | "hideTimeOverride": true, 197 | "id": 10, 198 | "interval": null, 199 | "links": [], 200 | "mappingType": 1, 201 | "mappingTypes": [ 202 | { 203 | "name": "value to text", 204 | "value": 1 205 | }, 206 | { 207 | "name": "range to text", 208 | "value": 2 209 | } 210 | ], 211 | "maxDataPoints": 100, 212 | "nullPointMode": "connected", 213 | "nullText": null, 214 | "postfix": "", 215 | "postfixFontSize": "50%", 216 | "prefix": "", 217 | "prefixFontSize": "50%", 218 | "rangeMaps": [ 219 | { 220 | "from": "null", 221 | "text": "N/A", 222 | "to": "null" 223 | } 224 | ], 225 | "sparkline": { 226 | "fillColor": "rgba(31, 118, 189, 0.18)", 227 | "full": false, 228 | "lineColor": "rgb(31, 120, 193)", 229 | "show": false 230 | }, 231 | "tableColumn": "", 232 | "targets": [ 233 | { 234 | "dsType": "influxdb", 235 | "groupBy": [], 236 | "measurement": "latency_read", 237 | "orderByTime": "ASC", 238 | "policy": "default", 239 | "refId": "A", 240 | "resultFormat": "time_series", 241 | "select": [ 242 | [ 243 | { 244 | "params": [ 245 | "value" 246 | ], 247 | "type": "field" 248 | } 249 | ] 250 | ], 251 | "tags": [ 252 | { 253 | "key": "type", 254 | "operator": "=", 255 | "value": "vsan" 256 | }, 257 | { 258 | "condition": "AND", 259 | "key": "san", 260 | "operator": "=~", 261 | "value": "/^$VSAN$/" 262 | } 263 | ] 264 | } 265 | ], 266 | "thresholds": "10,20,30", 267 | "timeFrom": "5m", 268 | "timeShift": "5m", 269 | "title": "Read Latency", 270 | "type": "singlestat", 271 | "valueFontSize": "80%", 272 | "valueMaps": [ 273 | { 274 | "op": "=", 275 | "text": "N/A", 276 | "value": "null" 277 | } 278 | ], 279 | "valueName": "max" 280 | }, 281 | { 282 | "cacheTimeout": null, 283 | "colorBackground": false, 284 | "colorValue": false, 285 | "colors": [ 286 | "#299c46", 287 | "rgba(237, 129, 40, 0.89)", 288 | "#d44a3a" 289 | ], 290 | "datasource": "${DS_INFLUX}", 291 | "format": "KBs", 292 | "gauge": { 293 | "maxValue": 100, 294 | "minValue": 0, 295 | "show": false, 296 | "thresholdLabels": false, 297 | "thresholdMarkers": true 298 | }, 299 | "gridPos": { 300 | "h": 3, 301 | "w": 6, 302 | "x": 12, 303 | "y": 0 304 | }, 305 | "id": 15, 306 | "interval": null, 307 | "links": [], 308 | "mappingType": 1, 309 | "mappingTypes": [ 310 | { 311 | "name": "value to text", 312 | "value": 1 313 | }, 314 | { 315 | "name": "range to text", 316 | "value": 2 317 | } 318 | ], 319 | "maxDataPoints": 100, 320 | "nullPointMode": "connected", 321 | "nullText": null, 322 | "postfix": "", 323 | "postfixFontSize": "50%", 324 | "prefix": "", 325 | "prefixFontSize": "50%", 326 | "rangeMaps": [ 327 | { 328 | "from": "null", 329 | "text": "N/A", 330 | "to": "null" 331 | } 332 | ], 333 | "sparkline": { 334 | "fillColor": "rgba(31, 118, 189, 0.18)", 335 | "full": false, 336 | "lineColor": "rgb(31, 120, 193)", 337 | "show": true 338 | }, 339 | "tableColumn": "", 340 | "targets": [ 341 | { 342 | "dsType": "influxdb", 343 | "groupBy": [], 344 | "measurement": "kB_write", 345 | "orderByTime": "ASC", 346 | "policy": "default", 347 | "refId": "A", 348 | "resultFormat": "time_series", 349 | "select": [ 350 | [ 351 | { 352 | "params": [ 353 | "value" 354 | ], 355 | "type": "field" 356 | } 357 | ] 358 | ], 359 | "tags": [ 360 | { 361 | "key": "type", 362 | "operator": "=", 363 | "value": "vsan" 364 | }, 365 | { 366 | "condition": "AND", 367 | "key": "san", 368 | "operator": "=~", 369 | "value": "/^$VSAN$/" 370 | } 371 | ] 372 | } 373 | ], 374 | "thresholds": "", 375 | "title": "Write Throughput", 376 | "type": "singlestat", 377 | "valueFontSize": "80%", 378 | "valueMaps": [ 379 | { 380 | "op": "=", 381 | "text": "N/A", 382 | "value": "null" 383 | } 384 | ], 385 | "valueName": "current" 386 | }, 387 | { 388 | "cacheTimeout": null, 389 | "colorBackground": true, 390 | "colorValue": false, 391 | "colors": [ 392 | "#299c46", 393 | "rgba(237, 129, 40, 0.89)", 394 | "#d44a3a" 395 | ], 396 | "datasource": "${DS_INFLUX}", 397 | "format": "ms", 398 | "gauge": { 399 | "maxValue": 100, 400 | "minValue": 0, 401 | "show": false, 402 | "thresholdLabels": false, 403 | "thresholdMarkers": true 404 | }, 405 | "gridPos": { 406 | "h": 3, 407 | "w": 6, 408 | "x": 18, 409 | "y": 0 410 | }, 411 | "hideTimeOverride": true, 412 | "id": 11, 413 | "interval": null, 414 | "links": [], 415 | "mappingType": 1, 416 | "mappingTypes": [ 417 | { 418 | "name": "value to text", 419 | "value": 1 420 | }, 421 | { 422 | "name": "range to text", 423 | "value": 2 424 | } 425 | ], 426 | "maxDataPoints": 100, 427 | "nullPointMode": "connected", 428 | "nullText": null, 429 | "postfix": "", 430 | "postfixFontSize": "50%", 431 | "prefix": "", 432 | "prefixFontSize": "50%", 433 | "rangeMaps": [ 434 | { 435 | "from": "null", 436 | "text": "N/A", 437 | "to": "null" 438 | } 439 | ], 440 | "sparkline": { 441 | "fillColor": "rgba(31, 118, 189, 0.18)", 442 | "full": false, 443 | "lineColor": "rgb(31, 120, 193)", 444 | "show": false 445 | }, 446 | "tableColumn": "", 447 | "targets": [ 448 | { 449 | "dsType": "influxdb", 450 | "groupBy": [], 451 | "measurement": "latency_write", 452 | "orderByTime": "ASC", 453 | "policy": "default", 454 | "refId": "A", 455 | "resultFormat": "time_series", 456 | "select": [ 457 | [ 458 | { 459 | "params": [ 460 | "value" 461 | ], 462 | "type": "field" 463 | } 464 | ] 465 | ], 466 | "tags": [ 467 | { 468 | "key": "type", 469 | "operator": "=", 470 | "value": "vsan" 471 | }, 472 | { 473 | "condition": "AND", 474 | "key": "san", 475 | "operator": "=~", 476 | "value": "/^$VSAN$/" 477 | } 478 | ] 479 | } 480 | ], 481 | "thresholds": "10,20,30", 482 | "timeFrom": "5m", 483 | "timeShift": "5m", 484 | "title": "Write Latency", 485 | "type": "singlestat", 486 | "valueFontSize": "80%", 487 | "valueMaps": [ 488 | { 489 | "op": "=", 490 | "text": "N/A", 491 | "value": "null" 492 | } 493 | ], 494 | "valueName": "max" 495 | }, 496 | { 497 | "aliasColors": {}, 498 | "bars": false, 499 | "dashLength": 10, 500 | "dashes": false, 501 | "datasource": "${DS_INFLUX}", 502 | "fill": 1, 503 | "gridPos": { 504 | "h": 6, 505 | "w": 12, 506 | "x": 0, 507 | "y": 3 508 | }, 509 | "id": 1, 510 | "interval": "300s", 511 | "legend": { 512 | "avg": false, 513 | "current": false, 514 | "max": false, 515 | "min": false, 516 | "show": true, 517 | "total": false, 518 | "values": false 519 | }, 520 | "lines": true, 521 | "linewidth": 1, 522 | "links": [], 523 | "nullPointMode": "null", 524 | "percentage": false, 525 | "pointradius": 5, 526 | "points": false, 527 | "renderer": "flot", 528 | "seriesOverrides": [], 529 | "spaceLength": 10, 530 | "stack": false, 531 | "steppedLine": false, 532 | "targets": [ 533 | { 534 | "alias": "$tag_san", 535 | "dsType": "influxdb", 536 | "groupBy": [ 537 | { 538 | "params": [ 539 | "$__interval" 540 | ], 541 | "type": "time" 542 | }, 543 | { 544 | "params": [ 545 | "san" 546 | ], 547 | "type": "tag" 548 | }, 549 | { 550 | "params": [ 551 | "null" 552 | ], 553 | "type": "fill" 554 | } 555 | ], 556 | "measurement": "kB_read", 557 | "orderByTime": "ASC", 558 | "policy": "default", 559 | "refId": "A", 560 | "resultFormat": "time_series", 561 | "select": [ 562 | [ 563 | { 564 | "params": [ 565 | "value" 566 | ], 567 | "type": "field" 568 | }, 569 | { 570 | "params": [], 571 | "type": "mean" 572 | } 573 | ] 574 | ], 575 | "tags": [ 576 | { 577 | "key": "type", 578 | "operator": "=", 579 | "value": "vsan" 580 | }, 581 | { 582 | "condition": "AND", 583 | "key": "san", 584 | "operator": "=~", 585 | "value": "/^$VSAN$/" 586 | } 587 | ] 588 | } 589 | ], 590 | "thresholds": [], 591 | "timeFrom": null, 592 | "timeShift": null, 593 | "title": "Read Throughput", 594 | "tooltip": { 595 | "shared": true, 596 | "sort": 0, 597 | "value_type": "individual" 598 | }, 599 | "type": "graph", 600 | "xaxis": { 601 | "buckets": null, 602 | "mode": "time", 603 | "name": null, 604 | "show": true, 605 | "values": [] 606 | }, 607 | "yaxes": [ 608 | { 609 | "format": "KBs", 610 | "label": null, 611 | "logBase": 1, 612 | "max": null, 613 | "min": null, 614 | "show": true 615 | }, 616 | { 617 | "format": "short", 618 | "label": null, 619 | "logBase": 1, 620 | "max": null, 621 | "min": null, 622 | "show": true 623 | } 624 | ] 625 | }, 626 | { 627 | "aliasColors": {}, 628 | "bars": false, 629 | "dashLength": 10, 630 | "dashes": false, 631 | "datasource": "${DS_INFLUX}", 632 | "fill": 1, 633 | "gridPos": { 634 | "h": 6, 635 | "w": 12, 636 | "x": 12, 637 | "y": 3 638 | }, 639 | "id": 2, 640 | "interval": "300s", 641 | "legend": { 642 | "avg": false, 643 | "current": false, 644 | "max": false, 645 | "min": false, 646 | "show": true, 647 | "total": false, 648 | "values": false 649 | }, 650 | "lines": true, 651 | "linewidth": 1, 652 | "links": [], 653 | "nullPointMode": "null", 654 | "percentage": false, 655 | "pointradius": 5, 656 | "points": false, 657 | "renderer": "flot", 658 | "seriesOverrides": [], 659 | "spaceLength": 10, 660 | "stack": false, 661 | "steppedLine": false, 662 | "targets": [ 663 | { 664 | "alias": "$tag_san", 665 | "dsType": "influxdb", 666 | "groupBy": [ 667 | { 668 | "params": [ 669 | "$__interval" 670 | ], 671 | "type": "time" 672 | }, 673 | { 674 | "params": [ 675 | "san" 676 | ], 677 | "type": "tag" 678 | }, 679 | { 680 | "params": [ 681 | "null" 682 | ], 683 | "type": "fill" 684 | } 685 | ], 686 | "measurement": "kB_write", 687 | "orderByTime": "ASC", 688 | "policy": "default", 689 | "refId": "A", 690 | "resultFormat": "time_series", 691 | "select": [ 692 | [ 693 | { 694 | "params": [ 695 | "value" 696 | ], 697 | "type": "field" 698 | }, 699 | { 700 | "params": [], 701 | "type": "mean" 702 | } 703 | ] 704 | ], 705 | "tags": [ 706 | { 707 | "key": "type", 708 | "operator": "=", 709 | "value": "vsan" 710 | }, 711 | { 712 | "condition": "AND", 713 | "key": "san", 714 | "operator": "=~", 715 | "value": "/^$VSAN$/" 716 | } 717 | ] 718 | } 719 | ], 720 | "thresholds": [], 721 | "timeFrom": null, 722 | "timeShift": null, 723 | "title": "Write Throughput", 724 | "tooltip": { 725 | "shared": true, 726 | "sort": 0, 727 | "value_type": "individual" 728 | }, 729 | "type": "graph", 730 | "xaxis": { 731 | "buckets": null, 732 | "mode": "time", 733 | "name": null, 734 | "show": true, 735 | "values": [] 736 | }, 737 | "yaxes": [ 738 | { 739 | "format": "KBs", 740 | "label": null, 741 | "logBase": 1, 742 | "max": null, 743 | "min": null, 744 | "show": true 745 | }, 746 | { 747 | "format": "short", 748 | "label": null, 749 | "logBase": 1, 750 | "max": null, 751 | "min": null, 752 | "show": true 753 | } 754 | ] 755 | }, 756 | { 757 | "aliasColors": {}, 758 | "bars": false, 759 | "dashLength": 10, 760 | "dashes": false, 761 | "datasource": "${DS_INFLUX}", 762 | "fill": 1, 763 | "gridPos": { 764 | "h": 6, 765 | "w": 12, 766 | "x": 0, 767 | "y": 9 768 | }, 769 | "id": 3, 770 | "interval": "300s", 771 | "legend": { 772 | "avg": false, 773 | "current": false, 774 | "max": false, 775 | "min": false, 776 | "show": true, 777 | "total": false, 778 | "values": false 779 | }, 780 | "lines": true, 781 | "linewidth": 1, 782 | "links": [], 783 | "nullPointMode": "null", 784 | "percentage": false, 785 | "pointradius": 5, 786 | "points": false, 787 | "renderer": "flot", 788 | "seriesOverrides": [], 789 | "spaceLength": 10, 790 | "stack": false, 791 | "steppedLine": false, 792 | "targets": [ 793 | { 794 | "alias": "$tag_san", 795 | "dsType": "influxdb", 796 | "groupBy": [ 797 | { 798 | "params": [ 799 | "san" 800 | ], 801 | "type": "tag" 802 | } 803 | ], 804 | "measurement": "latency_read", 805 | "orderByTime": "ASC", 806 | "policy": "default", 807 | "refId": "A", 808 | "resultFormat": "time_series", 809 | "select": [ 810 | [ 811 | { 812 | "params": [ 813 | "value" 814 | ], 815 | "type": "field" 816 | } 817 | ] 818 | ], 819 | "tags": [ 820 | { 821 | "key": "type", 822 | "operator": "=", 823 | "value": "vsan" 824 | }, 825 | { 826 | "condition": "AND", 827 | "key": "san", 828 | "operator": "=~", 829 | "value": "/^$VSAN$/" 830 | } 831 | ] 832 | } 833 | ], 834 | "thresholds": [], 835 | "timeFrom": null, 836 | "timeShift": null, 837 | "title": "Read Latency", 838 | "tooltip": { 839 | "shared": true, 840 | "sort": 0, 841 | "value_type": "individual" 842 | }, 843 | "type": "graph", 844 | "xaxis": { 845 | "buckets": null, 846 | "mode": "time", 847 | "name": null, 848 | "show": true, 849 | "values": [] 850 | }, 851 | "yaxes": [ 852 | { 853 | "format": "ms", 854 | "label": null, 855 | "logBase": 1, 856 | "max": null, 857 | "min": null, 858 | "show": true 859 | }, 860 | { 861 | "format": "short", 862 | "label": null, 863 | "logBase": 1, 864 | "max": null, 865 | "min": null, 866 | "show": true 867 | } 868 | ] 869 | }, 870 | { 871 | "aliasColors": {}, 872 | "bars": false, 873 | "dashLength": 10, 874 | "dashes": false, 875 | "datasource": "${DS_INFLUX}", 876 | "fill": 1, 877 | "gridPos": { 878 | "h": 6, 879 | "w": 12, 880 | "x": 12, 881 | "y": 9 882 | }, 883 | "id": 4, 884 | "interval": "300s", 885 | "legend": { 886 | "avg": false, 887 | "current": false, 888 | "max": false, 889 | "min": false, 890 | "show": true, 891 | "total": false, 892 | "values": false 893 | }, 894 | "lines": true, 895 | "linewidth": 1, 896 | "links": [], 897 | "nullPointMode": "null", 898 | "percentage": false, 899 | "pointradius": 5, 900 | "points": false, 901 | "renderer": "flot", 902 | "seriesOverrides": [], 903 | "spaceLength": 10, 904 | "stack": false, 905 | "steppedLine": false, 906 | "targets": [ 907 | { 908 | "alias": "$tag_san", 909 | "dsType": "influxdb", 910 | "groupBy": [ 911 | { 912 | "params": [ 913 | "san" 914 | ], 915 | "type": "tag" 916 | } 917 | ], 918 | "measurement": "latency_write", 919 | "orderByTime": "ASC", 920 | "policy": "default", 921 | "refId": "A", 922 | "resultFormat": "time_series", 923 | "select": [ 924 | [ 925 | { 926 | "params": [ 927 | "value" 928 | ], 929 | "type": "field" 930 | } 931 | ] 932 | ], 933 | "tags": [ 934 | { 935 | "key": "type", 936 | "operator": "=", 937 | "value": "vsan" 938 | }, 939 | { 940 | "condition": "AND", 941 | "key": "san", 942 | "operator": "=~", 943 | "value": "/^$VSAN$/" 944 | } 945 | ] 946 | } 947 | ], 948 | "thresholds": [], 949 | "timeFrom": null, 950 | "timeShift": null, 951 | "title": "Write Latency", 952 | "tooltip": { 953 | "shared": true, 954 | "sort": 0, 955 | "value_type": "individual" 956 | }, 957 | "type": "graph", 958 | "xaxis": { 959 | "buckets": null, 960 | "mode": "time", 961 | "name": null, 962 | "show": true, 963 | "values": [] 964 | }, 965 | "yaxes": [ 966 | { 967 | "format": "ms", 968 | "label": null, 969 | "logBase": 1, 970 | "max": null, 971 | "min": null, 972 | "show": true 973 | }, 974 | { 975 | "format": "short", 976 | "label": null, 977 | "logBase": 1, 978 | "max": null, 979 | "min": null, 980 | "show": true 981 | } 982 | ] 983 | }, 984 | { 985 | "aliasColors": {}, 986 | "bars": false, 987 | "dashLength": 10, 988 | "dashes": false, 989 | "datasource": "${DS_INFLUX}", 990 | "fill": 1, 991 | "gridPos": { 992 | "h": 6, 993 | "w": 12, 994 | "x": 0, 995 | "y": 15 996 | }, 997 | "id": 5, 998 | "legend": { 999 | "avg": false, 1000 | "current": false, 1001 | "max": false, 1002 | "min": false, 1003 | "show": true, 1004 | "total": false, 1005 | "values": false 1006 | }, 1007 | "lines": true, 1008 | "linewidth": 1, 1009 | "links": [], 1010 | "nullPointMode": "null", 1011 | "percentage": false, 1012 | "pointradius": 5, 1013 | "points": false, 1014 | "renderer": "flot", 1015 | "seriesOverrides": [], 1016 | "spaceLength": 10, 1017 | "stack": false, 1018 | "steppedLine": false, 1019 | "targets": [ 1020 | { 1021 | "alias": "$tag_san", 1022 | "dsType": "influxdb", 1023 | "groupBy": [ 1024 | { 1025 | "params": [ 1026 | "san" 1027 | ], 1028 | "type": "tag" 1029 | } 1030 | ], 1031 | "measurement": "congestion", 1032 | "orderByTime": "ASC", 1033 | "policy": "default", 1034 | "refId": "A", 1035 | "resultFormat": "time_series", 1036 | "select": [ 1037 | [ 1038 | { 1039 | "params": [ 1040 | "value" 1041 | ], 1042 | "type": "field" 1043 | } 1044 | ] 1045 | ], 1046 | "tags": [ 1047 | { 1048 | "key": "type", 1049 | "operator": "=", 1050 | "value": "vsan" 1051 | }, 1052 | { 1053 | "condition": "AND", 1054 | "key": "san", 1055 | "operator": "=~", 1056 | "value": "/^$VSAN$/" 1057 | } 1058 | ] 1059 | } 1060 | ], 1061 | "thresholds": [], 1062 | "timeFrom": null, 1063 | "timeShift": null, 1064 | "title": "Congestion", 1065 | "tooltip": { 1066 | "shared": true, 1067 | "sort": 0, 1068 | "value_type": "individual" 1069 | }, 1070 | "type": "graph", 1071 | "xaxis": { 1072 | "buckets": null, 1073 | "mode": "time", 1074 | "name": null, 1075 | "show": true, 1076 | "values": [] 1077 | }, 1078 | "yaxes": [ 1079 | { 1080 | "format": "short", 1081 | "label": null, 1082 | "logBase": 1, 1083 | "max": null, 1084 | "min": null, 1085 | "show": true 1086 | }, 1087 | { 1088 | "format": "short", 1089 | "label": null, 1090 | "logBase": 1, 1091 | "max": null, 1092 | "min": null, 1093 | "show": true 1094 | } 1095 | ] 1096 | }, 1097 | { 1098 | "aliasColors": {}, 1099 | "bars": false, 1100 | "dashLength": 10, 1101 | "dashes": false, 1102 | "datasource": "${DS_INFLUX}", 1103 | "fill": 1, 1104 | "gridPos": { 1105 | "h": 6, 1106 | "w": 12, 1107 | "x": 12, 1108 | "y": 15 1109 | }, 1110 | "id": 6, 1111 | "legend": { 1112 | "avg": false, 1113 | "current": false, 1114 | "max": false, 1115 | "min": false, 1116 | "show": true, 1117 | "total": false, 1118 | "values": false 1119 | }, 1120 | "lines": true, 1121 | "linewidth": 1, 1122 | "links": [], 1123 | "nullPointMode": "null", 1124 | "percentage": false, 1125 | "pointradius": 5, 1126 | "points": false, 1127 | "renderer": "flot", 1128 | "seriesOverrides": [], 1129 | "spaceLength": 10, 1130 | "stack": false, 1131 | "steppedLine": false, 1132 | "targets": [ 1133 | { 1134 | "alias": "$tag_san", 1135 | "dsType": "influxdb", 1136 | "groupBy": [ 1137 | { 1138 | "params": [ 1139 | "san" 1140 | ], 1141 | "type": "tag" 1142 | } 1143 | ], 1144 | "measurement": "io_outstanding", 1145 | "orderByTime": "ASC", 1146 | "policy": "default", 1147 | "refId": "A", 1148 | "resultFormat": "time_series", 1149 | "select": [ 1150 | [ 1151 | { 1152 | "params": [ 1153 | "value" 1154 | ], 1155 | "type": "field" 1156 | } 1157 | ] 1158 | ], 1159 | "tags": [ 1160 | { 1161 | "key": "type", 1162 | "operator": "=", 1163 | "value": "vsan" 1164 | }, 1165 | { 1166 | "condition": "AND", 1167 | "key": "san", 1168 | "operator": "=~", 1169 | "value": "/^$VSAN$/" 1170 | } 1171 | ] 1172 | } 1173 | ], 1174 | "thresholds": [], 1175 | "timeFrom": null, 1176 | "timeShift": null, 1177 | "title": "Outstanding IO", 1178 | "tooltip": { 1179 | "shared": true, 1180 | "sort": 0, 1181 | "value_type": "individual" 1182 | }, 1183 | "type": "graph", 1184 | "xaxis": { 1185 | "buckets": null, 1186 | "mode": "time", 1187 | "name": null, 1188 | "show": true, 1189 | "values": [] 1190 | }, 1191 | "yaxes": [ 1192 | { 1193 | "format": "short", 1194 | "label": null, 1195 | "logBase": 1, 1196 | "max": null, 1197 | "min": null, 1198 | "show": true 1199 | }, 1200 | { 1201 | "format": "short", 1202 | "label": null, 1203 | "logBase": 1, 1204 | "max": null, 1205 | "min": null, 1206 | "show": true 1207 | } 1208 | ] 1209 | } 1210 | ], 1211 | "refresh": "5m", 1212 | "schemaVersion": 16, 1213 | "style": "dark", 1214 | "tags": [ 1215 | "vsan", 1216 | "vsphere", 1217 | "storage" 1218 | ], 1219 | "templating": { 1220 | "list": [ 1221 | { 1222 | "allValue": null, 1223 | "current": {}, 1224 | "datasource": "${DS_INFLUX}", 1225 | "hide": 0, 1226 | "includeAll": true, 1227 | "label": null, 1228 | "multi": true, 1229 | "name": "VSAN", 1230 | "options": [], 1231 | "query": "SHOW TAG VALUES WITH KEY = \"san\" WHERE \"type\" = 'vsan'", 1232 | "refresh": 1, 1233 | "regex": "", 1234 | "sort": 0, 1235 | "tagValuesQuery": "", 1236 | "tags": [], 1237 | "tagsQuery": "", 1238 | "type": "query", 1239 | "useTags": false 1240 | } 1241 | ] 1242 | }, 1243 | "time": { 1244 | "from": "now-24h", 1245 | "to": "now" 1246 | }, 1247 | "timepicker": { 1248 | "refresh_intervals": [ 1249 | "5s", 1250 | "10s", 1251 | "30s", 1252 | "1m", 1253 | "5m", 1254 | "15m", 1255 | "30m", 1256 | "1h", 1257 | "2h", 1258 | "1d" 1259 | ], 1260 | "time_options": [ 1261 | "5m", 1262 | "15m", 1263 | "1h", 1264 | "6h", 1265 | "12h", 1266 | "24h", 1267 | "2d", 1268 | "7d", 1269 | "30d" 1270 | ] 1271 | }, 1272 | "timezone": "", 1273 | "title": "VSAN Frontend", 1274 | "uid": "KNESwsgmz", 1275 | "version": 2 1276 | } -------------------------------------------------------------------------------- /host_performance_poller.ps1: -------------------------------------------------------------------------------- 1 | #requires -module VMware.PowerCLI 2 | <# 3 | .SYNOPSIS 4 | Script for pulling performance metrics from vCenter and writing to an Influx database 5 | .DESCRIPTION 6 | The script will pull performance metrics for VMHosts from vCenter and writes the data to an Influx 7 | timeseries database. 8 | .NOTES 9 | Author: Rudi Martinsen / Intility AS 10 | Created: 30/06-2017 11 | Version 0.5.4 12 | Revised: 28/02-2018 13 | Changelog: 14 | 0.5.4 -- Added vmhba for new DL servers 15 | 0.5.3 -- Added metrics (adapter & network totals) 16 | 0.5.2 -- Added VDI metrics, comes in place if the cluster has VDI in its name 17 | 0.5.1 -- Added metrics (mem usage, co stop) 18 | 0.5.0 -- Added connection state 19 | 0.4.0 -- Added error handling on vCenter connection, cleaned some comments and variables 20 | 0.3.0 -- Added storageadapter and CPU Ready to metrics 21 | 0.2.0 -- Changed to entitycount for pollingstat 22 | .LINK 23 | http://www.rudimartinsen.com/2017/07/17/vsphere-performance-data-part-5-the-script/ 24 | .PARAMETER Samples 25 | Script parameter for how many samples to fetch. Default of 15 will give last 5 minutes (15*20sec) 26 | .PARAMETER VCenter 27 | The vCenter to connect to 28 | .PARAMETER Cluster 29 | The Cluster to get Hosts from. If omitted all Hosts in the vCenter will be fetched 30 | .PARAMETER HostCount 31 | Optional number of Hosts to get metrics from 32 | .PARAMETER Skip 33 | Optional number of Hosts to skip. Use with HostCount 34 | .PARAMETER Targetname 35 | Optional name of the target for use as a Tag in the Influx record 36 | .PARAMETER DBServer 37 | IP Address or hostname of the Influx Database server 38 | .PARAMETER DBServerPort 39 | TCP port for the DB server, Defaults to 8086 which is the default Influx port 40 | .PARAMETER LogFile 41 | Path to the logfile to write to 42 | #> 43 | param( 44 | $VCenter, 45 | $Cluster, 46 | $Samples = 15, 47 | $Hostcount = 0, 48 | $Skip = 0, 49 | $Targetname, 50 | $Dbserver, 51 | $DbserverPort = 8086, 52 | $LogFile 53 | ) 54 | #Function to get the correct timestamp format for Influx 55 | function Get-DBTimestamp($timestamp = (get-date)){ 56 | if($timestamp -is [system.string]){ 57 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 58 | } 59 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 60 | } 61 | 62 | if(!$LogFile){ 63 | $scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 64 | $LogFile = "$scriptDir\log\vcpoll_host.log" 65 | } 66 | $start = Get-Date 67 | 68 | #Import PowerCLI 69 | Import-Module VMware.VimAutomation.Core 70 | 71 | #statinterval is based on the realtime performance metrics gathered from vCenter which is 20 seconds 72 | $statInterval = 20 73 | 74 | #Variable to calculate correct CpuRdy value 75 | $cpuRdyInt = 200 76 | 77 | #Set targetname if omitted as a script parameter 78 | if($targetname -eq $null -or $targetname -eq ""){ 79 | if($cluster){ 80 | $targetname = $cluster 81 | } 82 | else{ 83 | $targetname = $vcenter 84 | } 85 | } 86 | 87 | #Connect to vCenter 88 | try { 89 | $vc_conn = Connect-VIServer $vcenter -ErrorAction Stop -ErrorVariable vcerr 90 | $vcid = $vc_conn.InstanceUuid 91 | } 92 | catch { 93 | Write-Output "$(Get-Date) : Couldn't connect to vCenter $vCenter. Script was started at $start" | Out-File $LogFile -Append 94 | Write-Output "$(Get-Date) : Error message was: $($vcerr.message)" | Out-File $LogFile -Append 95 | break 96 | } 97 | #Get Hosts 98 | if($cluster){ 99 | $vmhosts = Get-Cluster $cluster -Server $vcenter | Get-VMHost | Where-Object {$_.ConnectionState -ne "NotResponding"} 100 | } 101 | else{ 102 | $vmhosts = Get-VMHost -Server $vcenter | Where-Object {$_.ConnectionState -ne "NotResponding"} 103 | } 104 | 105 | ####Filter based on vmcount/skip parameters. Could probably be done in the query above? 106 | if($hostcount -gt 0){ 107 | $vmhosts = $vmhosts | Sort-Object name | Select-Object -First $hostcount -Skip $skip 108 | } 109 | 110 | #Table to store data 111 | $tbl = @() 112 | 113 | #The different metrics to fetch 114 | $metricsEsxi = "cpu.totalcapacity.average","cpu.usagemhz.average","cpu.ready.summation","cpu.costop.summation","cpu.latency.average","cpu.usage.average","cpu.utilization.average","mem.totalcapacity.average","mem.consumed.average","net.received.average","net.transmitted.average","storageadapter.read.average","storageadapter.write.average","mem.usage.average","net.usage.average","storageAdapter.commandsAveraged.average" 115 | $metricsVdi = $metricsesxi + "gpu.mem.usage.average","gpu.mem.used.average","gpu.temperature.average","gpu.utilization.average" 116 | 117 | foreach($vmhost in $vmhosts){ 118 | $lapStart = get-date 119 | 120 | #Build variables for host metadata 121 | $hid = $vmhost.Id 122 | $hname = $vmhost.Name 123 | $cid = $vmhost.ParentId 124 | $cname = $vmhost.Parent.Name 125 | $vendor = $vmhost.ExtensionData.Hardware.SystemInfo.Vendor 126 | $state = $vmhost.ConnectionState 127 | 128 | if($cname -like "*VDI*"){ 129 | $vdi = $true 130 | $metrics = $metricsvdi 131 | } 132 | else{ 133 | $vdi = $false 134 | $metrics = $metricsEsxi 135 | } 136 | 137 | #Get the stats 138 | $stats = Get-Stat -Entity $vmhost -Realtime -MaxSamples $samples -Stat $metrics 139 | 140 | foreach($stat in $stats){ 141 | $instance = $stat.Instance 142 | 143 | #Metrics will often have values for several instances per entity. Normally they will also have an aggregated instance. We're only interested in that one for now if not VDI metric 144 | if($instance -or $instance -ne "" -and $vdi -eq $false){ 145 | continue 146 | } 147 | 148 | $unit = $stat.Unit 149 | $value = $stat.Value 150 | $statTimestamp = Get-DBTimestamp $stat.Timestamp 151 | 152 | if($unit -eq "%"){ 153 | $unit="perc" 154 | } 155 | 156 | switch ($stat.MetricId) { 157 | "cpu.ready.summation" { $measurement = "cpu_ready"; $value = ($_.value / $cpuRdyInt); $unit = "perc" } 158 | "cpu.costop.summation" { $measurement = "cpu_costop"; $value = ($_.value / $cpuRdyInt); $unit = "perc" } 159 | "cpu.totalcapacity.average" { $measurement = "cpu_totalcapacity" } 160 | "cpu.utilization.average" {$measurement = "cpu_util" } 161 | "cpu.usagemhz.average" {$measurement = "cpu_usagemhz" } 162 | "cpu.usage.average" {$measurement = "cpu_usage" } 163 | "cpu.latency.average" {$measurement = "cpu_latency" } 164 | "mem.totalcapacity.average" {$measurement = "mem_totalcapacity"} 165 | "mem.consumed.average" {$measurement = "mem_consumed"} 166 | "mem.usage.average" {$measurement = "mem_usage"} 167 | "net.received.average" {$measurement = "net_through_receive"} 168 | "net.transmitted.average" {$measurement = "net_through_transmit"} 169 | "net.usage.average" {$measurement = "net_through_total"} 170 | "gpu.mem.used.average" {$measurement = "gpu_mem_usedkb";$vdiM=$true} 171 | "gpu.mem.usage.average" {$measurement = "gpu_mem_usage";$vdiM=$true} 172 | "gpu.utilization.average" {$measurement = "gpu_utilization";$vdiM=$true} 173 | "gpu.temperature.average" {$measurement = "gpu_temperature";$vdiM=$true} 174 | #"storageadapter.read.average" {$measurement = "stor_through_read"} 175 | #"storageadapter.write.average" {$measurement = "stor_through_write"} 176 | Default { $measurement = $null } 177 | } 178 | 179 | if($measurement -ne $null){ 180 | if($vdiM){ 181 | #Write-Output "VDI! $measurement" 182 | $tbl += "$measurement,type=host,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,location=$location,unit=$unit,statinterval=$statinterval,state=$state,instance=$instance value=$Value $stattimestamp" 183 | } 184 | else{ 185 | $tbl += "$measurement,type=host,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,location=$location,unit=$unit,statinterval=$statinterval,state=$state value=$Value $stattimestamp" 186 | } 187 | } 188 | 189 | } 190 | 191 | #Our environment consists mainly of HPE hosts which have the same adapters. The other hardware have different adapter configs and will be decommissioned soon so we don't care about them 192 | if($vendor -eq "HP" -or "HPE"){ 193 | $stats | Where-Object {$_.metricid -eq "storageadapter.read.average" -and (($_.instance -eq "vmhba0" -or $_.instance -eq "vmhba1") -or ($_.instance -eq "vmhba33" -or $_.instance -eq "vmhba34"))} | Group-Object timestamp | ForEach-Object {$tbl += "stor_through_read,type=host,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,location=$location,unit=KBps,statinterval=$statinterval value=$([int](($_.group[0].value + $_.group[1].value)) ) $(Get-DBTimestamp $_.name)"} 194 | $stats | Where-Object {$_.metricid -eq "storageadapter.write.average" -and (($_.instance -eq "vmhba0" -or $_.instance -eq "vmhba1") -or ($_.instance -eq "vmhba33" -or $_.instance -eq "vmhba34"))} | Group-Object timestamp | ForEach-Object {$tbl += "stor_through_write,type=host,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,location=$location,unit=KBps,statinterval=$statinterval value=$([int](($_.group[0].value + $_.group[1].value)) ) $(Get-DBTimestamp $_.name)"} 195 | $stats | Where-Object {$_.metricid -eq "storageAdapter.commandsAveraged.average" -and (($_.instance -eq "vmhba0" -or $_.instance -eq "vmhba1") -or ($_.instance -eq "vmhba33" -or $_.instance -eq "vmhba34"))} | Group-Object timestamp | ForEach-Object {$tbl += "stor_through_write,type=host,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,location=$location,unit=KBps,statinterval=$statinterval value=$([int](($_.group[0].value + $_.group[1].value)) ) $(Get-DBTimestamp $_.name)"} 196 | } 197 | 198 | #Calculate lap time 199 | $lapStop = get-date 200 | $timespan = New-TimeSpan -Start $lapStart -End $lapStop 201 | Write-Output $timespan.TotalSeconds 202 | 203 | } 204 | 205 | #Disconnect from vCenter 206 | Disconnect-VIServer $vcenter -Confirm:$false 207 | 208 | #Calculate runtime 209 | $stop = get-date 210 | $runTimespan = New-TimeSpan -Start $start -End $stop 211 | 212 | Write-Output "Run $run took $($runTimespan.TotalSeconds) seconds" 213 | 214 | #Build URI for the API call 215 | $baseUri = "http://" + $dbserver + ":" + $dbserverPort + "/" 216 | $dbname = "performance" 217 | $postUri = $baseUri + "write?db=" + $dbname 218 | 219 | ####Perform a test againts the API? 220 | 221 | #Write data to the API 222 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($newtbl -join "`n") 223 | 224 | #Build qry to write stats about the run 225 | $pollStatQry = "pollingstat,poller=$($env:COMPUTERNAME),unit=s,type=vmhostpoll,target=$($targetname) runtime=$($runtimespan.TotalSeconds),entitycount=$($vmhosts.Count) $(Get-DBTimestamp -timestamp $start)" 226 | 227 | #Write data about the run 228 | Invoke-RestMethod -Method Post -Uri $postUri -Body $pollStatQry 229 | -------------------------------------------------------------------------------- /vcsa/appliance_backup.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 6.0 2 | <# 3 | .SYNOPSIS 4 | Script for outputting VCSA info to Influx 5 | .DESCRIPTION 6 | This script will fetch update information from 7 | the VCSA REST API and post this data to a InfluxDB database 8 | 9 | This script is tested against vCenter 6.7U3, please note that 10 | there might be differences in other versions 11 | .NOTES 12 | Author: Rudi Martinsen 13 | Created: 07/11-2019 14 | Version: 2.1.0 15 | Revised: 05/04-2020 16 | Changelog: 17 | 2.1.0 -- Added multiple vCenter support 18 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 19 | .LINK 20 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 21 | #> 22 | #Function for generating correct timestamp for influx input 23 | function Get-DBTimestamp($timestamp = (get-date)){ 24 | if($timestamp -is [system.string]){ 25 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 26 | } 27 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 28 | } 29 | 30 | ######################## 31 | ## Environment params ## 32 | ######################## 33 | $vcenters = "","" 34 | $username = "" 35 | $pass = "" 36 | 37 | $database = "" 38 | $influxServer = "" 39 | $influxPort = 8086 40 | 41 | ################ 42 | ## End params ## 43 | ################ 44 | 45 | #Create array for storing data 46 | $tbl = @() 47 | 48 | foreach($vcenter in $vcenters){ 49 | $BaseUri = "https://$vcenter/rest/" 50 | 51 | #Authenticate to vCenter 52 | $SessionUri = $BaseUri + "com/vmware/cis/session" 53 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 54 | $header = @{ 55 | 'Authorization' = "Basic $auth" 56 | } 57 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 58 | $sessionheader = @{'vmware-api-session-id' = $token} 59 | 60 | #Fetch timestamp 61 | $timestamp = Get-DBTimestamp 62 | 63 | #API Endpoints 64 | $bckJobUri = $BaseUri + "appliance/recovery/backup/job" 65 | $bckSchedUri = $BaseUri + "appliance/recovery/backup/schedules" 66 | 67 | #Fetch data 68 | $bckJobResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $bckJobUri -SkipCertificateCheck 69 | $bckSchedResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $bckSchedUri -SkipCertificateCheck 70 | 71 | #Build variables for Influx 72 | $recurrence = "n/a" 73 | $schedEnabled = "false" 74 | $protocol = "n/a" 75 | $location = "n/a" 76 | if ($bckJobResponse) { 77 | if ($bckJobResponse.value.count -gt 1) { 78 | $jobId = $bckJobResponse.value[0] 79 | } 80 | else { 81 | $jobId = $bckJobResponse 82 | } 83 | $bckJobDetUri = $bckJobUri + "/$jobId" 84 | $bckJobDetResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $bckJobDetUri -SkipCertificateCheck 85 | 86 | $startTime = $bckJobDetResponse.value.start_time 87 | $endTime = $bckJobDetResponse.value.end_time 88 | 89 | $duration = (New-TimeSpan -Start $startTime -End $endTime).TotalSeconds 90 | $start = (New-TimeSpan -Start (get-date 1/1-1970) -End $startTime).TotalMilliseconds 91 | $end = (New-TimeSpan -Start (get-date 1/1-1970) -End $endTime).TotalMilliseconds 92 | $progress = $bckJobDetResponse.value.progress 93 | $state = $bckJobDetResponse.value.state 94 | } 95 | if ($bckSchedResponse.value) { 96 | $schedEnabled = $bckSchedResponse.value.value.enable 97 | if ($schedEnabled) { 98 | $schedLocation = $bckSchedResponse.value.value.location 99 | $schedLocSplit = $schedLocation.Split("://") 100 | $protocol = $schedLocSplit[0] 101 | $location = $schedLocSplit[1].Split(":")[0] 102 | 103 | $rec = $bckSchedResponse.value.value.recurrence_info 104 | if (!$rec.days) { 105 | $recurrence = "DAILY" 106 | } 107 | else { 108 | $recurrence = $rec.days 109 | } 110 | } 111 | } 112 | 113 | #Add to array 114 | if ($jobId) { 115 | $tbl += "appliance_backup_job,server=$vcenter jobid=""$jobId"",start=""$start"",end=""$end"",duration=$duration,progress=""$progress"",state=""$state"" $timestamp" 116 | } 117 | $tbl += "appliance_backup_schedule,server=$vcenter recurrence=""$recurrence"",protocol=""$protocol"",schedEnabled=$schedEnabled,location=""$location"" $timestamp" 118 | } 119 | 120 | #Post data to Influx API 121 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 122 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 123 | -------------------------------------------------------------------------------- /vcsa/appliance_health.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 6.0 2 | <# 3 | .SYNOPSIS 4 | Script for outputting VCSA health status to Influx 5 | .DESCRIPTION 6 | This script will fetch the health status from 7 | the VCSA REST API and post this data to a InfluxDB database. 8 | 9 | A conversion of the textual output of status to a numeric value 10 | will be done to support dashboard functions in Grafana 11 | 12 | This script is tested against vCenter 6.7U3, please note that 13 | there might be differences in other versions 14 | Note that this script is developed with PS Core and uses functionality 15 | not present in the desktop version of PS (v 5>=). A different version of the 16 | script that uses PS 5 can be found here, https://github.com/rumart/vmug-norway-dec-18 17 | .NOTES 18 | Author: Rudi Martinsen 19 | Created: 28/11-2018 20 | Version: 2.1.0 21 | Revised: 05/04-2020 22 | Changelog: 23 | 2.1.0 -- Added multiple vCenter support 24 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 25 | .LINK 26 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 27 | #> 28 | #Function for generating correct timestamp for influx input 29 | function Get-DBTimestamp($timestamp = (get-date)){ 30 | if($timestamp -is [system.string]){ 31 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 32 | } 33 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 34 | } 35 | 36 | ######################## 37 | ## Environment params ## 38 | ######################## 39 | $vcenters = "","" 40 | $username = "" 41 | $pass = "" 42 | 43 | $database = "" 44 | $influxServer = "" 45 | $influxPort = 8086 46 | 47 | ################ 48 | ## End params ## 49 | ################ 50 | 51 | #Create array for storing data 52 | $tbl = @() 53 | 54 | foreach($vcenter in $vcenters){ 55 | $BaseUri = "https://$vcenter/rest/" 56 | 57 | #Authenticate to vCenter 58 | $SessionUri = $BaseUri + "com/vmware/cis/session" 59 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 60 | $header = @{ 61 | 'Authorization' = "Basic $auth" 62 | } 63 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 64 | $sessionheader = @{'vmware-api-session-id' = $token} 65 | 66 | #Build string of metrics/endpoints to pull 67 | $metrics = "applmgmt","database-storage","load","mem","software-packages","storage","swap","system","services" 68 | 69 | #Fetch last checked timestamp. Will be used as timestamp for all records 70 | $lcuri = $BaseUri + "appliance/health/system/lastcheck" 71 | $lcresponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $lcuri -SkipCertificateCheck 72 | $timestamp = Get-DBTimestamp (get-date $lcresponse.value) 73 | 74 | #Iterate through all metrics/endpoints 75 | foreach($met in $metrics){ 76 | Remove-Variable value -ErrorAction SilentlyContinue | Out-Null 77 | 78 | #Build current endpoint URI 79 | $uri = $BaseUri + "appliance/health/$met" 80 | if($met -eq "services"){ 81 | $uri = $BaseUri + "appliance/$met" 82 | } 83 | 84 | #Fetch data from enpoint 85 | Clear-Variable meterr -ErrorAction SilentlyContinue 86 | $response = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $uri -SkipCertificateCheck -ErrorVariable metErr 87 | 88 | if(!$meterr){ 89 | #Set measurement name 90 | switch($met){ 91 | "database-storage" {$measurement="health_databasestorage"} 92 | "software-packages" {$measurement="health_softwarepackages"} 93 | default {$measurement = "health_$met"} 94 | } 95 | 96 | 97 | if($met -eq "services"){ 98 | 99 | foreach($val in $response.value){ 100 | $name = $val.key 101 | $value = $val.value.state 102 | #Set numeric value, used for determining status in dashboards 103 | switch($value){ 104 | "STARTED" {$val = 0} 105 | "STOPPED" {$val = 1} 106 | default {$val = 9} 107 | } 108 | #Add to data array 109 | $tbl += "services,server=$vcenter $name=""$value"",value=$val $timestamp" 110 | } 111 | } 112 | else{ 113 | 114 | $value = $response.value 115 | #Set numeric value, used for determining status in dashboards 116 | switch($value){ 117 | "green" {$val = 0} 118 | "orange" {$val = 1} 119 | "red" {$val = 2} 120 | "gray" {$val = 9} 121 | "unknown" {$val = 9} 122 | default {$val = 9} 123 | } 124 | 125 | #Add to data array 126 | $tbl += "$measurement,server=$vcenter text=""$value"",value=$val $timestamp" 127 | } 128 | 129 | } 130 | else{ 131 | Write-Warning "[ERROR] Error with $met, error msg $metErr" 132 | } 133 | 134 | } 135 | } 136 | 137 | #Post data to Influx API 138 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 139 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 140 | -------------------------------------------------------------------------------- /vcsa/appliance_info.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 6.0 2 | <# 3 | .SYNOPSIS 4 | Script for outputting VCSA info to Influx 5 | .DESCRIPTION 6 | This script will fetch build, version and uptime from 7 | the VCSA REST API and post this data to a InfluxDB database 8 | 9 | This script is tested against vCenter 6.7U3, please note that 10 | there might be differences in other versions 11 | Note that this script is developed with PS Core and uses functionality 12 | not present in the desktop version of PS (v 5>=). A different version of the 13 | script that uses PS 5 can be found here, https://github.com/rumart/vmug-norway-dec-18 14 | .NOTES 15 | Author: Rudi Martinsen 16 | Created: 28/11-2018 17 | Version: 2.1.0 18 | Revised: 05/04-2020 19 | Changelog: 20 | 2.1.0 -- Added multiple vCenter support 21 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 22 | .LINK 23 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 24 | #> 25 | #Function for generating correct timestamp for influx input 26 | function Get-DBTimestamp($timestamp = (get-date)){ 27 | if($timestamp -is [system.string]){ 28 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 29 | } 30 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 31 | } 32 | 33 | ######################## 34 | ## Environment params ## 35 | ######################## 36 | $vcenters = "","" 37 | $username = "" 38 | $pass = "" 39 | 40 | $database = "" 41 | $influxServer = "" 42 | $influxPort = 8086 43 | 44 | ################ 45 | ## End params ## 46 | ################ 47 | 48 | #Create array for storing data 49 | $tbl = @() 50 | 51 | foreach($vcenter in $vcenters){ 52 | $BaseUri = "https://$vcenter/rest/" 53 | 54 | #Authenticate to vCenter 55 | $SessionUri = $BaseUri + "com/vmware/cis/session" 56 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 57 | $header = @{ 58 | 'Authorization' = "Basic $auth" 59 | } 60 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 61 | $sessionheader = @{'vmware-api-session-id' = $token} 62 | 63 | #Create array for storing data 64 | $tbl = @() 65 | 66 | #Fetch timestamp 67 | $timestamp = Get-DBTimestamp 68 | 69 | #API Endpoints 70 | $verUri = $BaseUri + "appliance/system/version" 71 | $upUri = $BaseUri + "appliance/system/uptime" 72 | 73 | #Fetch data 74 | $verResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $verUri -SkipCertificateCheck 75 | $upResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $upUri -SkipCertificateCheck 76 | 77 | #Build variables for Influx 78 | $version = $verResponse.value.version 79 | $build = $verResponse.value.build 80 | $uptime = $upResponse.value 81 | 82 | #Add to array 83 | $tbl += "appliance_info,server=$vcenter version=""$version"",build=$build,uptime=$uptime $timestamp" 84 | } 85 | 86 | #Post data to Influx API 87 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 88 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 89 | -------------------------------------------------------------------------------- /vcsa/appliance_monitoring.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 6.0 2 | <# 3 | .SYNOPSIS 4 | Script for outputting vCenter load to Influx 5 | .DESCRIPTION 6 | This script will fetch the performance stats from 7 | the vCenter REST API and post this data to a InfluxDB database. 8 | 9 | The script will fetch the 5 minute interval. 10 | 11 | This script is tested against vCenter 6.7U3, please note that 12 | there might be differences in other versions 13 | Note that this script is developed with PS Core and uses functionality 14 | not present in the desktop version of PS (v 5>=). A different version of the 15 | script that uses PS 5 can be found here, https://github.com/rumart/vmug-norway-dec-18 16 | .NOTES 17 | Author: Rudi Martinsen 18 | Created: 28/11-2018 19 | Version: 2.1.0 20 | Revised: 05/04-2020 21 | Changelog: 22 | 2.1.0 -- Added multiple vCenter support 23 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 24 | .LINK 25 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 26 | #> 27 | #Function for generating correct timestamp for influx input 28 | function Get-DBTimestamp($timestamp = (get-date)){ 29 | if($timestamp -is [system.string]){ 30 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 31 | } 32 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 33 | } 34 | 35 | 36 | ######################## 37 | ## Environment params ## 38 | ######################## 39 | $vcenters = "","" 40 | $username = "" 41 | $pass = "" 42 | 43 | $database = "" 44 | $influxServer = "" 45 | $influxPort = 8086 46 | 47 | ################ 48 | ## End params ## 49 | ################ 50 | 51 | #Create array for storing data 52 | $tbl = @() 53 | 54 | foreach($vcenter in $vcenters){ 55 | $BaseUri = "https://$vcenter/rest/" 56 | 57 | #Authenticate to vCenter 58 | $SessionUri = $BaseUri + "com/vmware/cis/session" 59 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 60 | $header = @{ 61 | 'Authorization' = "Basic $auth" 62 | } 63 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 64 | $sessionheader = @{'vmware-api-session-id' = $token} 65 | 66 | #Build string of metrics to pull 67 | $metrics = @( 68 | "cpu.util" 69 | "mem.usage" 70 | ) 71 | 72 | $count = 1 73 | $string = "" 74 | foreach($met in $metrics){ 75 | $string += "&item.names.$count=$met" 76 | $count++ 77 | } 78 | 79 | #Set start/end timestamps for use in the endpoint queries 80 | $end = (Get-Date).AddMinutes(-5).ToUniversalTime() 81 | $start = $end.AddMinutes(-5) 82 | $endTime = Get-Date $end -Format "yyyy-MM-ddTHH\:mm\:ss.fffZ" 83 | $startTime = Get-Date $start -Format "yyyy-MM-ddTHH\:mm\:ss.fffZ" 84 | 85 | #Build URI with timestamps and metrics string 86 | $uri = $BaseUri + "appliance/monitoring/query?item.interval=MINUTES5&item.function=MAX&item.start_time=$startTime&item.end_time=$endTime$string" 87 | 88 | #Fetch data 89 | $response = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $uri -SkipCertificateCheck 90 | 91 | #Iterate through metrics 92 | foreach($stat in $response.value){ 93 | Remove-Variable val1,val2,time1,time2 -ErrorAction SilentlyContinue | Out-Null 94 | 95 | #Set measurement name 96 | switch($stat.name){ 97 | "cpu.util" {$measurement = "cpu"; $field = "value"; } 98 | "mem.usage" {$measurement = "mem"; $field = "value"; } 99 | default {$measurement = $null} 100 | } 101 | 102 | if($measurement -eq $null){ 103 | continue 104 | } 105 | 106 | #Fetch both values (in case of 5 min interval) and add to data array 107 | if($stat.data[-2]){ 108 | $val1 = $stat.data[-2] 109 | $time1 = Get-DBTimestamp (get-date $stat.start_time) 110 | $tbl += "$measurement,server=$vcenter,interval=$($stat.interval),unit=perc $field=$val1 $time1" 111 | } 112 | 113 | if($stat.data[-1]){ 114 | $val2 = $stat.data[-1] 115 | $time2 = Get-DBTimestamp (get-date $stat.end_time) 116 | $tbl += "$measurement,server=$vcenter,interval=$($stat.interval),unit=perc $field=$val2 $time2" 117 | } 118 | } 119 | } 120 | 121 | #Post data to Influx API 122 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 123 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 124 | -------------------------------------------------------------------------------- /vcsa/appliance_storage.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 6.0 2 | <# 3 | .SYNOPSIS 4 | Script for outputting vCenter storage info to Influx 5 | .DESCRIPTION 6 | This script will fetch the storage utilization from 7 | the vCenter REST API and post this data to a InfluxDB database. 8 | 9 | The script will fetch the 30 minute interval. 10 | 11 | This script is tested against vCenter 6.7U3, please note that 12 | there might be differences in other versions 13 | Note that this script is developed with PS Core and uses functionality 14 | not present in the desktop version of PS (v 5>=). A different version of the 15 | script that uses PS 5 can be found here, https://github.com/rumart/vmug-norway-dec-18 16 | .NOTES 17 | Author: Rudi Martinsen 18 | Created: 28/11-2018 19 | Version: 2.1.0 20 | Revised: 05/04-2020 21 | Changelog: 22 | 2.1.0 -- Added multiple vCenter support 23 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 24 | .LINK 25 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 26 | #> 27 | #Function for generating correct timestamp for influx input 28 | function Get-DBTimestamp($timestamp = (get-date)){ 29 | if($timestamp -is [system.string]){ 30 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 31 | } 32 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 33 | } 34 | 35 | 36 | ######################## 37 | ## Environment params ## 38 | ######################## 39 | $vcenters = "","" 40 | $username = "" 41 | $pass = "" 42 | 43 | $database = "" 44 | $influxServer = "" 45 | $influxPort = 8086 46 | 47 | ################ 48 | ## End params ## 49 | ################ 50 | 51 | #Create array for storing data 52 | $tbl = @() 53 | 54 | foreach($vcenter in $vcenters){ 55 | 56 | $BaseUri = "https://$vcenter/rest/" 57 | 58 | #Authenticate to vCenter 59 | $SessionUri = $BaseUri + "com/vmware/cis/session" 60 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 61 | $header = @{ 62 | 'Authorization' = "Basic $auth" 63 | } 64 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 65 | $sessionheader = @{'vmware-api-session-id' = $token} 66 | 67 | #Build string of metrics to pull 68 | $metrics = @( 69 | "storage.totalsize.filesystem.db" 70 | "storage.used.filesystem.db" 71 | "storage.totalsize.filesystem.dblog" 72 | "storage.used.filesystem.dblog" 73 | "storage.totalsize.filesystem.log" 74 | "storage.used.filesystem.log" 75 | "storage.totalsize.filesystem.root" 76 | "storage.used.filesystem.root" 77 | "storage.totalsize.filesystem.seat" 78 | "storage.used.filesystem.seat" 79 | "storage.totalsize.filesystem.updatemgr" 80 | "storage.used.filesystem.updatemgr" 81 | "storage.totalsize.filesystem.core" 82 | "storage.used.filesystem.core" 83 | ) 84 | 85 | $count = 1 86 | $string = "" 87 | foreach($met in $metrics){ 88 | $string += "&item.names.$count=$met" 89 | $count++ 90 | } 91 | 92 | #Set start/end timestamps for use in the endpoint queries 93 | $end = (Get-Date).AddMinutes(-5).ToUniversalTime() 94 | $start = $end.AddMinutes(-5) 95 | $endTime = Get-Date $end -Format "yyyy-MM-ddTHH\:mm\:ss.fffZ" 96 | $startTime = Get-Date $start -Format "yyyy-MM-ddTHH\:mm\:ss.fffZ" 97 | 98 | #Build URI with timestamps and metrics string 99 | $uri = $BaseUri + "appliance/monitoring/query?item.interval=MINUTES30&item.function=MAX&item.start_time=$startTime&item.end_time=$endTime$string" 100 | 101 | #Fetch data 102 | $response = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $uri -SkipCertificateCheck 103 | 104 | #Iterate through metrics 105 | foreach($stat in $response.value){ 106 | 107 | #Set timestamp 108 | $timestamp = Get-DBTimestamp (get-date $stat.end_time) 109 | 110 | #Select the latest value 111 | $storageVal = ($stat.data[-1] / 1024) 112 | 113 | #Set measurement and field names 114 | switch($stat.name){ 115 | "storage.totalsize.filesystem.db" {$measurement = "storage.db"; $field = "totalsize"} 116 | "storage.used.filesystem.db" {$measurement = "storage.db"; $field = "used"} 117 | "storage.totalsize.filesystem.dblog" {$measurement = "storage.dblog"; $field = "totalsize"} 118 | "storage.used.filesystem.dblog" {$measurement = "storage.dblog"; $field = "used"} 119 | "storage.totalsize.filesystem.seat" {$measurement = "storage.seat"; $field = "totalsize"} 120 | "storage.used.filesystem.seat" {$measurement = "storage.seat"; $field = "used"} 121 | "storage.totalsize.filesystem.core" {$measurement = "storage.core"; $field = "totalsize"} 122 | "storage.used.filesystem.core" {$measurement = "storage.core"; $field = "used"} 123 | "storage.totalsize.filesystem.log" {$measurement = "storage.log"; $field = "totalsize"} 124 | "storage.used.filesystem.log" {$measurement = "storage.log"; $field = "used"} 125 | "storage.totalsize.filesystem.root" {$measurement = "storage.root"; $field = "totalsize"} 126 | "storage.used.filesystem.root" {$measurement = "storage.root"; $field = "used"} 127 | "storage.totalsize.filesystem.updatemgr" {$measurement = "storage.updatemgr"; $field = "totalsize"} 128 | "storage.used.filesystem.updatemgr" {$measurement = "storage.updatemgr"; $field = "used"} 129 | } 130 | 131 | #Add data to array 132 | $tbl += "$measurement,server=$vcenter,interval=$($stat.interval),unit=MB $field=$storageVal $timestamp" 133 | 134 | } 135 | } 136 | 137 | #Post data to Influx API 138 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 139 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 140 | -------------------------------------------------------------------------------- /vcsa/appliance_update.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Script for outputting VCSA info to Influx 4 | .DESCRIPTION 5 | This script will fetch update information from 6 | the VCSA REST API and post this data to a InfluxDB database 7 | 8 | This script is tested against vCenter 6.7U3, please note that 9 | there might be differences in other version 10 | .NOTES 11 | Author: Rudi Martinsen 12 | Created: 07/11-2019 13 | Version: 2.1.0 14 | Revised: 05/04-2020 15 | Changelog: 16 | 2.1.0 -- Added multiple vCenter support 17 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 18 | .LINK 19 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 20 | #> 21 | #Function for generating correct timestamp for influx input 22 | function Get-DBTimestamp($timestamp = (get-date)){ 23 | if($timestamp -is [system.string]){ 24 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 25 | } 26 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 27 | } 28 | 29 | ######################## 30 | ## Environment params ## 31 | ######################## 32 | $vcenters = "","" 33 | $username = "" 34 | $pass = "" 35 | 36 | $database = "" 37 | $influxServer = "" 38 | $influxPort = 8086 39 | 40 | ################ 41 | ## End params ## 42 | ################ 43 | 44 | #Create array for storing data 45 | $tbl = @() 46 | 47 | foreach($vcenter in $vcenters){ 48 | 49 | $BaseUri = "https://$vcenter/rest/" 50 | 51 | #Authenticate to vCenter 52 | $SessionUri = $BaseUri + "com/vmware/cis/session" 53 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 54 | $header = @{ 55 | 'Authorization' = "Basic $auth" 56 | } 57 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 58 | $sessionheader = @{'vmware-api-session-id' = $token} 59 | 60 | 61 | #Fetch timestamp 62 | $timestamp = Get-DBTimestamp 63 | 64 | #API Endpoints 65 | $updUri = $BaseUri + "appliance/update" 66 | $updLastCheckUri = $BaseUri + "appliance/update/pending?source_type=LAST_CHECK" 67 | $updPolUri = $BaseUri + "appliance/update/policy" 68 | 69 | #Fetch data 70 | $updResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $updUri -SkipCertificateCheck 71 | $updPolResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $updPolUri -SkipCertificateCheck 72 | 73 | #Build variables for Influx 74 | $qryTime = $updResponse.value.latest_query_time 75 | $newVersion = "n/a" 76 | $upd_type = "n/a" 77 | $rel_date = "n/a" 78 | $priority = "n/a" 79 | $severity = "n/a" 80 | if($qryTime -and $qryTime -ge (Get-Date).AddDays(-1)){ 81 | $qryTime = (New-TimeSpan -Start (get-date 1/1-1970) -End $qrytime).TotalMilliseconds 82 | $updLastCheckResponse = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $updLastCheckUri -SkipCertificateCheck 83 | $state = $updResponse.value.state 84 | if ($updLastCheckResponse) { 85 | $newVersion = $updLastCheckResponse.value[0].version 86 | $upd_type = $updLastCheckResponse.value[0].update_type 87 | $rel_date = (New-TimeSpan -Start (get-date 1/1-1970) -End $updLastCheckResponse.value[0].release_date).TotalMilliseconds 88 | $priority = $updLastCheckResponse.value[0].priority 89 | $severity = $updLastCheckResponse.value[0].severity 90 | } 91 | } 92 | else{ 93 | $qryTime = "n/a" 94 | $state = "n/a" 95 | } 96 | 97 | $manualControl = $updPolResponse.value.manual_control 98 | 99 | #Add to array 100 | $tbl += "appliance_update,server=$vcenter state=""$state"",query_time=""$qryTime"",manual_control=$manualControl,new_version=""$newVersion"",rel_date=""$rel_date"",upd_type=""$upd_type"",severity=""$severity"",priority=""$priority"" $timestamp" 101 | 102 | } 103 | 104 | #Post data to Influx API 105 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 106 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 107 | 108 | -------------------------------------------------------------------------------- /vcsa/vcenter_services.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 6.0 2 | <# 3 | .SYNOPSIS 4 | Script for outputting vCenter storage info to Influx 5 | .DESCRIPTION 6 | This script will fetch the vCenter services status from 7 | the vCenter REST API and post this data to a InfluxDB database. 8 | 9 | A conversion of the textual output of status to a numeric value 10 | will be done to support dashboard functions in Grafana 11 | 12 | This script is tested against vCenter 6.7U3, please note that 13 | there might be differences in other versions 14 | Note that this script is developed with PS Core and uses functionality 15 | not present in the desktop version of PS (v 5>=). A different version of the 16 | script that uses PS 5 can be found here, https://github.com/rumart/vmug-norway-dec-18 17 | .NOTES 18 | Author: Rudi Martinsen 19 | Created: 28/11-2018 20 | Version: 2.1.0 21 | Revised: 05/04-2020 22 | Changelog: 23 | 2.1.0 -- Added multiple vCenter support 24 | 2.0.0 -- BREAKING CHANGE: Ported to PS core, v6+ required 25 | .LINK 26 | https://www.rudimartinsen.com/2018/12/03/vsphere-performance-vcenter-server-appliance-vcsa-monitoring/ 27 | #> 28 | #Function for generating correct timestamp for influx input 29 | function Get-DBTimestamp($timestamp = (get-date)){ 30 | if($timestamp -is [system.string]){ 31 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 32 | } 33 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 34 | } 35 | 36 | ######################## 37 | ## Environment params ## 38 | ######################## 39 | $vcenters = "","" 40 | $username = "" 41 | $pass = "" 42 | 43 | $database = "" 44 | $influxServer = "" 45 | $influxPort = 8086 46 | 47 | ################ 48 | ## End params ## 49 | ################ 50 | 51 | #Create array for storing data 52 | $tbl = @() 53 | 54 | foreach($vcenter in $vcenters){ 55 | $BaseUri = "https://$vcenter/rest/" 56 | 57 | #Authenticate to vCenter 58 | $SessionUri = $BaseUri + "com/vmware/cis/session" 59 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($UserName+':'+$Pass)) 60 | $header = @{ 61 | 'Authorization' = "Basic $auth" 62 | } 63 | $token = (Invoke-RestMethod -Method Post -Headers $header -Uri $SessionUri -SkipCertificateCheck).Value 64 | $sessionheader = @{'vmware-api-session-id' = $token} 65 | 66 | #Set endpoint URI 67 | $uri = $BaseUri + "appliance/vmon/service" 68 | 69 | #Fetch data 70 | $response = Invoke-RestMethod -Method Get -Headers $sessionheader -Uri $uri -SkipCertificateCheck 71 | 72 | #Set timestamp for query 73 | $timestamp = Get-DBTimestamp 74 | 75 | #Iterate through services 76 | foreach($stat in $response.value){ 77 | 78 | Remove-Variable value -ErrorAction SilentlyContinue | Out-Null 79 | 80 | #Set name and state of service 81 | $name = $stat.key 82 | $state = $stat.value.state 83 | 84 | #Set state to DEGRADED if an AUTOMATIC service is stopped 85 | if($stat.value.health){ 86 | $health = $stat.value.health 87 | } 88 | elseif($stat.value.startup_type -eq "AUTOMATIC" -and $stat.value.state -ne "STARTED"){ 89 | $health = "DEGRADED" 90 | } 91 | else{ 92 | $health = "N/A" 93 | } 94 | 95 | #Set numeric value based on textual output 96 | switch($health){ 97 | "HEALTHY" {$val = 0} 98 | "HEALTHY_WITH_WARNINGS" {$val = 1} 99 | "DEGRADED" {$val = 2} 100 | default {$val = 9} 101 | } 102 | 103 | #Set measurement name 104 | $measurementName = "vcservice_" + $name 105 | 106 | #Add to data array 107 | $tbl += "$measurementName,server=$vcenter health=""$health"",state=""$state"",value=$val $timestamp" 108 | 109 | } 110 | } 111 | 112 | #Post data to Influx API 113 | $postUri = "http://$influxServer" + ":$influxPort/write?db=$database" 114 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 115 | -------------------------------------------------------------------------------- /vm_performance_poller.ps1: -------------------------------------------------------------------------------- 1 | #requires -module VMware.PowerCLI 2 | <# 3 | .SYNOPSIS 4 | Script for pulling performance metrics from vCenter and writing to an Influx database 5 | .DESCRIPTION 6 | The script will pull performance metrics for VMs from vCenter and writes to an Influx 7 | timeseries database. 8 | .NOTES 9 | Author: Rudi Martinsen / Intility AS 10 | Created: 14/06-2017 11 | Version 0.8.3 12 | Revised: 05/03-2018 13 | Changelog: 14 | 0.8.3 -- Added metrics (net,disk,iops total & costop) 15 | 0.8.2 -- ToUpper on VMName 16 | 0.8.1 -- Fixed bug in VM selection 17 | 0.8.0 -- Added datastore as tag 18 | 0.7.1 -- Fixed bug in companycode 19 | 0.7.0 -- Added error handling on vCenter connection, added link to website 20 | 0.6.1 -- Fixed missing unit conversion on cpu_ready 21 | 0.6.0 -- Added override of Disk latency 22 | 0.5.0 -- Moved companycode logic to a function 23 | 0.4.2 -- Fixed bug in companycode 24 | 0.4.1 -- Fixed bug in hostname 25 | 0.4.0 -- Changed to entitycount for pollingstat 26 | 0.3.0 -- foreach and switch statement on stats 27 | 0.2.1 -- Cleaned script and added description 28 | .LINK 29 | http://www.rudimartinsen.com/2017/07/17/vsphere-performance-data-part-5-the-script/ 30 | .PARAMETER Samples 31 | Script parameter for how many samples to fetch. Default of 15 will give last 5 minutes (15*20sec) 32 | .PARAMETER VCenter 33 | The vCenter to connect to 34 | .PARAMETER Cluster 35 | The Cluster to get VMs from. If omitted all VMs in the vCenter will be fetched 36 | .PARAMETER VMCount 37 | Optional number of VMs to get metrics from 38 | .PARAMETER Skip 39 | Optional number of VMs to skip. Use with VMCount 40 | .PARAMETER Targetname 41 | Optional name of the target for use as a Tag in the Influx record 42 | .PARAMETER DBServer 43 | IP Address or hostname of the Influx Database server 44 | .PARAMETER DBServerPort 45 | TCP port for the DB server, Defaults to 8086 which is the default Influx port 46 | .PARAMETER LogFile 47 | Path to the logfile to write to 48 | #> 49 | param( 50 | $VCenter, 51 | $Cluster, 52 | $Samples = 15, 53 | $Vmcount = 0, 54 | $Skip = 0, 55 | $Targetname, 56 | $Dbserver, 57 | $DbserverPort = 8086, 58 | $LogFile 59 | ) 60 | #Function to get the correct timestamp format for Influx 61 | function Get-DBTimestamp($timestamp = (get-date)){ 62 | if($timestamp -is [system.string]){ 63 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 64 | } 65 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 66 | } 67 | 68 | function Get-CompanyCode ($vmname) { 69 | $splitName = $vmname.split("-")[0] 70 | 71 | if($splitName.Length -eq 2){ 72 | $companycode = $splitName 73 | } 74 | elseif($splitName.Length -gt 2){ 75 | $companycode = $splitName.Substring(0,2) 76 | 77 | } 78 | else{ 79 | $companycode = $null 80 | } 81 | return $companycode 82 | } 83 | 84 | if(!$LogFile){ 85 | $scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 86 | $logDir = "$scriptdir\log" 87 | if(!(Test-Path $logDir)){ 88 | New-Item -ItemType Directory -Path $logDir 89 | } 90 | $LogFile = "$logDir\vcpoll.log" 91 | } 92 | 93 | 94 | $start = Get-Date 95 | 96 | #Import PowerCLI 97 | Import-Module VMware.VimAutomation.Core 98 | 99 | #Vstatinterval is based on the realtime performance metrics gathered from vCenter which is 20 seconds 100 | $statInterval = 20 101 | 102 | #Variable to calculate correct CpuRdy value 103 | $cpuRdyInt = 200 104 | 105 | #Variable to calculate if Disk latency threshold. Used to override very high latency caused by snapshot removal 106 | #365 days * 24 hours * 60 minutes * 60 seconds * 1000 = x ms 107 | $latThreshold = 365 * 24 * 60 * 60 * 1000 108 | #Set targetname if omitted as a script parameter 109 | if($targetname -eq $null -or $targetname -eq ""){ 110 | if($cluster){ 111 | $targetname = $cluster 112 | } 113 | else{ 114 | $targetname = $vcenter 115 | } 116 | } 117 | 118 | #Connect to vCenter 119 | try { 120 | $vc_conn = Connect-VIServer $vcenter -ErrorAction Stop -ErrorVariable vcerr 121 | $vcid = $vc_conn.InstanceUuid 122 | } 123 | catch { 124 | Write-Output "$(Get-Date) : Couldn't connect to vCenter $vCenter. Script was started at $start" | Out-File $LogFile -Append 125 | Write-Output "$(Get-Date) : Error message was: $($vcerr.message)" | Out-File $LogFile -Append 126 | break 127 | } 128 | 129 | #Get VMs 130 | if($cluster){ 131 | $vms = Get-Cluster $cluster -Server $vcenter | Get-VM | Where-Object {$_.PowerState -eq "PoweredOn"} 132 | } 133 | else{ 134 | $vms = Get-VM -Server $vcenter | Where-Object {$_.PowerState -eq "PoweredOn"} 135 | } 136 | 137 | #Filter based on vmcount/skip parameters. 138 | #TODO: Could probably be done in the query above? 139 | if($vmcount -gt 0){ 140 | $vms = $vms | Sort-Object name | Select-Object -First $vmcount -Skip $skip 141 | } 142 | 143 | #Table to store data 144 | $tbl = @() 145 | 146 | #The different metrics to fetch 147 | $metrics = "cpu.ready.summation","cpu.costop.summation","cpu.latency.average","cpu.usagemhz.average","cpu.usage.average","mem.active.average","mem.usage.average","net.received.average","net.transmitted.average","disk.maxtotallatency.latest","disk.read.average","disk.write.average","disk.numberReadAveraged.average","disk.numberWriteAveraged.average","net.usage.average","disk.usage.average","disk.commandsAveraged.average" 148 | 149 | foreach($vm in $vms){ 150 | $lapStart = get-date 151 | 152 | #Build variables for vm "metadata" 153 | $hid = $vm.VMHostId 154 | $cid = $vm.VMHost.ParentId 155 | $cname = $vm.VMHost.Parent.Name 156 | $vid = $vm.Id 157 | $vname = $vm.name 158 | $vproc = $vm.NumCpu 159 | $hname = $vm.VMHost.Name 160 | $vname = $vname.toUpper() 161 | 162 | Clear-Variable datastore | Out-Null 163 | foreach($dsname in $vm.ExtensionData.Config.DatastoreUrl.Name){ 164 | if($dsname -ne "iso" -and $dsname -ne "storage"){ 165 | $datastore = $dsname 166 | break 167 | } 168 | } 169 | 170 | #Get the Company Code from the vmname 171 | $companycode = Get-CompanyCode -vmname $vname 172 | 173 | #Get the stats 174 | $stats = Get-Stat -Entity $vm -Realtime -MaxSamples $samples -Stat $metrics 175 | 176 | foreach($stat in $stats){ 177 | $instance = $stat.Instance 178 | 179 | #Metrics will often have values for several instances per entity. Normally they will also have an aggregated instance. We're only interested in that one for now 180 | if($instance -or $instance -ne ""){ 181 | continue 182 | } 183 | 184 | $unit = $stat.Unit 185 | $value = $stat.Value 186 | $statTimestamp = Get-DBTimestamp $stat.Timestamp 187 | 188 | if($unit -eq "%"){ 189 | $unit="perc" 190 | } 191 | 192 | switch ($stat.MetricId) { 193 | "cpu.ready.summation" { $measurement = "cpu_ready";$value = $(($Value / $cpuRdyInt)/$vproc); $unit = "perc" } 194 | "cpu.costop.summation" { $measurement = "cpu_costop";$value = $(($Value / $cpuRdyInt)/$vproc); $unit = "perc" } 195 | "cpu.latency.average" {$measurement = "cpu_latency" } 196 | "cpu.usagemhz.average" {$measurement = "cpu_usagemhz" } 197 | "cpu.usage.average" {$measurement = "cpu_usage" } 198 | "mem.active.average" {$measurement = "mem_usagekb" } 199 | "mem.usage.average" {$measurement = "mem_usage" } 200 | "net.received.average" {$measurement = "net_through_receive"} 201 | "net.transmitted.average" {$measurement = "net_through_transmit"} 202 | "net.usage.average" {$measurement = "net_through_total"} 203 | "disk.maxtotallatency.latest" {$measurement = "storage_latency";if($value -ge $latThreshold){$value = 0}} 204 | "disk.read.average" {$measurement = "disk_through_read"} 205 | "disk.write.average" {$measurement = "disk_through_write"} 206 | "disk.usage.average" {$measurement = "disk_through_total"} 207 | Default { $measurement = $null } 208 | } 209 | 210 | if($measurement -ne $null){ 211 | $tbl += "$measurement,type=vm,vm=$vname,vmid=$vid,companycode=$companycode,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,datastore=$datastore,unit=$unit,statinterval=$statinterval value=$Value $stattimestamp" 212 | } 213 | 214 | } 215 | 216 | $stats | Where-Object {$_.metricid -eq "disk.numberReadAveraged.average"} | Group-Object timestamp | ForEach-Object {$tbl += "disk_iops_read,type=vm,vm=$vname,vmid=$vid,companycode=$companycode,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,datastore=$datastore,unit=iops,statinterval=$statinterval value=$($_.group) $(Get-DBTimestamp $_.name)"} 217 | $stats | Where-Object {$_.metricid -eq "disk.numberWriteAveraged.average"} | Group-Object timestamp | ForEach-Object {$tbl += "disk_iops_write,type=vm,vm=$vname,vmid=$vid,companycode=$companycode,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,datastore=$datastore,unit=iops,statinterval=$statinterval value=$($_.group) $(Get-DBTimestamp $_.name)"} 218 | $stats | Where-Object {$_.metricid -eq "disk.commandsAveraged.average"} | Group-Object timestamp | ForEach-Object {$tbl += "disk_iops_total,type=vm,vm=$vname,vmid=$vid,companycode=$companycode,host=$hname,hostid=$hid,cluster=$cname,clusterid=$cid,platform=$vcenter,platformid=$vcid,datastore=$datastore,unit=iops,statinterval=$statinterval value=$($_.group) $(Get-DBTimestamp $_.name)"} 219 | 220 | #Calculate lap time 221 | $lapStop = get-date 222 | $timespan = New-TimeSpan -Start $lapStart -End $lapStop 223 | Write-Output $timespan.TotalSeconds 224 | 225 | } 226 | 227 | #Disconnect from vCenter 228 | Disconnect-VIServer $vcenter -Confirm:$false 229 | 230 | #Calculate runtime 231 | $stop = get-date 232 | $runTimespan = New-TimeSpan -Start $start -End $stop 233 | 234 | Write-Output "Run took $($runTimespan.TotalSeconds) seconds" 235 | 236 | #Build URI for the API call 237 | $baseUri = "http://" + $dbserver + ":" + $dbserverPort + "/" 238 | $dbname = "performance" 239 | $postUri = $baseUri + "write?db=" + $dbname 240 | 241 | #TODO: Perform a test againts the API? 242 | 243 | #Write data to the API 244 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($tbl -join "`n") 245 | 246 | #Build qry to write stats about the run 247 | $pollStatQry = "pollingstat,poller=$($env:COMPUTERNAME),unit=s,type=vmpoll,target=$($targetname) runtime=$($runtimespan.TotalSeconds),entitycount=$($vms.Count) $(Get-DBTimestamp -timestamp $start)" 248 | 249 | #Write data about the run 250 | Invoke-RestMethod -Method Post -Uri $postUri -Body $pollStatQry 251 | 252 | #TODO: Error handling for API calls.. -------------------------------------------------------------------------------- /vsan_cluster_performance_poller.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Script for pulling performance metrics from vCenter VSAN clusters and writing to an Influx database 4 | .DESCRIPTION 5 | The script will pull performance metrics for VSAN Hosts from vCenter and writes to an Influx 6 | timeseries database. 7 | .NOTES 8 | Author: Rudi Martinsen / Intility AS 9 | Created: 07/03-2018 10 | Version 0.2.0 11 | Revised: 25/06-2019 12 | Changelog: 13 | 0.2.0 -- Support for multiple clusters 14 | 0.1.2 -- Cleaned unused variables 15 | 0.1.1 -- Added backend stuff 16 | 0.1.0 -- Fork from Host poller 17 | .LINK 18 | http://www.rudimartinsen.com/2018/04/06/vsphere-performance-data-monitoring-vmware-vsan-performance/ 19 | .PARAMETER VCenter 20 | The vCenter to connect to 21 | .PARAMETER Cluster 22 | The Cluster to get stats from. If omitted all VSAN clusters in the vCenter will be fetched 23 | .PARAMETER Targetname 24 | Optional name of the target for use as a Tag in the Influx record 25 | .PARAMETER DBServer 26 | IP Address or hostname of the Influx Database server 27 | .PARAMETER DBServerPort 28 | TCP port for the DB server, Defaults to 8086 which is the default Influx port 29 | .PARAMETER LogFile 30 | Path to the logfile to write to 31 | #> 32 | param( 33 | [Parameter(Mandatory=$true)] 34 | $VCenter, 35 | [Parameter(Mandatory=$false)] 36 | $Cluster, 37 | $Targetname, 38 | $Dbserver, 39 | $DbserverPort = 8086, 40 | $LogFile 41 | ) 42 | #Function to get the correct timestamp format for Influx 43 | function Get-DBTimestamp($timestamp = (get-date)){ 44 | if($timestamp -is [system.string]){ 45 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 46 | } 47 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 48 | } 49 | 50 | if(!$LogFile){ 51 | $scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 52 | $LogFile = "$scriptDir\log\vcpoll_vsan_cluster.log" 53 | } 54 | $start = Get-Date 55 | 56 | #Import PowerCLI 57 | #Import-Module VMware.VimAutomation.Core 58 | Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip:$false -Scope Session -Confirm:$false 59 | 60 | #Vstatinterval is based on the realtime performance metrics gathered from vCenter which is 20 seconds 61 | $statInterval = 300 62 | 63 | #Set targetname if omitted as a script parameter 64 | if($targetname -eq $null -or $targetname -eq ""){ 65 | if($cluster){ 66 | $targetname = $cluster 67 | } 68 | else{ 69 | $targetname = $vcenter 70 | } 71 | $Targetname = "VSAN_" + $Targetname 72 | } 73 | 74 | #Connect to vCenter 75 | try { 76 | $vc_conn = Connect-VIServer $vcenter -ErrorAction Stop -ErrorVariable vcerr 77 | $vcid = $vc_conn.InstanceUuid 78 | } 79 | catch { 80 | Write-Output "$(Get-Date) : Couldn't connect to vCenter $vCenter. Script was started at $start" | Out-File $LogFile -Append 81 | Write-Output "$(Get-Date) : Error message was: $($vcerr.message)" | Out-File $LogFile -Append 82 | break 83 | } 84 | 85 | #Get VSAN clusters 86 | if($cluster){ 87 | $clusterObjects = Get-Cluster $cluster -ErrorAction Stop -ErrorVariable clustErr 88 | } 89 | else{ 90 | $clusterObjects = Get-Cluster | Where-Object {$_.VsanEnabled} 91 | Write-Output "Found $($clusterObjects.count) clusters" 92 | } 93 | 94 | #Table to store data 95 | $newtbl = @() 96 | 97 | #The different metrics to fetch. Because some errors with specifying the metrics we're using the wildcard instead.. 98 | #$metricsVsan = "VMConsumption.ReadThroughput","VMConsumption.AverageReadLatency","VMConsumption.WriteThroughput","VMConsumption.AverageWriteLatency","VMConsumption.Congestion","VMConsumption.OutstandingIO" 99 | $metricsVsan = "*" 100 | 101 | if(!$clusterObjects){ 102 | Write-Output "$(Get-Date) : Cluster not found. Exiting..." | Out-File $LogFile -Append 103 | break 104 | } 105 | foreach($clusterObj in $clusterObjects){ 106 | Write-Output "Processing VSAN cluster $($clusterObj.Name)" 107 | $san = $clusterObj.Name 108 | $sanid = $clusterObj.Id 109 | $type = "vsan" 110 | 111 | #Get the stats 112 | $stats = Get-VsanStat -Entity $clusterObj -Name $metricsVsan -StartTime $start.AddMinutes(-5) 113 | $space = Get-VsanSpaceUsage -Cluster $san 114 | 115 | foreach($stat in $stats){ 116 | 117 | $unit = $stat.Unit 118 | #We'll convert microseconds to milliseconds to correspond with "normal" vSphere stats 119 | if($unit -eq "Microseconds"){ 120 | $value = $stat.Value / 1000 121 | $unit = "ms" 122 | } 123 | else{ 124 | $value = $stat.Value 125 | } 126 | 127 | #Get correct timestamp for InfluxDB 128 | $statTimestamp = Get-DBTimestamp $stat.Time 129 | 130 | if($unit -eq "%"){ 131 | $unit="perc" 132 | } 133 | switch ($stat.Name) { 134 | "VMConsumption.ReadThroughput" { $measurement = "kB_read"; $value = ($value / 1024); $unit = "KBps" } 135 | "VMConsumption.AverageReadLatency" { $measurement = "latency_read"; } 136 | "VMConsumption.WriteThroughput" { $measurement = "kB_write"; $value = ($value / 1024); $unit = "KBps" } 137 | "VMConsumption.AverageWriteLatency" { $measurement = "latency_write"; } 138 | "VMConsumption.Congestion" {$measurement = "congestion"; $unit = "count" } 139 | "VMConsumption.OutstandingIO" { $measurement = "io_outstanding"; $unit = "count" } 140 | "VMConsumption.ReadIops" { $measurement = "io_read"; $unit = "iops" } 141 | "VMConsumption.WriteIops" { $measurement = "io_write"; $unit = "iops" } 142 | "Backend.ResyncReadLatency" { $measurement = "latency_resync_read"; } 143 | "Backend.ReadThroughput" { $measurement = "kB_read_backend"; $value = ($value / 1024); $unit = "KBps" } 144 | "Backend.AverageReadLatency" { $measurement = "latency_read_backend"; } 145 | "Backend.WriteThroughput" { $measurement = "kB_write_backend"; $value = ($value / 1024); $unit = "KBps" } 146 | "Backend.AverageWriteLatency" { $measurement = "latency_write_backend"; } 147 | "Backend.Congestion" {$measurement = "congestion_backend"; $unit = "count" } 148 | "Backend.OutstandingIO" { $measurement = "io_outstanding_backend"; $unit = "count" } 149 | "Backend.RecoveryWriteIops" { $measurement = "io_write_recovery"; $unit = "iops" } 150 | "Backend.RecoveryWriteThroughput" { $measurement = "kb_write_recovery"; $value = ($value / 1024); $unit = "KBps" } 151 | "Backend.RecoveryWriteAverageLatency" { $measurement = "latency_write_recovery"; } 152 | Default { $measurement = $null } 153 | } 154 | 155 | if($measurement -ne $null){ 156 | $newtbl += "$measurement,type=$type,san=$san,sanid=$sanid,platform=$vcenter,platformid=$vcid,unit=$unit,statinterval=$statinterval value=$Value $stattimestamp" 157 | } 158 | } 159 | 160 | if($space){ 161 | $newtbl += "vsan_diskusage,type=$type,san=$san,sanid=$sanid,platform=$vcenter,platformid=$vcid,unit=GB,statinterval=$statinterval freespace=$([int]$space.freespacegb),capacity=$([int]$space.CapacityGB),primaryvmdata=$([int]$space.PrimaryVMDataGB),vdiskusage=$([int]$space.VirtualDiskUsageGB),vsanoverhead=$([int]$space.VsanOverheadGB),vmhomeusage=$([int]$space.VMHomeUsageGB) $stattimestamp" 162 | } 163 | } 164 | #Disconnect from vCenter 165 | Disconnect-VIServer $vcenter -Confirm:$false 166 | 167 | #Calculate runtime 168 | $stop = get-date 169 | $runTimespan = New-TimeSpan -Start $start -End $stop 170 | 171 | Write-Output "Run $run took $($runTimespan.TotalSeconds) seconds" 172 | 173 | #Build URI for the API call 174 | $baseUri = "http://" + $dbserver + ":" + $dbserverPort + "/" 175 | $dbname = "performance" 176 | $postUri = $baseUri + "write?db=" + $dbname 177 | 178 | ####TODO: Test API access / error handling 179 | 180 | #Write data to the API 181 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($newtbl -join "`n") 182 | 183 | #Build qry to write stats about the run 184 | $pollStatQry = "pollingstat,poller=$($env:COMPUTERNAME),unit=s,type=vsanpoll,target=$($targetname) runtime=$($runtimespan.TotalSeconds),entitycount=$($vmhosts.Count) $(Get-DBTimestamp -timestamp $start)" 185 | 186 | #Write data about the run 187 | Invoke-RestMethod -Method Post -Uri $postUri -Body $pollStatQry 188 | -------------------------------------------------------------------------------- /vsan_cluster_performance_poller_withAuth.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Script for pulling performance metrics from vCenter VSAN clusters and writing to an Influx database 4 | .DESCRIPTION 5 | The script will pull performance metrics for VSAN Hosts from vCenter and writes to an Influx 6 | timeseries database. 7 | .NOTES 8 | Author: Rudi Martinsen / Intility AS 9 | Created: 07/03-2018 10 | <<<<<<< HEAD 11 | Version 0.3.0 12 | Revised: 25/06-2019 13 | Changelog: 14 | 0.3.0 -- Added support for multiple clusters 15 | ======= 16 | Version 0.3.0-beta 17 | Revised: 17/02-2019 18 | Changelog: 19 | 0.3.0-beta -- Added support for multiple clusters (not tested) 20 | >>>>>>> dc1f8f502eff2622bd72092906443782be8f2815 21 | 0.2.1 -- Fixed Read-host on password 22 | 0.2.0 -- Adding Influx auth support 23 | 0.1.2 -- Cleaned unused variables 24 | 0.1.1 -- Added backend stuff 25 | 0.1.0 -- Fork from Host poller 26 | .LINK 27 | http://www.rudimartinsen.com/2018/04/06/vsphere-performance-data-monitoring-vmware-vsan-performance/ 28 | .PARAMETER VCenter 29 | The vCenter to connect to 30 | .PARAMETER Cluster 31 | The Cluster to get stats from. If omitted all VSAN clusters in the vCenter will be fetched 32 | .PARAMETER Targetname 33 | Optional name of the target for use as a Tag in the Influx record 34 | .PARAMETER DBServer 35 | IP Address or hostname of the Influx Database server 36 | .PARAMETER DBServerPort 37 | TCP port for the DB server, Defaults to 8086 which is the default Influx port 38 | .PARAMETER DBServerUserName 39 | Username for authenticating to InfluxDB 40 | .PARAMETER DBServerUserPass 41 | Password for authenticating to InfluxDB 42 | .PARAMETER LogFile 43 | Path to the logfile to write to 44 | #> 45 | param( 46 | [Parameter(Mandatory=$true)] 47 | $VCenter, 48 | [Parameter(Mandatory=$false)] 49 | $Cluster, 50 | $Targetname, 51 | $DBServer, 52 | $DBServerPort = 8086, 53 | $DBServerUserName, 54 | [securestring] 55 | $DBServerUserPass = (Read-Host -Prompt "Please provide password" -AsSecureString), 56 | $SkipSSL = $true, 57 | $LogFile 58 | ) 59 | function Insecure-SSL { 60 | #skip ssl validation 61 | add-type @" 62 | using System.Net; 63 | using System.Security.Cryptography.X509Certificates; 64 | public class TrustAllCertsPolicy : ICertificatePolicy { 65 | public bool CheckValidationResult( 66 | ServicePoint srvPoint, X509Certificate certificate, 67 | WebRequest request, int certificateProblem) { 68 | return true; 69 | } 70 | } 71 | "@ 72 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 73 | $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' 74 | [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols 75 | } 76 | #Function to get the correct timestamp format for Influx 77 | function Get-DBTimestamp($timestamp = (get-date)){ 78 | if($timestamp -is [system.string]){ 79 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 80 | } 81 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 82 | } 83 | 84 | if(!$LogFile){ 85 | $scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 86 | $LogFile = "$scriptDir\log\vcpoll_vsan_cluster.log" 87 | } 88 | $start = Get-Date 89 | 90 | #Import PowerCLI 91 | #Import-Module VMware.VimAutomation.Core 92 | Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip:$false -Scope Session -Confirm:$false 93 | 94 | #Vstatinterval is based on the realtime performance metrics gathered from vCenter which is 20 seconds 95 | $statInterval = 300 96 | 97 | #Set targetname if omitted as a script parameter 98 | if($targetname -eq $null -or $targetname -eq ""){ 99 | if($cluster){ 100 | $targetname = $cluster 101 | } 102 | else{ 103 | $targetname = $vcenter 104 | } 105 | $Targetname = "VSAN_" + $Targetname 106 | } 107 | 108 | #Connect to vCenter 109 | try { 110 | $vc_conn = Connect-VIServer $vcenter -ErrorAction Stop -ErrorVariable vcerr 111 | $vcid = $vc_conn.InstanceUuid 112 | } 113 | catch { 114 | Write-Output "$(Get-Date) : Couldn't connect to vCenter $vCenter. Script was started at $start" | Out-File $LogFile -Append 115 | Write-Output "$(Get-Date) : Error message was: $($vcerr.message)" | Out-File $LogFile -Append 116 | break 117 | } 118 | 119 | #Get VSAN clusters 120 | if($cluster){ 121 | <<<<<<< HEAD 122 | $clusterObjects = Get-Cluster $cluster -ErrorAction Stop -ErrorVariable clustErr 123 | ======= 124 | $clusterObj = Get-Cluster $cluster | where-Object {$_.VsanEnabled -eq $true} -ErrorAction Stop -ErrorVariable clustErr 125 | >>>>>>> dc1f8f502eff2622bd72092906443782be8f2815 126 | } 127 | else{ 128 | $clusterObjects = Get-Cluster | Where-Object {$_.VsanEnabled} 129 | Write-Output "Found $($clusterObjects.count) clusters" 130 | } 131 | 132 | #Table to store data 133 | $newtbl = @() 134 | 135 | #The different metrics to fetch. Because some errors with specifying the metrics we're using the wildcard instead.. 136 | #$metricsVsan = "VMConsumption.ReadThroughput","VMConsumption.AverageReadLatency","VMConsumption.WriteThroughput","VMConsumption.AverageWriteLatency","VMConsumption.Congestion","VMConsumption.OutstandingIO" 137 | $metricsVsan = "*" 138 | 139 | <<<<<<< HEAD 140 | if(!$clusterObjects){ 141 | Write-Output "$(Get-Date) : Cluster not found. Exiting..." | Out-File $LogFile -Append 142 | break 143 | } 144 | 145 | foreach($clusterObj in $clusterObjects){ 146 | Write-Output "Processing VSAN cluster $($clusterObj.Name)" 147 | $san = $clusterObj.Name 148 | $sanid = $clusterObj.Id 149 | $type = "vsan" 150 | 151 | #Get the stats 152 | $stats = Get-VsanStat -Entity $clusterObj -Name $metricsVsan -StartTime $lapStart.AddMinutes(-5) 153 | $space = Get-VsanSpaceUsage -Cluster $clusterObj 154 | ======= 155 | if(!$clusterObj){ 156 | Write-Output "$(Get-Date) : VSAN Cluster not found. Exiting..." | Out-File $LogFile -Append 157 | break 158 | } 159 | 160 | foreach ($clust in $clusterObj){ 161 | Write-Output "Working on cluster $($clust.name)" 162 | $san = $clust.Name 163 | $sanid = $clust.Id 164 | $type = "vsan" 165 | 166 | #Get the stats 167 | $stats = Get-VsanStat -Entity $clust -Name $metricsVsan -StartTime $lapStart.AddMinutes(-5) 168 | $space = Get-VsanSpaceUsage -Cluster $clust 169 | >>>>>>> dc1f8f502eff2622bd72092906443782be8f2815 170 | 171 | foreach($stat in $stats){ 172 | 173 | $unit = $stat.Unit 174 | #We'll convert microseconds to milliseconds to correspond with "normal" vSphere stats 175 | if($unit -eq "Microseconds"){ 176 | $value = $stat.Value / 1000 177 | $unit = "ms" 178 | } 179 | else{ 180 | $value = $stat.Value 181 | } 182 | 183 | #Get correct timestamp for InfluxDB 184 | $statTimestamp = Get-DBTimestamp $stat.Time 185 | 186 | if($unit -eq "%"){ 187 | $unit="perc" 188 | } 189 | switch ($stat.Name) { 190 | "VMConsumption.ReadThroughput" { $measurement = "kB_read"; $value = ($value / 1024); $unit = "KBps" } 191 | "VMConsumption.AverageReadLatency" { $measurement = "latency_read"; } 192 | "VMConsumption.WriteThroughput" { $measurement = "kB_write"; $value = ($value / 1024); $unit = "KBps" } 193 | "VMConsumption.AverageWriteLatency" { $measurement = "latency_write"; } 194 | "VMConsumption.Congestion" {$measurement = "congestion"; $unit = "count" } 195 | "VMConsumption.OutstandingIO" { $measurement = "io_outstanding"; $unit = "count" } 196 | "VMConsumption.ReadIops" { $measurement = "io_read"; $unit = "iops" } 197 | "VMConsumption.WriteIops" { $measurement = "io_write"; $unit = "iops" } 198 | "Backend.ResyncReadLatency" { $measurement = "latency_resync_read"; } 199 | "Backend.ReadThroughput" { $measurement = "kB_read_backend"; $value = ($value / 1024); $unit = "KBps" } 200 | "Backend.AverageReadLatency" { $measurement = "latency_read_backend"; } 201 | "Backend.WriteThroughput" { $measurement = "kB_write_backend"; $value = ($value / 1024); $unit = "KBps" } 202 | "Backend.AverageWriteLatency" { $measurement = "latency_write_backend"; } 203 | "Backend.Congestion" {$measurement = "congestion_backend"; $unit = "count" } 204 | "Backend.OutstandingIO" { $measurement = "io_outstanding_backend"; $unit = "count" } 205 | "Backend.RecoveryWriteIops" { $measurement = "io_write_recovery"; $unit = "iops" } 206 | "Backend.RecoveryWriteThroughput" { $measurement = "kb_write_recovery"; $value = ($value / 1024); $unit = "KBps" } 207 | "Backend.RecoveryWriteAverageLatency" { $measurement = "latency_write_recovery"; } 208 | Default { $measurement = $null } 209 | } 210 | 211 | if($measurement -ne $null){ 212 | $newtbl += "$measurement,type=$type,san=$san,sanid=$sanid,platform=$vcenter,platformid=$vcid,unit=$unit,statinterval=$statinterval value=$Value $stattimestamp" 213 | } 214 | } 215 | 216 | if($space){ 217 | $newtbl += "vsan_diskusage,type=$type,san=$san,sanid=$sanid,platform=$vcenter,platformid=$vcid,unit=GB,statinterval=$statinterval freespace=$([int]$space.freespacegb),capacity=$([int]$space.CapacityGB),primaryvmdata=$([int]$space.PrimaryVMDataGB),vdiskusage=$([int]$space.VirtualDiskUsageGB),vsanoverhead=$([int]$space.VsanOverheadGB),vmhomeusage=$([int]$space.VMHomeUsageGB) $stattimestamp" 218 | } 219 | } 220 | #Disconnect from vCenter 221 | Disconnect-VIServer $vcenter -Confirm:$false 222 | 223 | #Calculate runtime 224 | $stop = get-date 225 | $runTimespan = New-TimeSpan -Start $start -End $stop 226 | 227 | Write-Output "Run $run took $($runTimespan.TotalSeconds) seconds" 228 | 229 | #Build URI for the API call 230 | $baseUri = "http://" + $dbserver + ":" + $dbserverPort + "/" 231 | $dbname = "performance" 232 | $postUri = $baseUri + "write?db=" + $dbname 233 | 234 | #User authentication to Influx 235 | if($SkipSSL){ 236 | Insecure-SSL 237 | } 238 | $insecurePass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($DBServerUserPass)) 239 | $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($DBServerUserName+':'+$insecurePass)) 240 | $header = @{ 241 | 'Authorization' = "Basic $auth" 242 | } 243 | 244 | ####TODO: Test API access / error handling 245 | 246 | #Write data to the API 247 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($newtbl -join "`n") -Headers $header 248 | 249 | #Build qry to write stats about the run 250 | $pollStatQry = "pollingstat,poller=$($env:COMPUTERNAME),unit=s,type=vsanpoll,target=$($targetname) runtime=$($runtimespan.TotalSeconds),entitycount=$($vmhosts.Count) $(Get-DBTimestamp -timestamp $start)" 251 | 252 | #Write data about the run 253 | Invoke-RestMethod -Method Post -Uri $postUri -Body $pollStatQry 254 | -------------------------------------------------------------------------------- /vsan_diskgroup_performance_poller.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Script for pulling performance metrics from vCenter VSAN diskgroups and writing to an Influx database 4 | .DESCRIPTION 5 | The script will pull performance metrics for VSAN Diskgroups from vCenter and writes to an Influx 6 | timeseries database. 7 | .NOTES 8 | Author: Rudi Martinsen / Intility AS 9 | Created: 02/04-2018 10 | Version 0.2.0 11 | Revised: 25/06-2019 12 | Changelog: 13 | 0.2.0 -- Support for multiple clusters 14 | 0.1.1 -- Cleaned unused variables 15 | 0.1.0 -- Fork from Host poller 16 | .LINK 17 | http://www.rudimartinsen.com/2018/04/06/vsphere-performance-data-monitoring-vmware-vsan-performance/ 18 | .PARAMETER VCenter 19 | The vCenter to connect to 20 | .PARAMETER Cluster 21 | The Cluster to get stats from. If omitted all VSAN clusters in the vCenter will be fetched 22 | .PARAMETER Targetname 23 | Optional name of the target for use as a Tag in the Influx record 24 | .PARAMETER DBServer 25 | IP Address or hostname of the Influx Database server 26 | .PARAMETER DBServerPort 27 | TCP port for the DB server, Defaults to 8086 which is the default Influx port 28 | .PARAMETER LogFile 29 | Path to the logfile to write to 30 | #> 31 | param( 32 | [Parameter(Mandatory=$true)] 33 | $VCenter, 34 | [Parameter(Mandatory=$false)] 35 | $Cluster, 36 | $Targetname, 37 | $Dbserver, 38 | $DbserverPort = 8086, 39 | $LogFile 40 | ) 41 | #Function to get the correct timestamp format for Influx 42 | function Get-DBTimestamp($timestamp = (get-date)){ 43 | if($timestamp -is [system.string]){ 44 | $timestamp = [datetime]::ParseExact($timestamp,'dd.MM.yyyy HH:mm:ss',$null) 45 | } 46 | return $([long][double]::Parse((get-date $($timestamp).ToUniversalTime() -UFormat %s)) * 1000 * 1000 * 1000) 47 | } 48 | 49 | if(!$LogFile){ 50 | $scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 51 | $LogFile = "$scriptDir\log\vcpoll_vsan_diskgroup.log" 52 | } 53 | $start = Get-Date 54 | 55 | #Import PowerCLI 56 | #Import-Module VMware.VimAutomation.Core 57 | Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip:$false -Scope Session -Confirm:$false 58 | 59 | #Vstatinterval is based on the realtime performance metrics gathered from vCenter which is 20 seconds 60 | $statInterval = 300 61 | 62 | #Set targetname if omitted as a script parameter 63 | if($targetname -eq $null -or $targetname -eq ""){ 64 | if($cluster){ 65 | $targetname = $cluster 66 | } 67 | else{ 68 | $targetname = $vcenter 69 | } 70 | $Targetname = "VSAN_" + $Targetname 71 | } 72 | 73 | #Connect to vCenter 74 | try { 75 | $vc_conn = Connect-VIServer $vcenter -ErrorAction Stop -ErrorVariable vcerr 76 | $vcid = $vc_conn.InstanceUuid 77 | } 78 | catch { 79 | Write-Output "$(Get-Date) : Couldn't connect to vCenter $vCenter. Script was started at $start" | Out-File $LogFile -Append 80 | Write-Output "$(Get-Date) : Error message was: $($vcerr.message)" | Out-File $LogFile -Append 81 | break 82 | } 83 | 84 | if($cluster){ 85 | $clusterObjects = Get-Cluster $cluster -ErrorAction Stop -ErrorVariable clustErr 86 | } 87 | else{ 88 | $clusterObjects = Get-Cluster | Where-Object {$_.VsanEnabled} 89 | Write-Output "Found $($clusterObjects.count) clusters" 90 | } 91 | 92 | if(!$clusterObjects){ 93 | Write-Output "$(Get-Date) : Cluster not found. Exiting..." | Out-File $LogFile -Append 94 | break 95 | } 96 | 97 | #Table to store data 98 | $newtbl = @() 99 | 100 | #The different metrics to fetch. Because some errors with specifying the metrics we're using the wildcard instead.. 101 | #$metricsVsan = "Performance.ReadCacheWriteIops","Performance.WriteBufferReadIops","Performance.ReadCacheReadIops","Performance.WriteBufferWriteIops","Performance.ReadThroughput","Performance.WriteThroughput","Performance.ReadCacheReadLatency","Performance.AverageReadLatency","Performance.AverageWriteLatency","Backend.ReadThroughput","Backend.AverageReadLatency","Backend.WriteThroughput","Backend.AverageWriteLatency","Backend.Congestion","Backend.OutstandingIO","Backend.RecoveryWriteIops","Backend.RecoveryWriteThroughput","Backend.RecoveryWriteAverageLatency" 102 | $metricsVsan = "*" 103 | 104 | foreach($clusterObj in $clusterObjects){ 105 | $diskGroups = Get-VsanDiskGroup -Cluster $clusterObj 106 | 107 | foreach($dg in $diskGroups){ 108 | 109 | $lapStart = get-date 110 | 111 | $vmhost = $dg.vmhost.name 112 | 113 | #Build variables for "metadata" 114 | $name = $dg.Name.Replace(" ","_") 115 | $dgType = $dg.DiskGroupType 116 | $san = $clusterObj.Name 117 | $sanid = $clusterObj.Id 118 | 119 | $type = "vsan_diskgroup" 120 | 121 | #Get the stats 122 | $stats = Get-VsanStat -Entity $dg -Name $metricsVsan -StartTime $lapStart.AddMinutes(-5) 123 | 124 | foreach($stat in $stats){ 125 | 126 | $unit = $stat.Unit 127 | #We'll convert microseconds to milliseconds to correspond with "normal" vSphere stats 128 | if($unit -eq "Microseconds"){ 129 | $value = $stat.Value / 1000 130 | $unit = "ms" 131 | } 132 | else{ 133 | $value = $stat.Value 134 | } 135 | 136 | #Get correct timestamp for InfluxDB 137 | $statTimestamp = Get-DBTimestamp $stat.Time 138 | 139 | if($unit -eq "%"){ 140 | $unit="perc" 141 | } 142 | switch ($stat.Name) { 143 | "Performance.ReadCacheWriteIops" { $measurement = "io_read"; $unit = "iops" } 144 | "Performance.WriteBufferReadIops" { $measurement = "io_write"; $unit = "iops" } 145 | "Performance.ReadCacheReadIops" { $measurement = "io_readcache_read"; $unit = "iops" } 146 | "Performance.WriteBufferWriteIops" { $measurement = "io_writebuffer_write"; $unit = "iops" } 147 | "Performance.ReadThroughput" {$measurement = "kB_read"; $value = ($value / 1024); $unit = "KBps" } 148 | "Performance.WriteThroughput" { $measurement = "kB_write"; $value = ($value / 1024); $unit = "KBps" } 149 | "Performance.AverageReadLatency" { $measurement = "latency_read"; $unit = "ms" } 150 | "Performance.AverageWriteLatency" { $measurement = "latency_write"; $unit = "ms" } 151 | "Performance.ReadCacheReadLatency" { $measurement = "latency_readcache_read"; } 152 | "Performance.ReadCacheHitRate" { $measurement = "readcache_hitrate"; } 153 | "Performance.WriteBufferFreePercentage" { $measurement = "writebuffer_free"; } 154 | "Performance.WriteBufferWriteLatency" { $measurement = "latency_writebuffer"; } 155 | "Performance.Capacity" { $measurement = "capacity"; $value = $value / 1GB; $unit = "GB" } 156 | "Performance.UsedCapacity" { $measurement = "used_capacity"; $value = $value / 1GB; $unit = "GB" } 157 | Default { $measurement = $null } 158 | } 159 | 160 | if($measurement -ne $null){ 161 | $newtbl += "$measurement,name=$name,diskgrouptype=$dgType,type=$type,san=$san,sanid=$sanid,platform=$vcenter,platformid=$vcid,unit=$unit,statinterval=$statinterval,host=$vmhost value=$Value $stattimestamp" 162 | } 163 | } 164 | 165 | #Calculate lap time 166 | $lapStop = get-date 167 | $timespan = New-TimeSpan -Start $lapStart -End $lapStop 168 | #Write-Output $timespan.TotalSeconds 169 | } 170 | 171 | } 172 | 173 | #Disconnect from vCenter 174 | Disconnect-VIServer $vcenter -Confirm:$false 175 | 176 | #Calculate runtime 177 | $stop = Get-Date 178 | $runTimespan = New-TimeSpan -Start $start -End $stop 179 | 180 | Write-Output "Run $run took $($runTimespan.TotalSeconds) seconds" 181 | 182 | #Build URI for the API call 183 | $baseUri = "http://" + $dbserver + ":" + $dbserverPort + "/" 184 | $dbname = "performance" 185 | $postUri = $baseUri + "write?db=" + $dbname 186 | 187 | ####TODO: Test API access / error handling 188 | 189 | #Write data to the API 190 | Invoke-RestMethod -Method Post -Uri $postUri -Body ($newtbl -join "`n") 191 | 192 | #Build qry to write stats about the run 193 | $pollStatQry = "pollingstat,poller=$($env:COMPUTERNAME),unit=s,type=vsanpoll,target=$($targetname) runtime=$($runtimespan.TotalSeconds),entitycount=$($vmhosts.Count) $(Get-DBTimestamp -timestamp $start)" 194 | 195 | #Write data about the run 196 | Invoke-RestMethod -Method Post -Uri $postUri -Body $pollStatQry 197 | 198 | --------------------------------------------------------------------------------