├── README.md └── zfs-pool-metrics-influxdb-v2_rev1.json /README.md: -------------------------------------------------------------------------------- 1 | # grafana-zfs-metrics 2 | 3 | ![granfana-zfs-metrics-overview-1](https://user-images.githubusercontent.com/7524620/200136236-8f6e7590-dfd9-41f3-b970-3dc7e2f347e6.jpg) 4 | 5 | A dashboard of metrics produced by the `zpool_influxdb` utility. You can read the [manpage](https://openzfs.github.io/openzfs-docs/man/8/zpool_influxdb.8.html) and check out the tool's [GitHub page](https://github.com/richardelling/zpool_influxdb) for more info on what it does and how it works. 6 | 7 | Features include pool activity, status, queues, and individual/aggregate IO sizes. 8 | 9 | This is a port of [Scott MacDonald's influxQL / v1 dashboard](https://grafana.com/grafana/dashboards/15362-zfs-pool-metrics/). This updated dashboard supports InfluxDBv2 and is written in [flux](https://docs.influxdata.com/influxdb/cloud/reference/syntax/flux/flux-vs-influxql/). 10 | 11 | This dahboard is [posted on Grafana's dashboards section](https://grafana.com/grafana/dashboards/17350-zfs-pool-metrics-influxdb-v2/). If you have time, I'd appreciate a rating and review there! 12 | 13 | ## Configuration 14 | 15 | This uses Telegraf with the `zpool_influxdb` collector. A [detailed setup guide can be found over at the du.nkel.dev blog](https://du.nkel.dev/blog/2021-05-05_proxmox_influxdb/), but a simple minimal config is: 16 | 17 | ``` 18 | # Read metrics from zpool_influxdb 19 | [[inputs.exec]] 20 | # CHECK PATH! Default installation location for zpool_influxdb command may be elsewhere 21 | commands = ["/usr/lib/zfs-linux/zpool_influxdb"] 22 | timeout = "5s" 23 | data_format = "influx" 24 | ``` 25 | 26 | Thanks to [@CalebFenton](https://github.com/CalebFenton) for noting `data_format` is needed too. 27 | 28 | ## Porting Details 29 | 30 | If you're interested in how this was ported from influxQL to flux, I have a series of posts over on my blog on the motivation and process: [Part 1](https://blog.roberthallam.org/2022/09/monitoring-zfs-latencies-in-proxmox-part-1/), [Part 2](https://blog.roberthallam.org/2022/09/monitoring-zfs-with-influxdb-grafana-graph-time-part-2/), [Part 3](https://blog.roberthallam.org/2022/09/monitoring-zfs-with-influxdb-grafana-adapting-panels-part-3/), [Part 4](https://blog.roberthallam.org/2022/09/monitoring-zfs-with-influxdb-grafana-tidying-up-part-4/), [Part 5](https://blog.roberthallam.org/2022/09/monitoring-zfs-with-influxdb-grafana-publishing-and-reflection-part-5/). 31 | -------------------------------------------------------------------------------- /zfs-pool-metrics-influxdb-v2_rev1.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_INFLUXDB", 5 | "label": "InfluxDBv2", 6 | "description": "Uses zpool_influxdb as a data source", 7 | "type": "datasource", 8 | "pluginId": "influxdb", 9 | "pluginName": "InfluxDB" 10 | } 11 | ], 12 | "__elements": {}, 13 | "__requires": [ 14 | { 15 | "type": "grafana", 16 | "id": "grafana", 17 | "name": "Grafana", 18 | "version": "9.0.7" 19 | }, 20 | { 21 | "type": "panel", 22 | "id": "heatmap", 23 | "name": "Heatmap", 24 | "version": "" 25 | }, 26 | { 27 | "type": "datasource", 28 | "id": "influxdb", 29 | "name": "InfluxDB", 30 | "version": "1.0.0" 31 | }, 32 | { 33 | "type": "panel", 34 | "id": "stat", 35 | "name": "Stat", 36 | "version": "" 37 | }, 38 | { 39 | "type": "panel", 40 | "id": "timeseries", 41 | "name": "Time series", 42 | "version": "" 43 | } 44 | ], 45 | "annotations": { 46 | "list": [ 47 | { 48 | "$$hashKey": "object:1627", 49 | "builtIn": 1, 50 | "datasource": { 51 | "type": "datasource", 52 | "uid": "grafana" 53 | }, 54 | "enable": true, 55 | "hide": true, 56 | "iconColor": "rgba(0, 211, 255, 1)", 57 | "name": "Annotations & Alerts", 58 | "target": { 59 | "limit": 100, 60 | "matchAny": false, 61 | "tags": [], 62 | "type": "dashboard" 63 | }, 64 | "type": "dashboard" 65 | } 66 | ] 67 | }, 68 | "description": "Dashboard of metrics generated by Richard Elling's cool \"zpool_influxdb\" utility (included in OpenZFS), version for InfluxDB v2.", 69 | "editable": true, 70 | "fiscalYearStartMonth": 0, 71 | "gnetId": 17350, 72 | "graphTooltip": 1, 73 | "id": null, 74 | "links": [], 75 | "liveNow": false, 76 | "panels": [ 77 | { 78 | "collapsed": false, 79 | "gridPos": { 80 | "h": 1, 81 | "w": 24, 82 | "x": 0, 83 | "y": 0 84 | }, 85 | "id": 87, 86 | "panels": [], 87 | "title": "Overview for $hostname $poolname", 88 | "type": "row" 89 | }, 90 | { 91 | "datasource": { 92 | "type": "influxdb", 93 | "uid": "${DS_INFLUXDB}" 94 | }, 95 | "fieldConfig": { 96 | "defaults": { 97 | "color": { 98 | "mode": "palette-classic" 99 | }, 100 | "custom": { 101 | "axisLabel": "", 102 | "axisPlacement": "auto", 103 | "barAlignment": 0, 104 | "drawStyle": "line", 105 | "fillOpacity": 0, 106 | "gradientMode": "none", 107 | "hideFrom": { 108 | "legend": false, 109 | "tooltip": false, 110 | "viz": false 111 | }, 112 | "lineInterpolation": "smooth", 113 | "lineWidth": 1, 114 | "pointSize": 5, 115 | "scaleDistribution": { 116 | "type": "linear" 117 | }, 118 | "showPoints": "never", 119 | "spanNulls": false, 120 | "stacking": { 121 | "group": "A", 122 | "mode": "none" 123 | }, 124 | "thresholdsStyle": { 125 | "mode": "off" 126 | } 127 | }, 128 | "mappings": [], 129 | "thresholds": { 130 | "mode": "absolute", 131 | "steps": [ 132 | { 133 | "color": "green", 134 | "value": null 135 | }, 136 | { 137 | "color": "red", 138 | "value": 80 139 | } 140 | ] 141 | }, 142 | "unit": "Bps" 143 | }, 144 | "overrides": [ 145 | { 146 | "matcher": { 147 | "id": "byRegexp", 148 | "options": "/Ops/" 149 | }, 150 | "properties": [ 151 | { 152 | "id": "custom.axisPlacement", 153 | "value": "right" 154 | }, 155 | { 156 | "id": "unit", 157 | "value": "iops" 158 | } 159 | ] 160 | } 161 | ] 162 | }, 163 | "gridPos": { 164 | "h": 8, 165 | "w": 9, 166 | "x": 0, 167 | "y": 1 168 | }, 169 | "id": 27, 170 | "options": { 171 | "legend": { 172 | "calcs": [], 173 | "displayMode": "list", 174 | "placement": "bottom" 175 | }, 176 | "tooltip": { 177 | "mode": "multi", 178 | "sort": "none" 179 | } 180 | }, 181 | "pluginVersion": "8.2.2", 182 | "targets": [ 183 | { 184 | "alias": "$col", 185 | "datasource": { 186 | "type": "influxdb", 187 | "uid": "${DS_INFLUXDB}" 188 | }, 189 | "groupBy": [ 190 | { 191 | "params": [ 192 | "$__interval" 193 | ], 194 | "type": "time" 195 | }, 196 | { 197 | "params": [ 198 | "none" 199 | ], 200 | "type": "fill" 201 | } 202 | ], 203 | "measurement": "zpool_stats", 204 | "orderByTime": "ASC", 205 | "policy": "default", 206 | "query": "import \"strings\"\n\nKEEPCOLS = ${TSCOLS}\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"read_bytes\" or r[\"_field\"] == \"write_bytes\" or r[\"_field\"] == \"read_ops\" or r[\"_field\"] == \"write_ops\")\n |> derivative(nonNegative: true)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\n NamedData = RawData\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"])}))\n |> keep(columns: KEEPCOLS)\n |> yield()", 207 | "refId": "A", 208 | "resultFormat": "time_series", 209 | "select": [ 210 | [ 211 | { 212 | "params": [ 213 | "write_bytes" 214 | ], 215 | "type": "field" 216 | }, 217 | { 218 | "params": [], 219 | "type": "last" 220 | }, 221 | { 222 | "params": [ 223 | "1s" 224 | ], 225 | "type": "non_negative_derivative" 226 | }, 227 | { 228 | "params": [ 229 | "Write Bytes" 230 | ], 231 | "type": "alias" 232 | } 233 | ], 234 | [ 235 | { 236 | "params": [ 237 | "read_bytes" 238 | ], 239 | "type": "field" 240 | }, 241 | { 242 | "params": [], 243 | "type": "last" 244 | }, 245 | { 246 | "params": [ 247 | "1s" 248 | ], 249 | "type": "non_negative_derivative" 250 | }, 251 | { 252 | "params": [ 253 | "Read Bytes" 254 | ], 255 | "type": "alias" 256 | } 257 | ], 258 | [ 259 | { 260 | "params": [ 261 | "write_ops" 262 | ], 263 | "type": "field" 264 | }, 265 | { 266 | "params": [], 267 | "type": "last" 268 | }, 269 | { 270 | "params": [ 271 | "1s" 272 | ], 273 | "type": "non_negative_derivative" 274 | }, 275 | { 276 | "params": [ 277 | "Write Ops" 278 | ], 279 | "type": "alias" 280 | } 281 | ], 282 | [ 283 | { 284 | "params": [ 285 | "read_ops" 286 | ], 287 | "type": "field" 288 | }, 289 | { 290 | "params": [], 291 | "type": "last" 292 | }, 293 | { 294 | "params": [ 295 | "1s" 296 | ], 297 | "type": "non_negative_derivative" 298 | }, 299 | { 300 | "params": [ 301 | "Read Ops" 302 | ], 303 | "type": "alias" 304 | } 305 | ] 306 | ], 307 | "tags": [ 308 | { 309 | "key": "host", 310 | "operator": "=~", 311 | "value": "/^$hostname$/" 312 | }, 313 | { 314 | "condition": "AND", 315 | "key": "name", 316 | "operator": "=~", 317 | "value": "/^$poolname$/" 318 | } 319 | ] 320 | } 321 | ], 322 | "title": "Pool Activity ($poolname)", 323 | "type": "timeseries" 324 | }, 325 | { 326 | "datasource": { 327 | "type": "influxdb", 328 | "uid": "${DS_INFLUXDB}" 329 | }, 330 | "fieldConfig": { 331 | "defaults": { 332 | "color": { 333 | "mode": "thresholds" 334 | }, 335 | "mappings": [], 336 | "thresholds": { 337 | "mode": "absolute", 338 | "steps": [ 339 | { 340 | "color": "semi-dark-blue", 341 | "value": null 342 | } 343 | ] 344 | } 345 | }, 346 | "overrides": [] 347 | }, 348 | "gridPos": { 349 | "h": 2, 350 | "w": 5, 351 | "x": 9, 352 | "y": 1 353 | }, 354 | "id": 32, 355 | "options": { 356 | "colorMode": "background", 357 | "graphMode": "area", 358 | "justifyMode": "auto", 359 | "orientation": "auto", 360 | "reduceOptions": { 361 | "calcs": [ 362 | "lastNotNull" 363 | ], 364 | "fields": "/^state$/", 365 | "values": false 366 | }, 367 | "text": {}, 368 | "textMode": "value" 369 | }, 370 | "pluginVersion": "9.0.7", 371 | "targets": [ 372 | { 373 | "alias": "$tag_state", 374 | "datasource": { 375 | "type": "influxdb", 376 | "uid": "${DS_INFLUXDB}" 377 | }, 378 | "groupBy": [ 379 | { 380 | "params": [ 381 | "state" 382 | ], 383 | "type": "tag" 384 | }, 385 | { 386 | "params": [ 387 | "state" 388 | ], 389 | "type": "tag" 390 | } 391 | ], 392 | "hide": false, 393 | "measurement": "zpool_stats", 394 | "orderByTime": "ASC", 395 | "policy": "default", 396 | "query": "import \"strings\"\n\nKEEPCOLS = [\"_field\", \"_time\", \"_value\", \"state\"]\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"size\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> last()\n\n NamedData = RawData\n //|> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"]), state: r[\"state\"]}))\n |> map(fn: (r) => ({r: r._time, c: \"state\", v: r[\"state\"]}))\n |> pivot(rowKey: [\"r\"], columnKey: [\"c\"], valueColumn: \"v\")\n //|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n //|> keep(columns: KEEPCOLS)\n |> yield(name: \"mean\")\n\n", 397 | "refId": "B", 398 | "resultFormat": "table", 399 | "select": [ 400 | [ 401 | { 402 | "params": [ 403 | "size" 404 | ], 405 | "type": "field" 406 | } 407 | ] 408 | ], 409 | "tags": [ 410 | { 411 | "key": "host", 412 | "operator": "=~", 413 | "value": "/^$hostname$/" 414 | }, 415 | { 416 | "condition": "AND", 417 | "key": "name", 418 | "operator": "=~", 419 | "value": "/^$poolname$/" 420 | } 421 | ] 422 | } 423 | ], 424 | "title": "$poolname Pool Status", 425 | "transparent": true, 426 | "type": "stat" 427 | }, 428 | { 429 | "datasource": { 430 | "type": "influxdb", 431 | "uid": "${DS_INFLUXDB}" 432 | }, 433 | "fieldConfig": { 434 | "defaults": { 435 | "color": { 436 | "mode": "palette-classic" 437 | }, 438 | "custom": { 439 | "axisLabel": "depth", 440 | "axisPlacement": "auto", 441 | "barAlignment": 0, 442 | "drawStyle": "line", 443 | "fillOpacity": 50, 444 | "gradientMode": "opacity", 445 | "hideFrom": { 446 | "legend": false, 447 | "tooltip": false, 448 | "viz": false 449 | }, 450 | "lineInterpolation": "stepAfter", 451 | "lineWidth": 1, 452 | "pointSize": 5, 453 | "scaleDistribution": { 454 | "type": "linear" 455 | }, 456 | "showPoints": "never", 457 | "spanNulls": false, 458 | "stacking": { 459 | "group": "A", 460 | "mode": "none" 461 | }, 462 | "thresholdsStyle": { 463 | "mode": "off" 464 | } 465 | }, 466 | "mappings": [], 467 | "thresholds": { 468 | "mode": "absolute", 469 | "steps": [ 470 | { 471 | "color": "green", 472 | "value": null 473 | }, 474 | { 475 | "color": "red", 476 | "value": 80 477 | } 478 | ] 479 | }, 480 | "unit": "short" 481 | }, 482 | "overrides": [] 483 | }, 484 | "gridPos": { 485 | "h": 7, 486 | "w": 10, 487 | "x": 14, 488 | "y": 1 489 | }, 490 | "id": 29, 491 | "options": { 492 | "legend": { 493 | "calcs": [], 494 | "displayMode": "list", 495 | "placement": "bottom" 496 | }, 497 | "tooltip": { 498 | "mode": "multi", 499 | "sort": "none" 500 | } 501 | }, 502 | "targets": [ 503 | { 504 | "alias": "$col", 505 | "datasource": { 506 | "type": "influxdb", 507 | "uid": "${DS_INFLUXDB}" 508 | }, 509 | "groupBy": [ 510 | { 511 | "params": [ 512 | "$__interval" 513 | ], 514 | "type": "time" 515 | }, 516 | { 517 | "params": [ 518 | "none" 519 | ], 520 | "type": "fill" 521 | } 522 | ], 523 | "measurement": "zpool_vdev_stats", 524 | "orderByTime": "ASC", 525 | "policy": "default", 526 | "query": "import \"strings\"\n\nKEEPCOLS = ${TSCOLS}\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_vdev_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"sync_w_active_queue\" or r[\"_field\"] == \"sync_r_active_queue\" or r[\"_field\"] == \"async_scrub_active_queue\" or r[\"_field\"] == \"async_w_active_queue\" or r[\"_field\"] == \"async_r_active_queue\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\n NamedData = RawData\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"])}))\n |> keep(columns: KEEPCOLS)\n |> yield()", 527 | "refId": "A", 528 | "resultFormat": "time_series", 529 | "select": [ 530 | [ 531 | { 532 | "params": [ 533 | "sync_w_active_queue" 534 | ], 535 | "type": "field" 536 | }, 537 | { 538 | "params": [], 539 | "type": "max" 540 | }, 541 | { 542 | "params": [ 543 | "Sync Write" 544 | ], 545 | "type": "alias" 546 | } 547 | ], 548 | [ 549 | { 550 | "params": [ 551 | "sync_r_active_queue" 552 | ], 553 | "type": "field" 554 | }, 555 | { 556 | "params": [], 557 | "type": "max" 558 | }, 559 | { 560 | "params": [ 561 | "Sync Read" 562 | ], 563 | "type": "alias" 564 | } 565 | ], 566 | [ 567 | { 568 | "params": [ 569 | "async_scrub_active_queue" 570 | ], 571 | "type": "field" 572 | }, 573 | { 574 | "params": [], 575 | "type": "max" 576 | }, 577 | { 578 | "params": [ 579 | "Async Scrub" 580 | ], 581 | "type": "alias" 582 | } 583 | ], 584 | [ 585 | { 586 | "params": [ 587 | "async_w_active_queue" 588 | ], 589 | "type": "field" 590 | }, 591 | { 592 | "params": [], 593 | "type": "max" 594 | }, 595 | { 596 | "params": [ 597 | "Async Write" 598 | ], 599 | "type": "alias" 600 | } 601 | ], 602 | [ 603 | { 604 | "params": [ 605 | "async_r_active_queue" 606 | ], 607 | "type": "field" 608 | }, 609 | { 610 | "params": [], 611 | "type": "max" 612 | }, 613 | { 614 | "params": [ 615 | "Async Read" 616 | ], 617 | "type": "alias" 618 | } 619 | ] 620 | ], 621 | "tags": [ 622 | { 623 | "key": "host", 624 | "operator": "=~", 625 | "value": "/^$hostname$/" 626 | }, 627 | { 628 | "condition": "AND", 629 | "key": "name", 630 | "operator": "=~", 631 | "value": "/^$poolname$/" 632 | } 633 | ] 634 | } 635 | ], 636 | "title": "vdev I/O Active Queues ($poolname)", 637 | "type": "timeseries" 638 | }, 639 | { 640 | "datasource": { 641 | "type": "influxdb", 642 | "uid": "${DS_INFLUXDB}" 643 | }, 644 | "fieldConfig": { 645 | "defaults": { 646 | "color": { 647 | "mode": "thresholds" 648 | }, 649 | "mappings": [], 650 | "thresholds": { 651 | "mode": "absolute", 652 | "steps": [ 653 | { 654 | "color": "semi-dark-red", 655 | "value": null 656 | } 657 | ] 658 | }, 659 | "unit": "short" 660 | }, 661 | "overrides": [ 662 | { 663 | "matcher": { 664 | "id": "byName", 665 | "options": "Fragmentation" 666 | }, 667 | "properties": [ 668 | { 669 | "id": "unit", 670 | "value": "percent" 671 | } 672 | ] 673 | } 674 | ] 675 | }, 676 | "gridPos": { 677 | "h": 5, 678 | "w": 5, 679 | "x": 9, 680 | "y": 3 681 | }, 682 | "id": 57, 683 | "options": { 684 | "colorMode": "value", 685 | "graphMode": "area", 686 | "justifyMode": "center", 687 | "orientation": "auto", 688 | "reduceOptions": { 689 | "calcs": [ 690 | "lastNotNull" 691 | ], 692 | "fields": "", 693 | "values": false 694 | }, 695 | "text": {}, 696 | "textMode": "value_and_name" 697 | }, 698 | "pluginVersion": "9.0.7", 699 | "targets": [ 700 | { 701 | "alias": "$col", 702 | "datasource": { 703 | "type": "influxdb", 704 | "uid": "${DS_INFLUXDB}" 705 | }, 706 | "groupBy": [ 707 | { 708 | "params": [ 709 | "$__interval" 710 | ], 711 | "type": "time" 712 | }, 713 | { 714 | "params": [ 715 | "null" 716 | ], 717 | "type": "fill" 718 | } 719 | ], 720 | "measurement": "zpool_stats", 721 | "orderByTime": "ASC", 722 | "policy": "default", 723 | "query": "import \"strings\"\n\nKEEPCOLS = ${TSCOLS}\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"read_errors\" or r[\"_field\"] == \"write_errors\" or r[\"_field\"] == \"fragmentation\" or r[\"_field\"] == \"checksum_errors\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> last()\n \n\n NamedData = RawData\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"])}))\n |> keep(columns: KEEPCOLS)\n |> yield()", 724 | "refId": "A", 725 | "resultFormat": "time_series", 726 | "select": [ 727 | [ 728 | { 729 | "params": [ 730 | "read_errors" 731 | ], 732 | "type": "field" 733 | }, 734 | { 735 | "params": [], 736 | "type": "last" 737 | }, 738 | { 739 | "params": [ 740 | "Read Errors" 741 | ], 742 | "type": "alias" 743 | } 744 | ], 745 | [ 746 | { 747 | "params": [ 748 | "write_errors" 749 | ], 750 | "type": "field" 751 | }, 752 | { 753 | "params": [], 754 | "type": "last" 755 | }, 756 | { 757 | "params": [ 758 | "Write Errors" 759 | ], 760 | "type": "alias" 761 | } 762 | ], 763 | [ 764 | { 765 | "params": [ 766 | "fragmentation" 767 | ], 768 | "type": "field" 769 | }, 770 | { 771 | "params": [], 772 | "type": "last" 773 | }, 774 | { 775 | "params": [ 776 | "Fragmentation" 777 | ], 778 | "type": "alias" 779 | } 780 | ], 781 | [ 782 | { 783 | "params": [ 784 | "checksum_errors" 785 | ], 786 | "type": "field" 787 | }, 788 | { 789 | "params": [], 790 | "type": "last" 791 | }, 792 | { 793 | "params": [ 794 | "Checksum Errors" 795 | ], 796 | "type": "alias" 797 | } 798 | ] 799 | ], 800 | "tags": [ 801 | { 802 | "key": "host", 803 | "operator": "=~", 804 | "value": "/^$hostname$/" 805 | }, 806 | { 807 | "condition": "AND", 808 | "key": "name", 809 | "operator": "=~", 810 | "value": "/^$poolname$/" 811 | }, 812 | { 813 | "condition": "AND", 814 | "key": "vdev", 815 | "operator": "=", 816 | "value": "root" 817 | } 818 | ] 819 | } 820 | ], 821 | "type": "stat" 822 | }, 823 | { 824 | "datasource": { 825 | "type": "influxdb", 826 | "uid": "${DS_INFLUXDB}" 827 | }, 828 | "fieldConfig": { 829 | "defaults": { 830 | "color": { 831 | "mode": "thresholds" 832 | }, 833 | "mappings": [], 834 | "thresholds": { 835 | "mode": "absolute", 836 | "steps": [ 837 | { 838 | "color": "semi-dark-blue", 839 | "value": null 840 | } 841 | ] 842 | }, 843 | "unit": "decbytes" 844 | }, 845 | "overrides": [ 846 | { 847 | "matcher": { 848 | "id": "byName", 849 | "options": "Fragmentation" 850 | }, 851 | "properties": [ 852 | { 853 | "id": "unit", 854 | "value": "percent" 855 | } 856 | ] 857 | }, 858 | { 859 | "matcher": { 860 | "id": "byName", 861 | "options": "Checksum Errors" 862 | }, 863 | "properties": [ 864 | { 865 | "id": "unit", 866 | "value": "short" 867 | } 868 | ] 869 | } 870 | ] 871 | }, 872 | "gridPos": { 873 | "h": 7, 874 | "w": 5, 875 | "x": 9, 876 | "y": 8 877 | }, 878 | "id": 55, 879 | "options": { 880 | "colorMode": "background", 881 | "graphMode": "none", 882 | "justifyMode": "auto", 883 | "orientation": "auto", 884 | "reduceOptions": { 885 | "calcs": [ 886 | "lastNotNull" 887 | ], 888 | "fields": "", 889 | "values": false 890 | }, 891 | "text": {}, 892 | "textMode": "value_and_name" 893 | }, 894 | "pluginVersion": "9.0.7", 895 | "targets": [ 896 | { 897 | "alias": "$col", 898 | "datasource": { 899 | "type": "influxdb", 900 | "uid": "${DS_INFLUXDB}" 901 | }, 902 | "groupBy": [ 903 | { 904 | "params": [ 905 | "$__interval" 906 | ], 907 | "type": "time" 908 | }, 909 | { 910 | "params": [ 911 | "null" 912 | ], 913 | "type": "fill" 914 | } 915 | ], 916 | "measurement": "zpool_stats", 917 | "orderByTime": "ASC", 918 | "policy": "default", 919 | "query": "import \"strings\"\n\nKEEPCOLS = ${TSCOLS}\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"alloc\" or r[\"_field\"] == \"free\" or r[\"_field\"] == \"size\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> last()\n\n NamedData = RawData\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"])}))\n |> keep(columns: KEEPCOLS)\n |> yield()", 920 | "refId": "A", 921 | "resultFormat": "time_series", 922 | "select": [ 923 | [ 924 | { 925 | "params": [ 926 | "alloc" 927 | ], 928 | "type": "field" 929 | }, 930 | { 931 | "params": [], 932 | "type": "last" 933 | }, 934 | { 935 | "params": [ 936 | "Alloc" 937 | ], 938 | "type": "alias" 939 | } 940 | ], 941 | [ 942 | { 943 | "params": [ 944 | "free" 945 | ], 946 | "type": "field" 947 | }, 948 | { 949 | "params": [], 950 | "type": "last" 951 | }, 952 | { 953 | "params": [ 954 | "Free" 955 | ], 956 | "type": "alias" 957 | } 958 | ], 959 | [ 960 | { 961 | "params": [ 962 | "size" 963 | ], 964 | "type": "field" 965 | }, 966 | { 967 | "params": [], 968 | "type": "last" 969 | }, 970 | { 971 | "params": [ 972 | "Size" 973 | ], 974 | "type": "alias" 975 | } 976 | ] 977 | ], 978 | "tags": [ 979 | { 980 | "key": "host", 981 | "operator": "=~", 982 | "value": "/^$hostname$/" 983 | }, 984 | { 985 | "condition": "AND", 986 | "key": "name", 987 | "operator": "=~", 988 | "value": "/^$poolname$/" 989 | }, 990 | { 991 | "condition": "AND", 992 | "key": "vdev", 993 | "operator": "=", 994 | "value": "root" 995 | } 996 | ] 997 | } 998 | ], 999 | "type": "stat" 1000 | }, 1001 | { 1002 | "datasource": { 1003 | "type": "influxdb", 1004 | "uid": "${DS_INFLUXDB}" 1005 | }, 1006 | "fieldConfig": { 1007 | "defaults": { 1008 | "color": { 1009 | "mode": "palette-classic" 1010 | }, 1011 | "custom": { 1012 | "axisLabel": "depth", 1013 | "axisPlacement": "auto", 1014 | "barAlignment": 0, 1015 | "drawStyle": "line", 1016 | "fillOpacity": 0, 1017 | "gradientMode": "none", 1018 | "hideFrom": { 1019 | "legend": false, 1020 | "tooltip": false, 1021 | "viz": false 1022 | }, 1023 | "lineInterpolation": "stepAfter", 1024 | "lineWidth": 1, 1025 | "pointSize": 5, 1026 | "scaleDistribution": { 1027 | "type": "linear" 1028 | }, 1029 | "showPoints": "never", 1030 | "spanNulls": false, 1031 | "stacking": { 1032 | "group": "A", 1033 | "mode": "none" 1034 | }, 1035 | "thresholdsStyle": { 1036 | "mode": "off" 1037 | } 1038 | }, 1039 | "mappings": [], 1040 | "thresholds": { 1041 | "mode": "absolute", 1042 | "steps": [ 1043 | { 1044 | "color": "green", 1045 | "value": null 1046 | }, 1047 | { 1048 | "color": "red", 1049 | "value": 80 1050 | } 1051 | ] 1052 | }, 1053 | "unit": "short" 1054 | }, 1055 | "overrides": [] 1056 | }, 1057 | "gridPos": { 1058 | "h": 7, 1059 | "w": 10, 1060 | "x": 14, 1061 | "y": 8 1062 | }, 1063 | "id": 30, 1064 | "options": { 1065 | "legend": { 1066 | "calcs": [], 1067 | "displayMode": "list", 1068 | "placement": "bottom" 1069 | }, 1070 | "tooltip": { 1071 | "mode": "multi", 1072 | "sort": "none" 1073 | } 1074 | }, 1075 | "targets": [ 1076 | { 1077 | "alias": "$col", 1078 | "datasource": { 1079 | "type": "influxdb", 1080 | "uid": "${DS_INFLUXDB}" 1081 | }, 1082 | "groupBy": [ 1083 | { 1084 | "params": [ 1085 | "$__interval" 1086 | ], 1087 | "type": "time" 1088 | }, 1089 | { 1090 | "params": [ 1091 | "none" 1092 | ], 1093 | "type": "fill" 1094 | } 1095 | ], 1096 | "measurement": "zpool_vdev_stats", 1097 | "orderByTime": "ASC", 1098 | "policy": "default", 1099 | "query": "import \"strings\"\n\nKEEPCOLS = ${TSCOLS}\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_vdev_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"sync_w_pend_queue\" or r[\"_field\"] == \"sync_r_pend_queue\" or r[\"_field\"] == \"async_scrub_pend_queue\" or r[\"_field\"] == \"async_w_pend_queue\" or r[\"_field\"] == \"async_r_pend_queue\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\n NamedData = RawData\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"])}))\n |> keep(columns: KEEPCOLS)\n |> yield()", 1100 | "refId": "A", 1101 | "resultFormat": "time_series", 1102 | "select": [ 1103 | [ 1104 | { 1105 | "params": [ 1106 | "sync_w_pend_queue" 1107 | ], 1108 | "type": "field" 1109 | }, 1110 | { 1111 | "params": [], 1112 | "type": "max" 1113 | }, 1114 | { 1115 | "params": [ 1116 | "Sync Write" 1117 | ], 1118 | "type": "alias" 1119 | } 1120 | ], 1121 | [ 1122 | { 1123 | "params": [ 1124 | "sync_r_pend_queue" 1125 | ], 1126 | "type": "field" 1127 | }, 1128 | { 1129 | "params": [], 1130 | "type": "max" 1131 | }, 1132 | { 1133 | "params": [ 1134 | "Sync Read" 1135 | ], 1136 | "type": "alias" 1137 | } 1138 | ], 1139 | [ 1140 | { 1141 | "params": [ 1142 | "async_scrub_pend_queue" 1143 | ], 1144 | "type": "field" 1145 | }, 1146 | { 1147 | "params": [], 1148 | "type": "max" 1149 | }, 1150 | { 1151 | "params": [ 1152 | "Async Scrub" 1153 | ], 1154 | "type": "alias" 1155 | } 1156 | ], 1157 | [ 1158 | { 1159 | "params": [ 1160 | "async_w_pend_queue" 1161 | ], 1162 | "type": "field" 1163 | }, 1164 | { 1165 | "params": [], 1166 | "type": "max" 1167 | }, 1168 | { 1169 | "params": [ 1170 | "Async Write" 1171 | ], 1172 | "type": "alias" 1173 | } 1174 | ], 1175 | [ 1176 | { 1177 | "params": [ 1178 | "async_r_pend_queue" 1179 | ], 1180 | "type": "field" 1181 | }, 1182 | { 1183 | "params": [], 1184 | "type": "max" 1185 | }, 1186 | { 1187 | "params": [ 1188 | "Async Read" 1189 | ], 1190 | "type": "alias" 1191 | } 1192 | ] 1193 | ], 1194 | "tags": [ 1195 | { 1196 | "key": "host", 1197 | "operator": "=~", 1198 | "value": "/^$hostname$/" 1199 | }, 1200 | { 1201 | "condition": "AND", 1202 | "key": "name", 1203 | "operator": "=~", 1204 | "value": "/^$poolname$/" 1205 | } 1206 | ] 1207 | } 1208 | ], 1209 | "title": "vdev I/O Pending Queues ($poolname)", 1210 | "type": "timeseries" 1211 | }, 1212 | { 1213 | "datasource": { 1214 | "type": "influxdb", 1215 | "uid": "${DS_INFLUXDB}" 1216 | }, 1217 | "fieldConfig": { 1218 | "defaults": { 1219 | "color": { 1220 | "mode": "palette-classic" 1221 | }, 1222 | "custom": { 1223 | "axisLabel": "", 1224 | "axisPlacement": "auto", 1225 | "barAlignment": 0, 1226 | "drawStyle": "line", 1227 | "fillOpacity": 0, 1228 | "gradientMode": "none", 1229 | "hideFrom": { 1230 | "legend": false, 1231 | "tooltip": false, 1232 | "viz": false 1233 | }, 1234 | "lineInterpolation": "linear", 1235 | "lineWidth": 1, 1236 | "pointSize": 5, 1237 | "scaleDistribution": { 1238 | "type": "linear" 1239 | }, 1240 | "showPoints": "never", 1241 | "spanNulls": false, 1242 | "stacking": { 1243 | "group": "A", 1244 | "mode": "none" 1245 | }, 1246 | "thresholdsStyle": { 1247 | "mode": "off" 1248 | } 1249 | }, 1250 | "mappings": [], 1251 | "min": 0, 1252 | "thresholds": { 1253 | "mode": "absolute", 1254 | "steps": [ 1255 | { 1256 | "color": "green", 1257 | "value": null 1258 | }, 1259 | { 1260 | "color": "red", 1261 | "value": 80 1262 | } 1263 | ] 1264 | }, 1265 | "unit": "decbytes" 1266 | }, 1267 | "overrides": [ 1268 | { 1269 | "matcher": { 1270 | "id": "byName", 1271 | "options": "Fragmentation" 1272 | }, 1273 | "properties": [ 1274 | { 1275 | "id": "custom.axisPlacement", 1276 | "value": "right" 1277 | }, 1278 | { 1279 | "id": "unit", 1280 | "value": "percent" 1281 | } 1282 | ] 1283 | } 1284 | ] 1285 | }, 1286 | "gridPos": { 1287 | "h": 6, 1288 | "w": 9, 1289 | "x": 0, 1290 | "y": 9 1291 | }, 1292 | "id": 25, 1293 | "options": { 1294 | "legend": { 1295 | "calcs": [], 1296 | "displayMode": "list", 1297 | "placement": "bottom" 1298 | }, 1299 | "tooltip": { 1300 | "mode": "multi", 1301 | "sort": "none" 1302 | } 1303 | }, 1304 | "targets": [ 1305 | { 1306 | "alias": "$col", 1307 | "datasource": { 1308 | "type": "influxdb", 1309 | "uid": "${DS_INFLUXDB}" 1310 | }, 1311 | "groupBy": [ 1312 | { 1313 | "params": [ 1314 | "$__interval" 1315 | ], 1316 | "type": "time" 1317 | }, 1318 | { 1319 | "params": [ 1320 | "none" 1321 | ], 1322 | "type": "fill" 1323 | } 1324 | ], 1325 | "measurement": "zpool_stats", 1326 | "orderByTime": "ASC", 1327 | "policy": "default", 1328 | "query": "import \"strings\"\n\nKEEPCOLS = ${TSCOLS}\n\nniceify_legend = ${NICEIFYLEG} // function defined as variable- changes underscores to spaces + title-cases\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"alloc\" or r[\"_field\"] == \"size\" or r[\"_field\"] == \"free\" or r[\"_field\"] == \"fragmentation\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\n NamedData = RawData\n |> map(fn: (r) => ({_value:r._value, _time:r._time, _field:niceify_legend(leg: r[\"_field\"])}))\n |> keep(columns: KEEPCOLS)\n |> yield()", 1329 | "refId": "A", 1330 | "resultFormat": "time_series", 1331 | "select": [ 1332 | [ 1333 | { 1334 | "params": [ 1335 | "alloc" 1336 | ], 1337 | "type": "field" 1338 | }, 1339 | { 1340 | "params": [], 1341 | "type": "mean" 1342 | }, 1343 | { 1344 | "params": [ 1345 | "Allocated" 1346 | ], 1347 | "type": "alias" 1348 | } 1349 | ], 1350 | [ 1351 | { 1352 | "params": [ 1353 | "size" 1354 | ], 1355 | "type": "field" 1356 | }, 1357 | { 1358 | "params": [], 1359 | "type": "mean" 1360 | }, 1361 | { 1362 | "params": [ 1363 | "Size" 1364 | ], 1365 | "type": "alias" 1366 | } 1367 | ], 1368 | [ 1369 | { 1370 | "params": [ 1371 | "free" 1372 | ], 1373 | "type": "field" 1374 | }, 1375 | { 1376 | "params": [], 1377 | "type": "mean" 1378 | }, 1379 | { 1380 | "params": [ 1381 | "Free" 1382 | ], 1383 | "type": "alias" 1384 | } 1385 | ], 1386 | [ 1387 | { 1388 | "params": [ 1389 | "fragmentation" 1390 | ], 1391 | "type": "field" 1392 | }, 1393 | { 1394 | "params": [], 1395 | "type": "last" 1396 | }, 1397 | { 1398 | "params": [ 1399 | "Fragmentation" 1400 | ], 1401 | "type": "alias" 1402 | } 1403 | ] 1404 | ], 1405 | "tags": [ 1406 | { 1407 | "key": "host", 1408 | "operator": "=~", 1409 | "value": "/^$hostname$/" 1410 | }, 1411 | { 1412 | "condition": "AND", 1413 | "key": "name", 1414 | "operator": "=~", 1415 | "value": "/^$poolname$/" 1416 | }, 1417 | { 1418 | "condition": "AND", 1419 | "key": "vdev", 1420 | "operator": "=", 1421 | "value": "root" 1422 | } 1423 | ] 1424 | } 1425 | ], 1426 | "title": "Pool Usage ($poolname)", 1427 | "type": "timeseries" 1428 | }, 1429 | { 1430 | "collapsed": false, 1431 | "datasource": { 1432 | "type": "influxdb", 1433 | "uid": "y2F-575nk" 1434 | }, 1435 | "gridPos": { 1436 | "h": 1, 1437 | "w": 24, 1438 | "x": 0, 1439 | "y": 15 1440 | }, 1441 | "id": 5, 1442 | "panels": [], 1443 | "targets": [ 1444 | { 1445 | "datasource": { 1446 | "type": "influxdb", 1447 | "uid": "y2F-575nk" 1448 | }, 1449 | "refId": "A" 1450 | } 1451 | ], 1452 | "title": "Latencies", 1453 | "type": "row" 1454 | }, 1455 | { 1456 | "cards": { 1457 | "cardPadding": 1, 1458 | "cardRound": 0 1459 | }, 1460 | "color": { 1461 | "cardColor": "#8AB8FF", 1462 | "colorScale": "sqrt", 1463 | "colorScheme": "interpolateGreens", 1464 | "exponent": 0.5, 1465 | "mode": "spectrum" 1466 | }, 1467 | "dataFormat": "tsbuckets", 1468 | "datasource": { 1469 | "type": "influxdb", 1470 | "uid": "${DS_INFLUXDB}" 1471 | }, 1472 | "description": "Latency histogram for the total reads of a ZFS pool", 1473 | "gridPos": { 1474 | "h": 8, 1475 | "w": 13, 1476 | "x": 0, 1477 | "y": 16 1478 | }, 1479 | "heatmap": {}, 1480 | "hideZeroBuckets": true, 1481 | "highlightCards": true, 1482 | "id": 2, 1483 | "legend": { 1484 | "show": true 1485 | }, 1486 | "reverseYBuckets": false, 1487 | "targets": [ 1488 | { 1489 | "alias": "$tag_le", 1490 | "datasource": { 1491 | "type": "influxdb", 1492 | "uid": "${DS_INFLUXDB}" 1493 | }, 1494 | "groupBy": [ 1495 | { 1496 | "params": [ 1497 | "$__interval" 1498 | ], 1499 | "type": "time" 1500 | }, 1501 | { 1502 | "params": [ 1503 | "le" 1504 | ], 1505 | "type": "tag" 1506 | }, 1507 | { 1508 | "params": [ 1509 | "null" 1510 | ], 1511 | "type": "fill" 1512 | } 1513 | ], 1514 | "measurement": "zpool_latency", 1515 | "orderByTime": "ASC", 1516 | "policy": "default", 1517 | "query": "KEEPCOLS = ${HMCOLS}\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_latency\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"total_read\") |> derivative(nonNegative: true)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\nNamedData = RawData\n |> keep(columns: KEEPCOLS)\n |> yield()", 1518 | "refId": "A", 1519 | "resultFormat": "time_series", 1520 | "select": [ 1521 | [ 1522 | { 1523 | "params": [ 1524 | "total_read" 1525 | ], 1526 | "type": "field" 1527 | }, 1528 | { 1529 | "params": [], 1530 | "type": "last" 1531 | }, 1532 | { 1533 | "params": [ 1534 | "1s" 1535 | ], 1536 | "type": "non_negative_derivative" 1537 | } 1538 | ] 1539 | ], 1540 | "tags": [ 1541 | { 1542 | "key": "host", 1543 | "operator": "=~", 1544 | "value": "/^$hostname$/" 1545 | }, 1546 | { 1547 | "condition": "AND", 1548 | "key": "name", 1549 | "operator": "=~", 1550 | "value": "/^$poolname$/" 1551 | }, 1552 | { 1553 | "condition": "AND", 1554 | "key": "vdev", 1555 | "operator": "=", 1556 | "value": "root" 1557 | } 1558 | ] 1559 | } 1560 | ], 1561 | "title": "Total Reads (rate)", 1562 | "tooltip": { 1563 | "show": true, 1564 | "showHistogram": false 1565 | }, 1566 | "transformations": [], 1567 | "type": "heatmap", 1568 | "xAxis": { 1569 | "show": true 1570 | }, 1571 | "yAxis": { 1572 | "decimals": 0, 1573 | "format": "s", 1574 | "logBase": 1, 1575 | "show": true 1576 | }, 1577 | "yBucketBound": "auto" 1578 | }, 1579 | { 1580 | "cards": {}, 1581 | "color": { 1582 | "cardColor": "#b4ff00", 1583 | "colorScale": "sqrt", 1584 | "colorScheme": "interpolateOranges", 1585 | "exponent": 0.5, 1586 | "mode": "spectrum" 1587 | }, 1588 | "dataFormat": "tsbuckets", 1589 | "datasource": { 1590 | "type": "influxdb", 1591 | "uid": "${DS_INFLUXDB}" 1592 | }, 1593 | "description": "Latency histogram for the total writes of a ZFS pool", 1594 | "gridPos": { 1595 | "h": 8, 1596 | "w": 11, 1597 | "x": 13, 1598 | "y": 16 1599 | }, 1600 | "heatmap": {}, 1601 | "hideZeroBuckets": true, 1602 | "highlightCards": true, 1603 | "id": 3, 1604 | "legend": { 1605 | "show": true 1606 | }, 1607 | "reverseYBuckets": false, 1608 | "targets": [ 1609 | { 1610 | "alias": "$tag_le", 1611 | "datasource": { 1612 | "type": "influxdb", 1613 | "uid": "${DS_INFLUXDB}" 1614 | }, 1615 | "groupBy": [ 1616 | { 1617 | "params": [ 1618 | "$__interval" 1619 | ], 1620 | "type": "time" 1621 | }, 1622 | { 1623 | "params": [ 1624 | "le" 1625 | ], 1626 | "type": "tag" 1627 | }, 1628 | { 1629 | "params": [ 1630 | "null" 1631 | ], 1632 | "type": "fill" 1633 | } 1634 | ], 1635 | "measurement": "zpool_latency", 1636 | "orderByTime": "ASC", 1637 | "policy": "default", 1638 | "query": "KEEPCOLS = ${HMCOLS}\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_latency\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"total_write\") |> derivative(nonNegative: true)\n |> drop(columns: [\"_start\", \"_stop\", \"host\", \"name\", \"vdev\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\nNamedData = RawData\n |> keep(columns: KEEPCOLS)\n |> yield()", 1639 | "refId": "A", 1640 | "resultFormat": "time_series", 1641 | "select": [ 1642 | [ 1643 | { 1644 | "params": [ 1645 | "total_write" 1646 | ], 1647 | "type": "field" 1648 | }, 1649 | { 1650 | "params": [], 1651 | "type": "last" 1652 | }, 1653 | { 1654 | "params": [ 1655 | "1s" 1656 | ], 1657 | "type": "non_negative_derivative" 1658 | } 1659 | ] 1660 | ], 1661 | "tags": [ 1662 | { 1663 | "key": "host", 1664 | "operator": "=~", 1665 | "value": "/^$hostname$/" 1666 | }, 1667 | { 1668 | "condition": "AND", 1669 | "key": "name", 1670 | "operator": "=~", 1671 | "value": "/^$poolname$/" 1672 | }, 1673 | { 1674 | "condition": "AND", 1675 | "key": "vdev", 1676 | "operator": "=", 1677 | "value": "root" 1678 | } 1679 | ] 1680 | } 1681 | ], 1682 | "title": "Total Writes (rate)", 1683 | "tooltip": { 1684 | "show": true, 1685 | "showHistogram": true 1686 | }, 1687 | "type": "heatmap", 1688 | "xAxis": { 1689 | "show": true 1690 | }, 1691 | "yAxis": { 1692 | "decimals": 0, 1693 | "format": "s", 1694 | "logBase": 1, 1695 | "show": true 1696 | }, 1697 | "yBucketBound": "auto" 1698 | }, 1699 | { 1700 | "cards": {}, 1701 | "color": { 1702 | "cardColor": "#b4ff00", 1703 | "colorScale": "sqrt", 1704 | "colorScheme": "interpolateGreens", 1705 | "exponent": 0.5, 1706 | "mode": "spectrum" 1707 | }, 1708 | "dataFormat": "tsbuckets", 1709 | "datasource": { 1710 | "type": "influxdb", 1711 | "uid": "${DS_INFLUXDB}" 1712 | }, 1713 | "description": "Latency histogram for $latencyparams of pool $poolname", 1714 | "gridPos": { 1715 | "h": 8, 1716 | "w": 6, 1717 | "x": 0, 1718 | "y": 24 1719 | }, 1720 | "heatmap": {}, 1721 | "hideZeroBuckets": true, 1722 | "highlightCards": true, 1723 | "id": 101, 1724 | "legend": { 1725 | "show": false 1726 | }, 1727 | "repeat": "latencyparams", 1728 | "repeatDirection": "h", 1729 | "reverseYBuckets": false, 1730 | "targets": [ 1731 | { 1732 | "datasource": { 1733 | "type": "influxdb", 1734 | "uid": "${DS_INFLUXDB}" 1735 | }, 1736 | "query": "KEEPCOLS = ${HMCOLS}\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_latency\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> filter(fn: (r) => r[\"name\"] == \"${poolname}\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"${latencyparams}\") |> derivative(nonNegative: true)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\nNamedData = RawData\n |> keep(columns: KEEPCOLS)\n |> yield()", 1737 | "refId": "A" 1738 | } 1739 | ], 1740 | "title": "Queue $latencyparams Latency Rate", 1741 | "tooltip": { 1742 | "show": true, 1743 | "showHistogram": false 1744 | }, 1745 | "transparent": true, 1746 | "type": "heatmap", 1747 | "xAxis": { 1748 | "show": true 1749 | }, 1750 | "yAxis": { 1751 | "decimals": 0, 1752 | "format": "s", 1753 | "logBase": 1, 1754 | "show": true 1755 | }, 1756 | "yBucketBound": "auto" 1757 | }, 1758 | { 1759 | "collapsed": true, 1760 | "gridPos": { 1761 | "h": 1, 1762 | "w": 24, 1763 | "x": 0, 1764 | "y": 40 1765 | }, 1766 | "id": 66, 1767 | "panels": [ 1768 | { 1769 | "cards": {}, 1770 | "color": { 1771 | "cardColor": "#b4ff00", 1772 | "colorScale": "sqrt", 1773 | "colorScheme": "interpolateGreens", 1774 | "exponent": 0.5, 1775 | "mode": "spectrum" 1776 | }, 1777 | "dataFormat": "tsbuckets", 1778 | "datasource": { 1779 | "type": "influxdb", 1780 | "uid": "${DS_INFLUXDB}" 1781 | }, 1782 | "description": "$indagg I/O Sizes - $ioparams", 1783 | "gridPos": { 1784 | "h": 10, 1785 | "w": 8, 1786 | "x": 0, 1787 | "y": 41 1788 | }, 1789 | "heatmap": {}, 1790 | "hideZeroBuckets": true, 1791 | "highlightCards": true, 1792 | "id": 59, 1793 | "legend": { 1794 | "show": true 1795 | }, 1796 | "maxPerRow": 3, 1797 | "repeat": "ioparams", 1798 | "repeatDirection": "h", 1799 | "reverseYBuckets": false, 1800 | "targets": [ 1801 | { 1802 | "datasource": { 1803 | "type": "influxdb", 1804 | "uid": "${DS_INFLUXDB}" 1805 | }, 1806 | "query": "KEEPCOLS = ${HMCOLS}\n\nRawData = from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_io_size\")\n |> filter(fn: (r) => r[\"vdev\"] == \"root\")\n |> filter(fn: (r) => r[\"_field\"] == \"${ioparams}_${indagg}\") |> derivative(nonNegative: true)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n\nNamedData = RawData\n |> keep(columns: KEEPCOLS)\n |> yield()", 1807 | "refId": "A" 1808 | } 1809 | ], 1810 | "title": "ZFS IO - ${ioparams}_${indagg}", 1811 | "tooltip": { 1812 | "show": true, 1813 | "showHistogram": false 1814 | }, 1815 | "transparent": true, 1816 | "type": "heatmap", 1817 | "xAxis": { 1818 | "show": true 1819 | }, 1820 | "yAxis": { 1821 | "decimals": 0, 1822 | "format": "decbytes", 1823 | "logBase": 1, 1824 | "show": true 1825 | }, 1826 | "yBucketBound": "auto" 1827 | } 1828 | ], 1829 | "repeat": "indagg", 1830 | "repeatDirection": "h", 1831 | "title": "I/O Sizes ($indagg)", 1832 | "type": "row" 1833 | } 1834 | ], 1835 | "refresh": "", 1836 | "schemaVersion": 36, 1837 | "style": "dark", 1838 | "tags": [], 1839 | "templating": { 1840 | "list": [ 1841 | { 1842 | "current": {}, 1843 | "datasource": { 1844 | "type": "influxdb", 1845 | "uid": "${DS_INFLUXDB}" 1846 | }, 1847 | "definition": "buckets()", 1848 | "description": "bucket where zpool_influxdb data is stored", 1849 | "hide": 0, 1850 | "includeAll": false, 1851 | "multi": false, 1852 | "name": "bucket", 1853 | "options": [], 1854 | "query": "buckets()", 1855 | "refresh": 1, 1856 | "regex": "", 1857 | "skipUrlSync": false, 1858 | "sort": 0, 1859 | "type": "query" 1860 | }, 1861 | { 1862 | "current": {}, 1863 | "datasource": { 1864 | "type": "influxdb", 1865 | "uid": "${DS_INFLUXDB}" 1866 | }, 1867 | "definition": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> keep(columns: [\"host\"])\n |> unique(column: \"host\")\n |> map(fn: (r) => ({_value: r[\"host\"]}))\n |> yield(name: \"mean\")", 1868 | "description": "filter by host", 1869 | "hide": 0, 1870 | "includeAll": false, 1871 | "multi": false, 1872 | "name": "hostname", 1873 | "options": [], 1874 | "query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> keep(columns: [\"host\"])\n |> unique(column: \"host\")\n |> map(fn: (r) => ({_value: r[\"host\"]}))\n |> yield(name: \"mean\")", 1875 | "refresh": 2, 1876 | "regex": "", 1877 | "skipUrlSync": false, 1878 | "sort": 5, 1879 | "tagValuesQuery": "", 1880 | "tagsQuery": "", 1881 | "type": "query", 1882 | "useTags": false 1883 | }, 1884 | { 1885 | "current": {}, 1886 | "datasource": { 1887 | "type": "influxdb", 1888 | "uid": "${DS_INFLUXDB}" 1889 | }, 1890 | "definition": " from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> keep(columns: [\"name\"])\n |> unique(column: \"name\")\n |> map(fn: (r) => ({_value: r[\"name\"]}))\n |> yield(name: \"mean\")", 1891 | "description": "filter by pool", 1892 | "hide": 0, 1893 | "includeAll": false, 1894 | "multi": false, 1895 | "name": "poolname", 1896 | "options": [], 1897 | "query": " from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zpool_stats\")\n |> filter(fn: (r) => r[\"host\"] == \"${hostname}\")\n |> keep(columns: [\"name\"])\n |> unique(column: \"name\")\n |> map(fn: (r) => ({_value: r[\"name\"]}))\n |> yield(name: \"mean\")", 1898 | "refresh": 1, 1899 | "regex": "", 1900 | "skipUrlSync": false, 1901 | "sort": 5, 1902 | "tagValuesQuery": "", 1903 | "tagsQuery": "", 1904 | "type": "query", 1905 | "useTags": false 1906 | }, 1907 | { 1908 | "allValue": "", 1909 | "current": { 1910 | "selected": true, 1911 | "text": [ 1912 | "async_read_ind" 1913 | ], 1914 | "value": [ 1915 | "async_read_ind" 1916 | ] 1917 | }, 1918 | "description": "zpool_io_size parameters to create histograms for (recommended: all)", 1919 | "hide": 0, 1920 | "includeAll": true, 1921 | "label": "i/O Parameters", 1922 | "multi": true, 1923 | "name": "ioparams", 1924 | "options": [ 1925 | { 1926 | "selected": true, 1927 | "text": "All", 1928 | "value": "$__all" 1929 | }, 1930 | { 1931 | "selected": false, 1932 | "text": "async_read", 1933 | "value": "async_read" 1934 | }, 1935 | { 1936 | "selected": false, 1937 | "text": "sync_read", 1938 | "value": "sync_read" 1939 | }, 1940 | { 1941 | "selected": false, 1942 | "text": "scrub_read", 1943 | "value": "scrub_read" 1944 | }, 1945 | { 1946 | "selected": false, 1947 | "text": "async_write", 1948 | "value": "async_write" 1949 | }, 1950 | { 1951 | "selected": false, 1952 | "text": "sync_write", 1953 | "value": "sync_write" 1954 | }, 1955 | { 1956 | "selected": false, 1957 | "text": "trim_write", 1958 | "value": "trim_write" 1959 | } 1960 | ], 1961 | "query": "async_read, sync_read, scrub_read, async_write, sync_write, trim_write", 1962 | "queryValue": "", 1963 | "skipUrlSync": false, 1964 | "type": "custom" 1965 | }, 1966 | { 1967 | "allValue": "", 1968 | "current": { 1969 | "selected": true, 1970 | "text": [ 1971 | "All" 1972 | ], 1973 | "value": [ 1974 | "$__all" 1975 | ] 1976 | }, 1977 | "description": "individual or aggregate metrics (recommended: all)", 1978 | "hide": 0, 1979 | "includeAll": true, 1980 | "label": "Individual / Aggregate", 1981 | "multi": true, 1982 | "name": "indagg", 1983 | "options": [ 1984 | { 1985 | "selected": true, 1986 | "text": "All", 1987 | "value": "$__all" 1988 | }, 1989 | { 1990 | "selected": false, 1991 | "text": "ind", 1992 | "value": "ind" 1993 | }, 1994 | { 1995 | "selected": false, 1996 | "text": "agg", 1997 | "value": "agg" 1998 | } 1999 | ], 2000 | "query": "ind,agg", 2001 | "queryValue": "", 2002 | "skipUrlSync": false, 2003 | "type": "custom" 2004 | }, 2005 | { 2006 | "allValue": "", 2007 | "current": { 2008 | "selected": true, 2009 | "text": [ 2010 | "All" 2011 | ], 2012 | "value": [ 2013 | "$__all" 2014 | ] 2015 | }, 2016 | "description": "Latency parameters to show histograms for selected pool (recommended: all)", 2017 | "hide": 0, 2018 | "includeAll": true, 2019 | "label": "Latency Parameters", 2020 | "multi": true, 2021 | "name": "latencyparams", 2022 | "options": [ 2023 | { 2024 | "selected": true, 2025 | "text": "All", 2026 | "value": "$__all" 2027 | }, 2028 | { 2029 | "selected": false, 2030 | "text": "sync_read", 2031 | "value": "sync_read" 2032 | }, 2033 | { 2034 | "selected": false, 2035 | "text": "async_read", 2036 | "value": "async_read" 2037 | }, 2038 | { 2039 | "selected": false, 2040 | "text": "scrub", 2041 | "value": "scrub" 2042 | }, 2043 | { 2044 | "selected": false, 2045 | "text": "disk_read", 2046 | "value": "disk_read" 2047 | }, 2048 | { 2049 | "selected": false, 2050 | "text": "sync_write", 2051 | "value": "sync_write" 2052 | }, 2053 | { 2054 | "selected": false, 2055 | "text": "async_write", 2056 | "value": "async_write" 2057 | }, 2058 | { 2059 | "selected": false, 2060 | "text": "trim", 2061 | "value": "trim" 2062 | }, 2063 | { 2064 | "selected": false, 2065 | "text": "disk_write", 2066 | "value": "disk_write" 2067 | } 2068 | ], 2069 | "query": "sync_read,async_read,scrub,disk_read,sync_write,async_write,trim,disk_write", 2070 | "queryValue": "", 2071 | "skipUrlSync": false, 2072 | "type": "custom" 2073 | }, 2074 | { 2075 | "current": { 2076 | "selected": false, 2077 | "text": "[\"_field\", \"_time\", \"_value\"]", 2078 | "value": "[\"_field\", \"_time\", \"_value\"]" 2079 | }, 2080 | "hide": 2, 2081 | "includeAll": false, 2082 | "label": "Time series columns to retain", 2083 | "multi": false, 2084 | "name": "TSCOLS", 2085 | "options": [ 2086 | { 2087 | "selected": true, 2088 | "text": "[\"_field\", \"_time\", \"_value\"]", 2089 | "value": "[\"_field\", \"_time\", \"_value\"]" 2090 | } 2091 | ], 2092 | "query": "[\"_field\"\\, \"_time\"\\, \"_value\"]", 2093 | "skipUrlSync": false, 2094 | "type": "custom" 2095 | }, 2096 | { 2097 | "current": { 2098 | "selected": false, 2099 | "text": "[\"_time\", \"_value\", \"le\"]", 2100 | "value": "[\"_time\", \"_value\", \"le\"]" 2101 | }, 2102 | "description": "Columns to retain in heatmaps", 2103 | "hide": 2, 2104 | "includeAll": false, 2105 | "label": "Heatmap columns", 2106 | "multi": false, 2107 | "name": "HMCOLS", 2108 | "options": [ 2109 | { 2110 | "selected": true, 2111 | "text": "[\"_time\", \"_value\", \"le\"]", 2112 | "value": "[\"_time\", \"_value\", \"le\"]" 2113 | } 2114 | ], 2115 | "query": "[\"_time\"\\, \"_value\"\\, \"le\"]", 2116 | "skipUrlSync": false, 2117 | "type": "custom" 2118 | }, 2119 | { 2120 | "current": { 2121 | "selected": false, 2122 | "text": "(leg) => strings.title(v: strings.replaceAll(v:leg, t: \"_\", u: \" \"))", 2123 | "value": "(leg) => strings.title(v: strings.replaceAll(v:leg, t: \"_\", u: \" \"))" 2124 | }, 2125 | "description": "Function used in queries to replace underscores with spaces and then title case the result", 2126 | "hide": 2, 2127 | "includeAll": false, 2128 | "label": "Niceify Legend", 2129 | "multi": false, 2130 | "name": "NICEIFYLEG", 2131 | "options": [ 2132 | { 2133 | "selected": true, 2134 | "text": "(leg) => strings.title(v: strings.replaceAll(v:leg, t: \"_\", u: \" \"))", 2135 | "value": "(leg) => strings.title(v: strings.replaceAll(v:leg, t: \"_\", u: \" \"))" 2136 | } 2137 | ], 2138 | "query": "(leg) => strings.title(v: strings.replaceAll(v:leg\\, t: \"_\"\\, u: \" \"))", 2139 | "skipUrlSync": false, 2140 | "type": "custom" 2141 | } 2142 | ] 2143 | }, 2144 | "time": { 2145 | "from": "now-1h", 2146 | "to": "now" 2147 | }, 2148 | "timepicker": { 2149 | "refresh_intervals": [ 2150 | "10s", 2151 | "30s", 2152 | "1m", 2153 | "5m", 2154 | "15m", 2155 | "30m", 2156 | "1h", 2157 | "2h", 2158 | "1d" 2159 | ] 2160 | }, 2161 | "timezone": "", 2162 | "title": "ZFS Pool Metrics (InfluxDBv2)", 2163 | "uid": "lj--ccG4z", 2164 | "version": 12, 2165 | "weekStart": "" 2166 | } --------------------------------------------------------------------------------