From 61346f1fbee1e299d15fd4153e350316e4de30bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Fri, 9 Oct 2026 20:45:51 +0200 Subject: [PATCH] dashboard: add process metrics with bounded graphs and summaries (#2631) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- contrib/mixin/.dashboard-lint.yaml | 19 + contrib/mixin/dashboards/processes.libsonnet | 57 + contrib/mixin/dashboards/variables.libsonnet | 26 + .../dashboards/windows-exporter.libsonnet | 1 + dashboard/README.md | 12 +- dashboard/windows-exporter-dashboard.json | 1702 +++++++++++++++++ 6 files changed, 1816 insertions(+), 1 deletion(-) create mode 100644 contrib/mixin/dashboards/processes.libsonnet diff --git a/contrib/mixin/.dashboard-lint.yaml b/contrib/mixin/.dashboard-lint.yaml index d2647962..a2fbdb45 100644 --- a/contrib/mixin/.dashboard-lint.yaml +++ b/contrib/mixin/.dashboard-lint.yaml @@ -1,5 +1,24 @@ # Keep exceptions scoped to the existing sample dashboard and panels. exclusions: + target-promql-rule: + reason: dashboard-linter 0.3.0's v2 adapter omits custom variable current values and options, so the numeric process_top value becomes a vector identifier. These queries are validated against live Prometheus with limits 5, 10 and 20. + entries: + - dashboard: Windows Exporter + panel: Process CPU usage + - dashboard: Windows Exporter + panel: Process working set + - dashboard: Windows Exporter + panel: Process private bytes + - dashboard: Windows Exporter + panel: Process I/O throughput + - dashboard: Windows Exporter + panel: Process threads + - dashboard: Windows Exporter + panel: Process handles + - dashboard: Windows Exporter + panel: Process I/O operations + - dashboard: Windows Exporter + panel: Process page faults target-instance-rule: reason: Fleet panels intentionally span instances; per-host panels use an exact matcher for the single-select instance variable. entries: diff --git a/contrib/mixin/dashboards/processes.libsonnet b/contrib/mixin/dashboards/processes.libsonnet new file mode 100644 index 00000000..a7b5e8d3 --- /dev/null +++ b/contrib/mixin/dashboards/processes.libsonnet @@ -0,0 +1,57 @@ +local b = import 'builders.libsonnet'; +// PID 0 is the synthetic Idle process, not CPU consumed by an application. +local selector = '{job=~"$job", instance="$instance", process=~"$process", process_id!="0"}'; +local gauge(metric, at='') = 'windows_process_' + metric + selector + at; +local rate(metric, at='') = 'rate(' + gauge(metric) + '[$__rate_interval]' + at + ')'; +local sumRates(metric, at='') = 'sum by (process, process_id) (' + rate(metric, at) + ')'; +local stat(id, title, description, expr, unit) = + b.panel.new(id, title, 'stat') + + b.panel.withDescription(description + ' Includes all selected processes, regardless of Top N. Requires the process collector.') + + b.panel.withQueries([b.query.new(expr) + b.query.withInstant()]) + + b.panel.withDefaults({ min: 0, unit: unit }); +local graph(id, title, description, expr, ranking, unit) = + b.panel.new(id, title, 'timeseries') + + b.panel.withDescription(description + ' Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.') + + b.panel.withQueries([ + b.query.new(expr + ' and on (process, process_id) topk($process_top, ' + ranking + ')') + + b.query.withLegendFormat('{{process}} ({{process_id}})'), + ]) + + b.panel.withQueryOptions({ maxDataPoints: 300 }) + + b.panel.withDefaults({ min: 0, unit: unit }); + +b.tab( + 'Processes', + b.grid([ + b.place(150, 0, 0, 4, 4), + b.place(151, 4, 0, 4, 4), + b.place(152, 8, 0, 4, 4), + b.place(153, 12, 0, 4, 4), + b.place(154, 16, 0, 4, 4), + b.place(155, 20, 0, 4, 4), + b.place(112, 0, 4, 12, 8), + b.place(113, 12, 4, 12, 8), + b.place(114, 0, 12, 12, 8), + b.place(115, 12, 12, 12, 8), + b.place(116, 0, 20, 12, 8), + b.place(117, 12, 20, 12, 8), + b.place(118, 0, 28, 12, 8), + b.place(119, 12, 28, 12, 8), + ]), + [ + stat(150, 'Processes', 'Number of distinct process IDs currently collected, excluding Idle.', 'count(count by (process_id) (' + gauge('info') + '))', 'short'), + stat(151, 'Threads', 'Total active threads in the selected processes.', 'sum(' + gauge('threads') + ')', 'short'), + stat(152, 'Handles', 'Total open handles in the selected processes.', 'sum(' + gauge('handles') + ')', 'short'), + stat(153, 'Process CPU busy', 'CPU time used by the selected processes as a share of all logical processors of the host, excluding Idle.', 'sum(' + rate('cpu_time_total') + ') / scalar(max(windows_cpu_logical_processor{job=~"$job", instance="$instance"}))', 'percentunit'), + stat(154, 'Private working set', 'Physical memory private to the selected processes; shared pages are excluded.', 'sum(' + gauge('working_set_private_bytes') + ')', 'bytes'), + stat(155, 'Private bytes', 'Total memory allocated by the selected processes that cannot be shared; it may include nonresident memory.', 'sum(' + gauge('private_bytes') + ')', 'bytes'), + + graph(112, 'Process CPU usage', 'User and privileged CPU time per process as a share of one logical processor. Values above 100% mean the process uses more than one core.', sumRates('cpu_time_total'), sumRates('cpu_time_total', ' @ end()'), 'percentunit'), + graph(113, 'Process working set', 'Physical memory in the working set of each process, including shared pages.', gauge('working_set_bytes'), gauge('working_set_bytes', ' @ end()'), 'bytes'), + graph(114, 'Process private bytes', 'Memory allocated by each process that cannot be shared with other processes.', gauge('private_bytes'), gauge('private_bytes', ' @ end()'), 'bytes'), + graph(115, 'Process I/O throughput', 'Total bytes issued for read, write and other I/O per process, including file, network and device operations.', sumRates('io_bytes_total'), sumRates('io_bytes_total', ' @ end()'), 'Bps'), + graph(116, 'Process threads', 'Active threads in each process.', gauge('threads'), gauge('threads', ' @ end()'), 'short'), + graph(117, 'Process handles', 'Open handles in each process. Steady growth can indicate a handle leak.', gauge('handles'), gauge('handles', ' @ end()'), 'short'), + graph(118, 'Process I/O operations', 'Total read, write and other I/O operations per second per process. Includes file, network and device I/O.', sumRates('io_operations_total'), sumRates('io_operations_total', ' @ end()'), 'iops'), + graph(119, 'Process page faults', 'Page faults per second by each process, including soft faults that do not require reading from disk.', rate('page_faults_total'), rate('page_faults_total', ' @ end()'), 'ops'), + ] +) diff --git a/contrib/mixin/dashboards/variables.libsonnet b/contrib/mixin/dashboards/variables.libsonnet index ec110ae3..bdc4dd9e 100644 --- a/contrib/mixin/dashboards/variables.libsonnet +++ b/contrib/mixin/dashboards/variables.libsonnet @@ -99,4 +99,30 @@ local new(name, definition) = common + query.spec.withLabel('Network interface') + query.spec.withMulti(true) + query.spec.withRegex('/^(?!isatap|Teredo|6to4).+$/'), + new('process', 'label_values(windows_process_info{job=~"$job", instance="$instance", process_id!="0"}, process)') + + query.spec.withCurrent({ + text: [ + 'All', + ], + value: [ + '$__all', + ], + }) + + query.spec.withIncludeAll(true) + + query.spec.withLabel('Process') + + query.spec.withMulti(true), + variables.CustomVariableKind.withKind() + + variables.CustomVariableKind.withSpec({ + name: 'process_top', + label: 'Top N processes', + description: 'Maximum number of processes per graph. Summary counters include all selected processes.', + query: '5,10,20', + current: { text: '10', value: '10' }, + options: [{ text: value, value: value, selected: value == '10' } for value in ['5', '10', '20']], + multi: false, + includeAll: false, + allowCustomValue: false, + hide: 'dontHide', + skipUrlSync: false, + }), ] diff --git a/contrib/mixin/dashboards/windows-exporter.libsonnet b/contrib/mixin/dashboards/windows-exporter.libsonnet index 79c40fa2..5229cd14 100644 --- a/contrib/mixin/dashboards/windows-exporter.libsonnet +++ b/contrib/mixin/dashboards/windows-exporter.libsonnet @@ -7,6 +7,7 @@ local tabs = [ import 'memory.libsonnet', import 'disk.libsonnet', import 'network.libsonnet', + import 'processes.libsonnet', import 'services.libsonnet', import 'gpu.libsonnet', import 'hyper_v.libsonnet', diff --git a/dashboard/README.md b/dashboard/README.md index 4ec8aa14..da4fa7fb 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -8,7 +8,7 @@ and takes several ideas from Grafana's [windows-observ-lib](https://github.com/g - Grafana 13 or later with a Prometheus data source. The file uses the v2 dashboard schema, which Grafana needs for tabs. - windows_exporter with the default collectors (`cpu`, `logical_disk`, `memory`, `net`, `os`, `physical_disk`, `service`, `system`). - The GPU, Hyper-V and Time tabs and the TCP and UDP rows of the Network tab need the `gpu`, `hyperv`, `time`, `tcp` and `udp` collectors, which are not enabled by default. + The Processes, GPU, Hyper-V and Time tabs and the TCP and UDP rows of the Network tab need the `process`, `gpu`, `hyperv`, `time`, `tcp` and `udp` collectors, which are not enabled by default. The process names in the GPU tab need the `process` collector. GPU temperature, fan, power and clock panels require WDDM 2.4 or newer and driver support; unsupported sensors are absent. @@ -24,6 +24,8 @@ Import the JSON file through **Dashboards > New > Import** and pick the Promethe | Instance | The host shown in all tabs except Fleet. | | Volume | Volumes shown in the Overview and Disk tabs. `HarddiskVolume*` are hidden. | | Network interface | Interfaces shown in the Overview and Network tabs. | +| Process | One or more process names shown in the Processes tab, or All. | +| Top N processes | Maximum processes per graph: 5, 10 (default), or 20. | The **Reboots** annotation marks each reboot of the selected host on all graphs. @@ -38,6 +40,7 @@ The **Reboots** annotation marks each reboot of the selected host on all graphs. | Disk | Volume size and free space, usage, busy time, throughput, IOPS, latency and queue length. | | Network | Throughput, utilization, packets, errors and discards per interface; TCP connection states and rates, segments and retransmissions; UDP datagrams and errors. | | Services | Running, pending and disabled services, automatic services that are not running, and services that started or stopped in the time range. | +| Processes | CPU usage, working set, private bytes, I/O throughput and operations, threads, handles and page faults per process, labelled with name and PID. | | GPU | Utilization by engine type, memory capacity, commitment and locality, temperature, fans, power, clocks, and top processes by GPU utilization and memory. | | Hyper-V | VM count and health, Hyper-V WMI health, host CPU time, CPU and memory per VM, virtual disks, virtual switches and VM network adapters. | | Time | Time zone, clock sync source, NTP time sources, clock offset and NTP round-trip delay. | @@ -45,6 +48,13 @@ The **Reboots** annotation marks each reboot of the selected host on all graphs. Click a hostname in the Fleet tab to open that host in the Overview tab. +The Processes tab starts with totals for all selected processes: process count, +threads, handles, CPU usage across the host, private working set and private bytes. +The synthetic Idle process (PID 0) is excluded. Each graph shows at most **Top N** +processes, ranked separately at the end of the time range, with a fixed set of +process IDs across the graph. Processes that exited before that point may not +appear. I/O graphs combine read, write and other operations per process. + ### Changing the dashboard Don't edit the JSON file by hand. It is generated from Jsonnet with [grafonnet](https://github.com/grafana/grafonnet) as part of the [windows_exporter mixin](../contrib/mixin): diff --git a/dashboard/windows-exporter-dashboard.json b/dashboard/windows-exporter-dashboard.json index 9672b6a0..6a1c1ad6 100644 --- a/dashboard/windows-exporter-dashboard.json +++ b/dashboard/windows-exporter-dashboard.json @@ -1787,6 +1787,942 @@ } } }, + "panel-112": { + "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": "sum by (process, process_id) (rate(windows_process_cpu_time_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval])) and on (process, process_id) topk($process_top, sum by (process, process_id) (rate(windows_process_cpu_time_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval] @ end())))", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "User and privileged CPU time per process as a share of one logical processor. Values above 100% mean the process uses more than one core. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 112, + "links": [], + "title": "Process CPU usage", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-113": { + "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": "windows_process_working_set_bytes{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} and on (process, process_id) topk($process_top, windows_process_working_set_bytes{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} @ end())", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Physical memory in the working set of each process, including shared pages. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 113, + "links": [], + "title": "Process working set", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-114": { + "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": "windows_process_private_bytes{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} and on (process, process_id) topk($process_top, windows_process_private_bytes{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} @ end())", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Memory allocated by each process that cannot be shared with other processes. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 114, + "links": [], + "title": "Process private bytes", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-115": { + "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": "sum by (process, process_id) (rate(windows_process_io_bytes_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval])) and on (process, process_id) topk($process_top, sum by (process, process_id) (rate(windows_process_io_bytes_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval] @ end())))", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Total bytes issued for read, write and other I/O per process, including file, network and device operations. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 115, + "links": [], + "title": "Process I/O throughput", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-116": { + "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": "windows_process_threads{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} and on (process, process_id) topk($process_top, windows_process_threads{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} @ end())", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Active threads in each process. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 116, + "links": [], + "title": "Process threads", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-117": { + "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": "windows_process_handles{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} and on (process, process_id) topk($process_top, windows_process_handles{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"} @ end())", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Open handles in each process. Steady growth can indicate a handle leak. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 117, + "links": [], + "title": "Process handles", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-118": { + "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": "sum by (process, process_id) (rate(windows_process_io_operations_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval])) and on (process, process_id) topk($process_top, sum by (process, process_id) (rate(windows_process_io_operations_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval] @ end())))", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Total read, write and other I/O operations per second per process. Includes file, network and device I/O. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 118, + "links": [], + "title": "Process I/O operations", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "iops" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, + "panel-119": { + "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": "rate(windows_process_page_faults_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval]) and on (process, process_id) topk($process_top, rate(windows_process_page_faults_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval] @ end()))", + "instant": false, + "legendFormat": "{{process}} ({{process_id}})", + "range": true + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": { + "maxDataPoints": 300 + }, + "transformations": [] + } + }, + "description": "Page faults per second by each process, including soft faults that do not require reading from disk. Shows the Top N selected processes ranked at the end of the time range; that set stays fixed throughout the graph. Requires the process collector.", + "id": 119, + "links": [], + "title": "Process page faults", + "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": "off" + } + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + } + }, + "version": "" + } + } + }, "panel-12": { "kind": "Panel", "spec": { @@ -4584,6 +5520,504 @@ } } }, + "panel-150": { + "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 (process_id) (windows_process_info{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}))", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "Number of distinct process IDs currently collected, excluding Idle. Includes all selected processes, regardless of Top N. Requires the process collector.", + "id": 150, + "links": [], + "title": "Processes", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-151": { + "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": "sum(windows_process_threads{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"})", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "Total active threads in the selected processes. Includes all selected processes, regardless of Top N. Requires the process collector.", + "id": 151, + "links": [], + "title": "Threads", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-152": { + "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": "sum(windows_process_handles{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"})", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "Total open handles in the selected processes. Includes all selected processes, regardless of Top N. Requires the process collector.", + "id": 152, + "links": [], + "title": "Handles", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-153": { + "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": "sum(rate(windows_process_cpu_time_total{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"}[$__rate_interval])) / scalar(max(windows_cpu_logical_processor{job=~\"$job\", instance=\"$instance\"}))", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "CPU time used by the selected processes as a share of all logical processors of the host, excluding Idle. Includes all selected processes, regardless of Top N. Requires the process collector.", + "id": 153, + "links": [], + "title": "Process CPU busy", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-154": { + "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": "sum(windows_process_working_set_private_bytes{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"})", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "Physical memory private to the selected processes; shared pages are excluded. Includes all selected processes, regardless of Top N. Requires the process collector.", + "id": 154, + "links": [], + "title": "Private working set", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, + "panel-155": { + "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": "sum(windows_process_private_bytes{job=~\"$job\", instance=\"$instance\", process=~\"$process\", process_id!=\"0\"})", + "instant": true, + "legendFormat": "__auto", + "range": false + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "Total memory allocated by the selected processes that cannot be shared; it may include nonresident memory. Includes all selected processes, regardless of Top N. Requires the process collector.", + "id": 155, + "links": [], + "title": "Private bytes", + "vizConfig": { + "group": "stat", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + } + }, + "version": "" + } + } + }, "panel-16": { "kind": "Panel", "spec": { @@ -16298,6 +17732,201 @@ "title": "Network" } }, + { + "kind": "TabsLayoutTab", + "spec": { + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-150" + }, + "height": 4, + "width": 4, + "x": 0, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-151" + }, + "height": 4, + "width": 4, + "x": 4, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-152" + }, + "height": 4, + "width": 4, + "x": 8, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-153" + }, + "height": 4, + "width": 4, + "x": 12, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-154" + }, + "height": 4, + "width": 4, + "x": 16, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-155" + }, + "height": 4, + "width": 4, + "x": 20, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-112" + }, + "height": 8, + "width": 12, + "x": 0, + "y": 4 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-113" + }, + "height": 8, + "width": 12, + "x": 12, + "y": 4 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-114" + }, + "height": 8, + "width": 12, + "x": 0, + "y": 12 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-115" + }, + "height": 8, + "width": 12, + "x": 12, + "y": 12 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-116" + }, + "height": 8, + "width": 12, + "x": 0, + "y": 20 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-117" + }, + "height": 8, + "width": 12, + "x": 12, + "y": 20 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-118" + }, + "height": 8, + "width": 12, + "x": 0, + "y": 28 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-119" + }, + "height": 8, + "width": 12, + "x": 12, + "y": 28 + } + } + ] + } + }, + "title": "Processes" + } + }, { "kind": "TabsLayoutTab", "spec": { @@ -17589,6 +19218,79 @@ "skipUrlSync": false, "sort": "alphabeticalAsc" } + }, + { + "kind": "QueryVariable", + "spec": { + "allowCustomValue": true, + "current": { + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "definition": "label_values(windows_process_info{job=~\"$job\", instance=\"$instance\", process_id!=\"0\"}, process)", + "hide": "dontHide", + "includeAll": true, + "label": "Process", + "multi": true, + "name": "process", + "options": [], + "query": { + "datasource": { + "name": "${datasource}" + }, + "group": "prometheus", + "kind": "DataQuery", + "spec": { + "qryType": 1, + "query": "label_values(windows_process_info{job=~\"$job\", instance=\"$instance\", process_id!=\"0\"}, process)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "version": "v0" + }, + "refresh": "onTimeRangeChanged", + "regex": "", + "skipUrlSync": false, + "sort": "alphabeticalAsc" + } + }, + { + "kind": "CustomVariable", + "spec": { + "allowCustomValue": false, + "current": { + "text": "10", + "value": "10" + }, + "description": "Maximum number of processes per graph. Summary counters include all selected processes.", + "hide": "dontHide", + "includeAll": false, + "label": "Top N processes", + "multi": false, + "name": "process_top", + "options": [ + { + "selected": false, + "text": "5", + "value": "5" + }, + { + "selected": true, + "text": "10", + "value": "10" + }, + { + "selected": false, + "text": "20", + "value": "20" + } + ], + "query": "5,10,20", + "skipUrlSync": false + } } ] }