diff --git a/contrib/mixin/dashboards/fleet.libsonnet b/contrib/mixin/dashboards/fleet.libsonnet index df9ecddd..3b0b2c75 100644 --- a/contrib/mixin/dashboards/fleet.libsonnet +++ b/contrib/mixin/dashboards/fleet.libsonnet @@ -1,16 +1,39 @@ local b = import 'builders.libsonnet'; +local hosts = 'windows_os_hostname{job=~"$job", hostname=~"$hostname"}'; +// Counts hosts matching expr, a vector by instance. Falls back to 0 while hosts are selected. +local countHosts(expr) = 'count((' + expr + ') and on (instance) ' + hosts + ') or (0 * count(' + hosts + '))'; +local cpuBusy = '100 * (1 - avg by (instance) (clamp_max(rate(windows_cpu_time_total{job=~"$job", mode="idle"}[$__rate_interval]), 1)))'; +local memoryUsed = '100 * (1 - windows_memory_physical_free_bytes{job=~"$job"} / windows_memory_physical_total_bytes{job=~"$job"})'; +local volumeFree = '100 * windows_logical_disk_free_bytes{job=~"$job", volume!~"HarddiskVolume.*"} / windows_logical_disk_size_bytes{job=~"$job", volume!~"HarddiskVolume.*"}'; +local attention = [{ color: 'green', value: null }, { color: 'orange', value: 1 }]; -function(on) +// config supplies the alert thresholds, so a counter turns orange when the matching alert condition holds. +function(on, config) b.tab( 'Fleet', b.rows([ + if on('os') then b.summary([ + 250, + 251, + if on('cpu') then 252, + if on('memory') then 253, + if on('logical_disk') then 254, + if on('service') then 255, + ]), if on('os') then b.row('Hosts', b.flow([[2, 24, 10]])), if on('os') then b.row('Utilization', b.flow([if on('cpu') then [3, 8, 8], if on('memory') then [4, 8, 8], if on('logical_disk') then [5, 8, 8]])), - if on('os') then b.row('Throughput and errors', b.flow([if on('net') then [6, 8, 8], if on('logical_disk') then [7, 8, 8], if on('net') then [8, 8, 8]])), + if on('os') then b.row('Network and disk', b.flow([if on('net') then [6, 12, 8], if on('net') then [9, 12, 8], if on('logical_disk') then [7, 12, 8], if on('net') then [8, 12, 8]])), ]), [ + b.stat(250, 'Hosts', 'Hosts that match the Job and Hostname selection and report windows_os_hostname.', 'count(' + hosts + ')'), + b.stat(251, 'Hosts down', 'Selected hosts whose last scrape failed. Hosts stay selectable for one day after they stop reporting.', 'count((up{job=~"$job"} == 0) and on (instance) last_over_time(' + hosts + '[1d])) or (0 * count(up{job=~"$job"}))', steps=[{ color: 'green', value: null }, { color: 'red', value: 1 }]), + b.stat(252, 'CPU > %s%%' % config.cpuHighUsageThreshold, 'Hosts whose CPU usage is above the cpuHighUsageThreshold of the WindowsCPUHighUsage alert. The alert also requires 15 minutes above it.', countHosts(cpuBusy + ' > %s' % config.cpuHighUsageThreshold), steps=attention), + b.stat(253, 'RAM > %s%%' % config.memoryHighUsageThreshold, 'Hosts whose physical memory usage is above the memoryHighUsageThreshold of the WindowsMemoryHighUsage alert. The alert also requires 15 minutes above it.', countHosts('max by (instance) (' + memoryUsed + ') > %s' % config.memoryHighUsageThreshold), steps=attention), + b.stat(254, 'Low disk', 'Hosts with at least one volume with less than %s%% free space, the diskFreeWarningThreshold' % config.diskFreeWarningThreshold + ' of the WindowsDiskAlmostFull alert. HarddiskVolume* volumes without a drive letter are ignored.', countHosts('min by (instance) (' + volumeFree + ') < %s' % config.diskFreeWarningThreshold), steps=attention), + b.stat(255, 'Auto stopped', 'Hosts with at least one service with start mode auto that is not running. Delayed-start and trigger-start services can show up here until they start.', countHosts('count by (instance) (windows_service_state{job=~"$job", state="running"} == 0 and on (instance, name) windows_service_start_mode{job=~"$job", start_mode="auto"} == 1)'), steps=attention), + b.panel.new(2, 'Hosts', 'table') - + b.panel.withDescription('One row per scraped host. Click a hostname to open its details. Services up counts running services; Auto stopped counts services with start mode auto that are not running.') + + b.panel.withDescription('One row per scraped host. Click a hostname to open its details. C: used is the usage of the C: volume, usually the system drive; Fullest volume is the most used volume with a drive letter. Services up counts running services; Auto stopped counts services with start mode auto that are not running.') + b.panel.withQueries([ b.query.new('max by (instance, hostname) (windows_os_hostname{job=~"$job", hostname=~"$hostname"})', 'A') + b.query.withInstant() @@ -48,6 +71,9 @@ function(on) b.query.new('(max by (instance) (windows_system_processes{job=~"$job"})) and on (instance) windows_os_hostname{job=~"$job", hostname=~"$hostname"}', 'L') + b.query.withInstant() + b.query.withFormat('table'), + b.query.new('(max by (instance) (100 * (1 - windows_logical_disk_free_bytes{job=~"$job", volume="C:"} / windows_logical_disk_size_bytes{job=~"$job", volume="C:"}))) and on (instance) windows_os_hostname{job=~"$job", hostname=~"$hostname"}', 'M') + + b.query.withInstant() + + b.query.withFormat('table'), ]) + b.panel.withTransformations([ { @@ -71,6 +97,7 @@ function(on) 'Time 10': true, 'Time 11': true, 'Time 12': true, + 'Time 13': true, 'Time 2': true, 'Time 3': true, 'Time 4': true, @@ -90,10 +117,11 @@ function(on) 'Value #F': 7, 'Value #G': 8, 'Value #H': 9, - 'Value #I': 10, - 'Value #J': 11, - 'Value #K': 12, - 'Value #L': 13, + 'Value #I': 11, + 'Value #J': 12, + 'Value #K': 13, + 'Value #L': 14, + 'Value #M': 10, hostname: 0, instance: 1, product: 2, @@ -110,6 +138,7 @@ function(on) 'Value #J': 'Services up', 'Value #K': 'Auto stopped', 'Value #L': 'Processes', + 'Value #M': 'C: used', hostname: 'Hostname', instance: 'Instance', product: 'OS', @@ -481,6 +510,63 @@ function(on) }, ], }, + { + matcher: { + id: 'byName', + options: 'Value #M', + }, + properties: [ + { + id: 'unit', + value: 'percent', + }, + { + id: 'min', + value: 0, + }, + { + id: 'max', + value: 100, + }, + { + id: 'thresholds', + value: { + mode: 'absolute', + steps: [ + { + color: 'green', + }, + { + color: 'orange', + value: 80, + }, + { + color: 'red', + value: 90, + }, + ], + }, + }, + { + id: 'color', + value: { + mode: 'continuous-GrYlRd', + }, + }, + { + id: 'custom.cellOptions', + value: { + mode: 'basic', + type: 'gauge', + valueDisplayMode: 'text', + }, + }, + { + id: 'decimals', + value: 1, + }, + ], + }, { matcher: { id: 'byName', @@ -655,6 +741,26 @@ function(on) }, ]), + b.panel.new(9, 'Busiest interface', 'timeseries') + + b.panel.withDescription('Utilization of the busiest interface of each host: bytes sent and received per second against its current bandwidth. Unlike the throughput sum, it shows a single saturated interface on a host with several. Shows the 25 highest hosts at each point in time.') + + b.panel.withQueries([ + b.query.new('topk(25, max by (instance) (rate(windows_net_bytes_total{job=~"$job"}[$__rate_interval]) / (windows_net_current_bandwidth_bytes{job=~"$job"} > 0)) * on (instance) group_left (hostname) max by (instance, hostname) (windows_os_hostname{job=~"$job", hostname=~"$hostname"}))', 'A') + + b.query.withLegendFormat('{{hostname}}'), + ]) + + b.panel.withDefaults({ + custom: { thresholdsStyle: { mode: 'dashed' } }, + max: 1, + min: 0, + thresholds: { steps: b.levels(0.8, 0.9) }, + unit: 'percentunit', + }) + + b.panel.withOptions({ + legend: { + calcs: [], + displayMode: 'list', + }, + }), + b.panel.new(7, 'Disk throughput', 'timeseries') + b.panel.withDescription('Sum over all volumes. Read is drawn below the axis. Shows the 25 highest hosts at each point in time.') + b.panel.withQueries([ diff --git a/contrib/mixin/dashboards/windows-exporter.libsonnet b/contrib/mixin/dashboards/windows-exporter.libsonnet index 0634493c..1d3e6ecf 100644 --- a/contrib/mixin/dashboards/windows-exporter.libsonnet +++ b/contrib/mixin/dashboards/windows-exporter.libsonnet @@ -15,7 +15,7 @@ function(config) local tabs = [ tab for tab in [ - (import 'fleet.libsonnet')(on), + (import 'fleet.libsonnet')(on, config), (import 'overview.libsonnet')(on), (import 'cpu.libsonnet')(on), (import 'memory.libsonnet')(on), diff --git a/contrib/mixin/tests/dashboard.test.jsonnet b/contrib/mixin/tests/dashboard.test.jsonnet index ab9d2318..1593a580 100644 --- a/contrib/mixin/tests/dashboard.test.jsonnet +++ b/contrib/mixin/tests/dashboard.test.jsonnet @@ -46,20 +46,20 @@ assert expect('defaults', { CPU: ['Summary', 'Utilization', 'Scheduling', 'System calls and frequency'], Disk: ['Summary', 'Volumes', 'Volume I/O', 'Physical disks'], Exporter: exporter, - Fleet: ['Hosts', 'Utilization', 'Throughput and errors'], + Fleet: ['Summary', 'Hosts', 'Utilization', 'Network and disk'], Memory: ['Summary', 'Physical memory and commit', 'Paging and kernel memory'], Network: ['Summary', 'Interfaces'], Overview: ['Summary', 'CPU and memory', 'Storage and network'], Services: ['Summary', 'State'], }); -assert expect('osOnly', { Exporter: exporter, Fleet: ['Hosts'], Overview: ['Summary'] }); -assert expect('smbClientOnly', { Exporter: exporter, Fleet: ['Hosts'], Overview: ['Summary'], SMB: ['Summary', 'Client shares'] }); +assert expect('osOnly', { Exporter: exporter, Fleet: ['Summary', 'Hosts'], Overview: ['Summary'] }); +assert expect('smbClientOnly', { Exporter: exporter, Fleet: ['Summary', 'Hosts'], Overview: ['Summary'], SMB: ['Summary', 'Client shares'] }); assert expect('diskWithoutDiskdrive', ['Summary', 'Volumes', 'Volume I/O', 'Physical disks']); assert expect('diskWithDiskdrive', ['Summary', 'Volumes', 'Volume I/O', 'Drives', 'Physical disks']); assert expect('replaced', { CPU: ['Summary', 'Utilization', 'System calls and frequency'], Exporter: exporter, - Fleet: ['Hosts', 'Utilization'], + Fleet: ['Summary', 'Hosts', 'Utilization'], Overview: ['Summary', 'CPU and memory'], }); diff --git a/dashboard/README.md b/dashboard/README.md index 1b98273c..1f57798f 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -34,7 +34,7 @@ The **Reboots** annotation marks each reboot of the selected host on all graphs. | Tab | Content | |----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Fleet | One row per host with OS version, uptime, CPU, memory, commit charge, the fullest volume and stopped automatic services, and graphs of the 25 highest hosts. | +| Fleet | Counts of hosts, hosts down and hosts above the CPU, memory and disk alert thresholds or with stopped automatic services; one row per host with OS version, uptime, CPU, memory, commit charge, C: and fullest volume usage and stopped automatic services; graphs of the 25 highest hosts, including the busiest interface per host. | | Overview | Summary of the selected host: operating system, uptime, CPUs, memory, commit charge, volumes, disk and network throughput. | | CPU | Utilization by mode and per core, processor queue length, context switches, interrupts, processes, threads, system calls and the effective CPU frequency. | | Memory | Used and available physical memory, commit charge, hard page faults, kernel pools and the system cache. | diff --git a/dashboard/windows-exporter-dashboard.json b/dashboard/windows-exporter-dashboard.json index 6ee6f7dc..203c6e36 100644 --- a/dashboard/windows-exporter-dashboard.json +++ b/dashboard/windows-exporter-dashboard.json @@ -10436,6 +10436,29 @@ }, "refId": "L" } + }, + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "(max by (instance) (100 * (1 - windows_logical_disk_free_bytes{job=~\"$job\", volume=\"C:\"} / windows_logical_disk_size_bytes{job=~\"$job\", volume=\"C:\"}))) and on (instance) windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "M" + } } ], "queryOptions": {}, @@ -10461,6 +10484,7 @@ "Time 10": true, "Time 11": true, "Time 12": true, + "Time 13": true, "Time 2": true, "Time 3": true, "Time 4": true, @@ -10480,10 +10504,11 @@ "Value #F": 7, "Value #G": 8, "Value #H": 9, - "Value #I": 10, - "Value #J": 11, - "Value #K": 12, - "Value #L": 13, + "Value #I": 11, + "Value #J": 12, + "Value #K": 13, + "Value #L": 14, + "Value #M": 10, "hostname": 0, "instance": 1, "product": 2, @@ -10500,6 +10525,7 @@ "Value #J": "Services up", "Value #K": "Auto stopped", "Value #L": "Processes", + "Value #M": "C: used", "hostname": "Hostname", "instance": "Instance", "product": "OS", @@ -10511,7 +10537,7 @@ ] } }, - "description": "One row per scraped host. Click a hostname to open its details. Services up counts running services; Auto stopped counts services with start mode auto that are not running.", + "description": "One row per scraped host. Click a hostname to open its details. C: used is the usage of the C: volume, usually the system drive; Fullest volume is the most used volume with a drive letter. Services up counts running services; Auto stopped counts services with start mode auto that are not running.", "id": 2, "links": [], "title": "Hosts", @@ -10889,6 +10915,63 @@ } ] }, + { + "matcher": { + "id": "byName", + "options": "Value #M" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "orange", + "value": 80 + }, + { + "color": "red", + "value": 90 + } + ] + } + }, + { + "id": "color", + "value": { + "mode": "continuous-GrYlRd" + } + }, + { + "id": "custom.cellOptions", + "value": { + "mode": "basic", + "type": "gauge", + "valueDisplayMode": "text" + } + }, + { + "id": "decimals", + "value": 1 + } + ] + }, { "matcher": { "id": "byName", @@ -15793,6 +15876,531 @@ } } }, + "panel-250": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "count(windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"})", + "instant": false, + "legendFormat": "__auto", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 100 + }, + "transformations": [] + } + }, + "description": "Hosts that match the Job and Hostname selection and report windows_os_hostname.", + "id": 250, + "links": [], + "title": "Hosts", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-251": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "count((up{job=~\"$job\"} == 0) and on (instance) last_over_time(windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}[1d])) or (0 * count(up{job=~\"$job\"}))", + "instant": false, + "legendFormat": "__auto", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 100 + }, + "transformations": [] + } + }, + "description": "Selected hosts whose last scrape failed. Hosts stay selectable for one day after they stop reporting.", + "id": 251, + "links": [], + "title": "Hosts down", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-252": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "count((100 * (1 - avg by (instance) (clamp_max(rate(windows_cpu_time_total{job=~\"$job\", mode=\"idle\"}[$__rate_interval]), 1))) > 90) and on (instance) windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}) or (0 * count(windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}))", + "instant": false, + "legendFormat": "__auto", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 100 + }, + "transformations": [] + } + }, + "description": "Hosts whose CPU usage is above the cpuHighUsageThreshold of the WindowsCPUHighUsage alert. The alert also requires 15 minutes above it.", + "id": 252, + "links": [], + "title": "CPU > 90%", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 1 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-253": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "count((max by (instance) (100 * (1 - windows_memory_physical_free_bytes{job=~\"$job\"} / windows_memory_physical_total_bytes{job=~\"$job\"})) > 90) and on (instance) windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}) or (0 * count(windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}))", + "instant": false, + "legendFormat": "__auto", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 100 + }, + "transformations": [] + } + }, + "description": "Hosts whose physical memory usage is above the memoryHighUsageThreshold of the WindowsMemoryHighUsage alert. The alert also requires 15 minutes above it.", + "id": 253, + "links": [], + "title": "RAM > 90%", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 1 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-254": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "count((min by (instance) (100 * windows_logical_disk_free_bytes{job=~\"$job\", volume!~\"HarddiskVolume.*\"} / windows_logical_disk_size_bytes{job=~\"$job\", volume!~\"HarddiskVolume.*\"}) < 10) and on (instance) windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}) or (0 * count(windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}))", + "instant": false, + "legendFormat": "__auto", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 100 + }, + "transformations": [] + } + }, + "description": "Hosts with at least one volume with less than 10% free space, the diskFreeWarningThreshold of the WindowsDiskAlmostFull alert. HarddiskVolume* volumes without a drive letter are ignored.", + "id": 254, + "links": [], + "title": "Low disk", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 1 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-255": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "count((count by (instance) (windows_service_state{job=~\"$job\", state=\"running\"} == 0 and on (instance, name) windows_service_start_mode{job=~\"$job\", start_mode=\"auto\"} == 1)) and on (instance) windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}) or (0 * count(windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}))", + "instant": false, + "legendFormat": "__auto", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 100 + }, + "transformations": [] + } + }, + "description": "Hosts with at least one service with start mode auto that is not running. Delayed-start and trigger-start services can show up here until they start.", + "id": 255, + "links": [], + "title": "Auto stopped", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 1 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, "panel-26": { "kind": "Panel", "spec": { @@ -23658,6 +24266,126 @@ } } }, + "panel-9": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "editorMode": "code", + "expr": "topk(25, max by (instance) (rate(windows_net_bytes_total{job=~\"$job\"}[$__rate_interval]) / (windows_net_current_bandwidth_bytes{job=~\"$job\"} > 0)) * on (instance) group_left (hostname) max by (instance, hostname) (windows_os_hostname{job=~\"$job\", hostname=~\"$hostname\"}))", + "instant": false, + "legendFormat": "{{hostname}}", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "Utilization of the busiest interface of each host: bytes sent and received per second against its current bandwidth. Unlike the throughput sum, it shows a single saturated interface on a host with several. Shows the 25 highest hosts at each point in time.", + "id": 9, + "links": [], + "title": "Busiest interface", + "vizConfig": { + "group": "timeseries", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "dashed" + } + }, + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, "panel-90": { "kind": "Panel", "spec": { @@ -24762,6 +25490,98 @@ "kind": "RowsLayout", "spec": { "rows": [ + { + "kind": "RowsLayoutRow", + "spec": { + "collapse": false, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-250" + }, + "height": 4, + "width": 4, + "x": 0, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-251" + }, + "height": 4, + "width": 4, + "x": 4, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-252" + }, + "height": 4, + "width": 4, + "x": 8, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-253" + }, + "height": 4, + "width": 4, + "x": 12, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-254" + }, + "height": 4, + "width": 4, + "x": 16, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-255" + }, + "height": 4, + "width": 4, + "x": 20, + "y": 0 + } + } + ] + } + }, + "title": "Summary" + } + }, { "kind": "RowsLayoutRow", "spec": { @@ -24858,11 +25678,24 @@ "name": "panel-6" }, "height": 8, - "width": 8, + "width": 12, "x": 0, "y": 0 } }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-9" + }, + "height": 8, + "width": 12, + "x": 12, + "y": 0 + } + }, { "kind": "GridLayoutItem", "spec": { @@ -24871,9 +25704,9 @@ "name": "panel-7" }, "height": 8, - "width": 8, - "x": 8, - "y": 0 + "width": 12, + "x": 0, + "y": 8 } }, { @@ -24884,15 +25717,15 @@ "name": "panel-8" }, "height": 8, - "width": 8, - "x": 16, - "y": 0 + "width": 12, + "x": 12, + "y": 8 } } ] } }, - "title": "Throughput and errors" + "title": "Network and disk" } } ]