Files
windows_exporter/contrib/mixin/dashboards/overview.libsonnet
T

489 lines
15 KiB
Jsonnet

local b = import 'builders.libsonnet';
function(on)
b.tab(
'Overview',
b.rows([
b.row('Summary', b.flow([if on('os') then [10, 4, 4], if on('system') then [11, 3, 4], if on('cpu') then [12, 2, 4], if on('memory') then [13, 2, 4], if on('cpu') then [14, 3, 4], if on('memory') then [15, 3, 4], if on('memory') then [16, 3, 4], if on('service') then [17, 4, 4]])),
b.row('CPU and memory', b.flow([if on('cpu') then [18, 12, 8], if on('memory') then [19, 12, 8]])),
b.row('Storage and network', b.flow([if on('logical_disk') then [20, 8, 8], if on('logical_disk') then [21, 8, 8], if on('net') then [22, 8, 8]])),
]),
[
b.panel.new(10, 'Operating system', 'stat')
+ b.panel.withDescription('Windows product name and version reported by the os collector. Use this to distinguish hosts when investigating version-specific behavior.')
+ b.panel.withQueries([
b.query.new('windows_os_info{job=~"$job", instance="$instance"}', 'A')
+ b.query.withInstant()
+ b.query.withFormat('table'),
])
+ b.panel.withDefaults({
unit: '',
})
+ b.panel.withOptions({
colorMode: 'none',
reduceOptions: {
fields: '/^product$/',
},
textMode: 'value',
}),
b.panel.new(11, 'Uptime', 'stat')
+ b.panel.withDescription('Time since the last boot.')
+ b.panel.withQueries([
b.query.new('time() - windows_system_boot_time_timestamp{job=~"$job", instance="$instance"}', 'A')
+ b.query.withInstant(),
])
+ b.panel.withDefaults({
thresholds: {
steps: [
{
color: 'orange',
value: null,
},
{
color: 'text',
value: 3600,
},
],
},
unit: 'dtdurations',
}),
b.panel.new(12, 'CPUs', 'stat')
+ b.panel.withDescription('Number of logical processors available to Windows, including SMT threads. This is the logical CPU count rather than the number of physical sockets.')
+ b.panel.withQueries([
b.query.new('windows_cpu_logical_processor{job=~"$job", instance="$instance"}', 'A')
+ b.query.withInstant(),
]),
b.panel.new(13, 'RAM', 'stat')
+ b.panel.withDescription('Total physical memory visible to Windows in bytes. Compare with used memory and commit charge when investigating memory pressure.')
+ b.panel.withQueries([
b.query.new('windows_memory_physical_total_bytes{job=~"$job", instance="$instance"}', 'A')
+ b.query.withInstant(),
])
+ b.panel.withDefaults({
decimals: 1,
unit: 'bytes',
}),
b.panel.new(14, 'CPU busy', 'stat')
+ b.panel.withDescription('Percentage of non-idle CPU time averaged across logical processors over the rate interval. Sustained high values together with a growing processor queue can indicate CPU contention.')
+ b.panel.withQueries([
b.query.new('100 * (1 - avg by (instance) (clamp_max(rate(windows_cpu_time_total{job=~"$job", instance="$instance", mode="idle"}[$__rate_interval]), 1)))', 'A'),
])
+ b.panel.withDefaults({
decimals: 1,
max: 100,
min: 0,
thresholds: {
steps: [
{
color: 'green',
value: null,
},
{
color: 'orange',
value: 80,
},
{
color: 'red',
value: 90,
},
],
},
unit: 'percent',
})
+ b.panel.withOptions({
graphMode: 'area',
}),
b.panel.new(15, 'Memory used', 'stat')
+ b.panel.withDescription('Percentage of physical memory in use, calculated as total minus available memory. This differs from commit charge, which measures promised virtual memory against the commit limit.')
+ b.panel.withQueries([
b.query.new('100 * (1 - windows_memory_physical_free_bytes{job=~"$job", instance="$instance"} / windows_memory_physical_total_bytes{job=~"$job", instance="$instance"})', 'A'),
])
+ b.panel.withDefaults({
decimals: 1,
max: 100,
min: 0,
thresholds: {
steps: [
{
color: 'green',
value: null,
},
{
color: 'orange',
value: 80,
},
{
color: 'red',
value: 90,
},
],
},
unit: 'percent',
})
+ b.panel.withOptions({
graphMode: 'area',
}),
b.panel.new(16, 'Commit used', 'stat')
+ b.panel.withDescription('Committed virtual memory as a share of the commit limit (physical memory + page files). Allocations fail at 100%.')
+ b.panel.withQueries([
b.query.new('100 * windows_memory_committed_bytes{job=~"$job", instance="$instance"} / windows_memory_commit_limit_bytes{job=~"$job", instance="$instance"}', 'A'),
])
+ b.panel.withDefaults({
decimals: 1,
max: 100,
min: 0,
thresholds: {
steps: [
{
color: 'green',
value: null,
},
{
color: 'orange',
value: 80,
},
{
color: 'red',
value: 90,
},
],
},
unit: 'percent',
})
+ b.panel.withOptions({
graphMode: 'area',
}),
b.panel.new(17, 'Stopped auto services', 'stat')
+ b.panel.withDescription('Services with start mode "auto" that are not running. See the Services tab for names.')
+ b.panel.withQueries([
b.query.new('count(windows_service_state{job=~"$job", instance="$instance", state="running"} == 0 and on (name) windows_service_start_mode{job=~"$job", instance="$instance", start_mode="auto"} == 1) or vector(0)', 'A')
+ b.query.withInstant(),
])
+ b.panel.withDefaults({
thresholds: {
steps: [
{
color: 'green',
value: null,
},
{
color: 'orange',
value: 1,
},
],
},
}),
b.panel.new(18, 'CPU utilization', 'timeseries')
+ b.panel.withDescription('Percentage of non-idle CPU time averaged across logical processors. This measures CPU time rather than the frequency-adjusted processor utility shown by Windows Task Manager.')
+ b.panel.withQueries([
b.query.new('100 * (1 - avg by (instance) (clamp_max(rate(windows_cpu_time_total{job=~"$job", instance="$instance", mode="idle"}[$__rate_interval]), 1)))', 'A')
+ b.query.withLegendFormat('CPU busy'),
])
+ b.panel.withDefaults({
max: 100,
min: 0,
thresholds: {
steps: [
{
color: 'green',
value: null,
},
{
color: 'orange',
value: 80,
},
{
color: 'red',
value: 90,
},
],
},
unit: 'percent',
})
+ b.panel.withOptions({
legend: {
calcs: [],
displayMode: 'list',
},
}),
b.panel.new(19, 'Physical memory', 'timeseries')
+ b.panel.withDescription('Available memory is the standby (cache), free and zero page lists.')
+ b.panel.withQueries([
b.query.new('windows_memory_physical_total_bytes{job=~"$job", instance="$instance"} - windows_memory_physical_free_bytes{job=~"$job", instance="$instance"}', 'A')
+ b.query.withLegendFormat('used'),
b.query.new('windows_memory_physical_free_bytes{job=~"$job", instance="$instance"}', 'B')
+ b.query.withLegendFormat('available'),
])
+ b.panel.withDefaults({
custom: {
fillOpacity: 40,
stacking: {
mode: 'normal',
},
},
min: 0,
unit: 'bytes',
})
+ b.panel.withOptions({
legend: {
calcs: [],
displayMode: 'list',
},
})
+ b.panel.withOverrides([
{
matcher: {
id: 'byName',
options: 'used',
},
properties: [
{
id: 'color',
value: {
fixedColor: 'orange',
mode: 'fixed',
},
},
],
},
{
matcher: {
id: 'byName',
options: 'available',
},
properties: [
{
id: 'color',
value: {
fixedColor: 'green',
mode: 'fixed',
},
},
],
},
]),
b.panel.new(20, 'Volumes', 'table')
+ b.panel.withDescription('Size, available space and used percentage of each selected logical volume. Windows free-space counters can lag by 10 to 15 minutes; use trends rather than treating a single sample as immediate confirmation of reclaimed space.')
+ b.panel.withQueries([
b.query.new('windows_logical_disk_size_bytes{job=~"$job", instance="$instance", volume=~"$volume"}', 'A')
+ b.query.withInstant()
+ b.query.withFormat('table'),
b.query.new('windows_logical_disk_free_bytes{job=~"$job", instance="$instance", volume=~"$volume"}', 'B')
+ b.query.withInstant()
+ b.query.withFormat('table'),
b.query.new('100 * (1 - windows_logical_disk_free_bytes{job=~"$job", instance="$instance", volume=~"$volume"} / windows_logical_disk_size_bytes{job=~"$job", instance="$instance", volume=~"$volume"})', 'C')
+ b.query.withInstant()
+ b.query.withFormat('table'),
])
+ b.panel.withTransformations([
{
group: 'joinByField',
kind: 'Transformation',
spec: {
options: {
byField: 'volume',
mode: 'outer',
},
},
},
{
group: 'organize',
kind: 'Transformation',
spec: {
options: {
excludeByName: {
Time: true,
'Time 1': true,
'Time 2': true,
'Time 3': true,
__name__: true,
instance: true,
'instance 1': true,
'instance 2': true,
'instance 3': true,
job: true,
'job 1': true,
'job 2': true,
'job 3': true,
port: true,
'port 1': true,
'port 2': true,
'port 3': true,
},
includeByName: {},
indexByName: {
'Value #A': 1,
'Value #B': 2,
'Value #C': 3,
volume: 0,
},
renameByName: {
'Value #A': 'Size',
'Value #B': 'Free',
'Value #C': 'Used',
volume: 'Volume',
},
},
},
},
])
+ b.panel.withOverrides([
{
matcher: {
id: 'byName',
options: 'Value #A',
},
properties: [
{
id: 'unit',
value: 'bytes',
},
],
},
{
matcher: {
id: 'byName',
options: 'Value #B',
},
properties: [
{
id: 'unit',
value: 'bytes',
},
],
},
{
matcher: {
id: 'byName',
options: 'Value #C',
},
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,
},
],
},
]),
b.panel.new(21, 'Disk throughput', 'timeseries')
+ b.panel.withDescription('Sum over the selected volumes. Reads are drawn below the axis.')
+ b.panel.withQueries([
b.query.new('sum(rate(windows_logical_disk_write_bytes_total{job=~"$job", instance="$instance", volume=~"$volume"}[$__rate_interval]))', 'A')
+ b.query.withLegendFormat('write'),
b.query.new('sum(rate(windows_logical_disk_read_bytes_total{job=~"$job", instance="$instance", volume=~"$volume"}[$__rate_interval]))', 'B')
+ b.query.withLegendFormat('read'),
])
+ b.panel.withDefaults({
unit: 'Bps',
})
+ b.panel.withOptions({
legend: {
calcs: [],
displayMode: 'list',
},
})
+ b.panel.withOverrides([
{
matcher: {
id: 'byRegexp',
options: 'read',
},
properties: [
{
id: 'custom.transform',
value: 'negative-Y',
},
],
},
]),
b.panel.new(22, 'Network throughput', 'timeseries')
+ b.panel.withDescription('Sum over the selected interfaces. Received traffic is drawn below the axis.')
+ b.panel.withQueries([
b.query.new('sum(rate(windows_net_bytes_sent_total{job=~"$job", instance="$instance", nic=~"$nic"}[$__rate_interval])) * 8', 'A')
+ b.query.withLegendFormat('sent'),
b.query.new('sum(rate(windows_net_bytes_received_total{job=~"$job", instance="$instance", nic=~"$nic"}[$__rate_interval])) * 8', 'B')
+ b.query.withLegendFormat('received'),
])
+ b.panel.withDefaults({
unit: 'bps',
})
+ b.panel.withOptions({
legend: {
calcs: [],
displayMode: 'list',
},
})
+ b.panel.withOverrides([
{
matcher: {
id: 'byRegexp',
options: 'received',
},
properties: [
{
id: 'custom.transform',
value: 'negative-Y',
},
],
},
]),
]
)