From 17d6a993fc17d533460c5f40f3908c708e057c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 23 May 2024 18:45:17 +0200 Subject: Merging upstream version 18.2.3. Signed-off-by: Daniel Baumann --- monitoring/ceph-mixin/dashboards/host.libsonnet | 75 +++++- monitoring/ceph-mixin/dashboards/osd.libsonnet | 285 +++++++++++++++----- .../ceph-mixin/dashboards/piechart_panel.libsonnet | 73 ++++++ monitoring/ceph-mixin/dashboards/pool.libsonnet | 287 ++++++++++++++++++--- monitoring/ceph-mixin/dashboards/rbd.libsonnet | 228 +++++++++++++--- monitoring/ceph-mixin/dashboards/rgw.libsonnet | 67 +++-- monitoring/ceph-mixin/dashboards/utils.libsonnet | 83 +++++- 7 files changed, 928 insertions(+), 170 deletions(-) create mode 100644 monitoring/ceph-mixin/dashboards/piechart_panel.libsonnet (limited to 'monitoring/ceph-mixin/dashboards') diff --git a/monitoring/ceph-mixin/dashboards/host.libsonnet b/monitoring/ceph-mixin/dashboards/host.libsonnet index 4fd35c3ed..674f678a1 100644 --- a/monitoring/ceph-mixin/dashboards/host.libsonnet +++ b/monitoring/ceph-mixin/dashboards/host.libsonnet @@ -719,19 +719,70 @@ local g = import 'grafonnet/grafana.libsonnet'; 11, 9 ), - $.addTableSchema( - '$datasource', - 'This table shows the 10 hosts with the highest number of slow ops', - { col: 2, desc: true }, - [ - $.overviewStyle('Instance', 'instance', 'string', 'short'), - $.overviewStyle('Slow Ops', 'Value', 'number', 'none'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + + $.addTableExtended( + datasource='${datasource}', + title='Top Slow Ops per Host', + gridPosition={ h: 8, w: 6, x: 0, y: 30 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'instance' }, + properties: [ + { id: 'displayName', value: 'Instance' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'Slow Ops' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Top Slow Ops per Host', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + } + { + id: 'organize', + options: { + excludeByName: { + Time: true, + cluster: true, + }, + indexByName: {}, + renameByName: {}, + includeByName: {}, + }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -743,6 +794,6 @@ local g = import 'grafonnet/grafana.libsonnet'; 1, true ) - ) + { gridPos: { x: 0, y: 40, w: 4, h: 8 } }, + ), ]), } diff --git a/monitoring/ceph-mixin/dashboards/osd.libsonnet b/monitoring/ceph-mixin/dashboards/osd.libsonnet index 0ea43c96f..ca25b0630 100644 --- a/monitoring/ceph-mixin/dashboards/osd.libsonnet +++ b/monitoring/ceph-mixin/dashboards/osd.libsonnet @@ -1,5 +1,6 @@ local g = import 'grafonnet/grafana.libsonnet'; + (import 'utils.libsonnet') { 'osds-overview.json': $.dashboardSchema( @@ -89,19 +90,70 @@ local g = import 'grafonnet/grafana.libsonnet'; ), ], ), - $.addTableSchema( - '$datasource', - "This table shows the osd's that are delivering the 10 highest read latencies within the cluster", - { col: 2, desc: true }, - [ - $.overviewStyle('OSD ID', 'ceph_daemon', 'string', 'short'), - $.overviewStyle('Latency (ms)', 'Value', 'number', 'none'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + + $.addTableExtended( + datasource='${datasource}', + title='Highest READ Latencies', + gridPosition={ h: 8, w: 4, x: 8, y: 0 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'ceph_daemon' }, + properties: [ + { id: 'displayName', value: 'OSD ID' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'Latency (ms)' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Highest READ Latencies', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + }, + { + id: 'organize', + options: { + excludeByName: { + Time: true, + cluster: true, + }, + indexByName: {}, + renameByName: {}, + includeByName: {}, + }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -119,7 +171,8 @@ local g = import 'grafonnet/grafana.libsonnet'; 1, true ) - ) + { gridPos: { x: 8, y: 0, w: 4, h: 8 } }, + ), + $.simpleGraphPanel( { '@95%ile write': '#e0752d', @@ -164,21 +217,80 @@ local g = import 'grafonnet/grafana.libsonnet'; ), ], ), - $.addTableSchema( - '$datasource', - "This table shows the osd's that are delivering the 10 highest write latencies within the cluster", - { col: 2, desc: true }, - [ - $.overviewStyle( - 'OSD ID', 'ceph_daemon', 'string', 'short' - ), - $.overviewStyle('Latency (ms)', 'Value', 'number', 'none'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + + $.addTableExtended( + datasource='${datasource}', + title='Highest WRITE Latencies', + description="This table shows the osd's that are delivering the 10 highest write latencies within the cluster", + gridPosition={ h: 8, w: 4, x: 20, y: 0 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'ceph_daemon' }, + properties: [ + { id: 'displayName', value: 'OSD ID' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'Latency (ms)' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'mappings', value: [{ type: 'value', options: { NaN: { text: '0.00', index: 0 } } }] }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Highest WRITE Latencies', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + }, + { + id: 'organize', + options: { + excludeByName: { + Time: true, + cluster: true, + }, + indexByName: {}, + renameByName: {}, + includeByName: {}, + }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -194,29 +306,20 @@ local g = import 'grafonnet/grafana.libsonnet'; 1, true ) - ) + { gridPos: { x: 20, y: 0, w: 4, h: 8 } }, - $.simplePieChart( - {}, '', 'OSD Types Summary' - ) + ), + + $.pieChartPanel('OSD Types Summary', '', '$datasource', { x: 0, y: 8, w: 4, h: 8 }, 'table', 'bottom', true, ['percent'], { mode: 'single', sort: 'none' }, 'pie', ['percent', 'value'], 'palette-classic') .addTarget( $.addTargetSchema('count by (device_class) (ceph_osd_metadata{%(matchers)s})' % $.matchers(), '{{device_class}}') - ) + { gridPos: { x: 0, y: 8, w: 4, h: 8 } }, - $.simplePieChart( - { 'Non-Encrypted': '#E5AC0E' }, '', 'OSD Objectstore Types' - ) - .addTarget( - $.addTargetSchema( - 'count(ceph_bluefs_wal_total_bytes{%(matchers)s})' % $.matchers(), 'bluestore', 'time_series', 2 - ) - ) - .addTarget( - $.addTargetSchema( - 'absent(ceph_bluefs_wal_total_bytes{%(matchers)s}) * count(ceph_osd_metadata{%(matchers)s})' % $.matchers(), 'filestore', 'time_series', 2 - ) - ) + { gridPos: { x: 4, y: 8, w: 4, h: 8 } }, - $.simplePieChart( - {}, 'The pie chart shows the various OSD sizes used within the cluster', 'OSD Size Summary' - ) + ), + $.pieChartPanel('OSD Objectstore Types', '', '$datasource', { x: 4, y: 8, w: 4, h: 8 }, 'table', 'bottom', true, ['percent'], { mode: 'single', sort: 'none' }, 'pie', ['percent', 'value'], 'palette-classic') + .addTarget($.addTargetSchema( + 'count(ceph_bluefs_wal_total_bytes{%(matchers)s})' % $.matchers(), 'bluestore', 'time_series', 2 + )) + .addTarget($.addTargetSchema( + 'absent(ceph_bluefs_wal_total_bytes{job=~"$job"}) * count(ceph_osd_metadata{job=~"$job"})' % $.matchers(), 'filestore', 'time_series', 2 + )), + $.pieChartPanel('OSD Size Summary', 'The pie chart shows the various OSD sizes used within the cluster', '$datasource', { x: 8, y: 8, w: 4, h: 8 }, 'table', 'bottom', true, ['percent'], { mode: 'single', sort: 'none' }, 'pie', ['percent', 'value'], 'palette-classic') .addTarget($.addTargetSchema( 'count(ceph_osd_stat_bytes{%(matchers)s} < 1099511627776)' % $.matchers(), '<1TB', 'time_series', 2 )) @@ -243,7 +346,7 @@ local g = import 'grafonnet/grafana.libsonnet'; )) .addTarget($.addTargetSchema( 'count(ceph_osd_stat_bytes{%(matchers)s} >= 13194139533312)' % $.matchers(), '<12TB+', 'time_series', 2 - )) + { gridPos: { x: 8, y: 8, w: 4, h: 8 } }, + )), g.graphPanel.new(bars=true, datasource='$datasource', title='Distribution of PGs per OSD', @@ -257,7 +360,7 @@ local g = import 'grafonnet/grafana.libsonnet'; nullPointMode='null') .addTarget($.addTargetSchema( 'ceph_osd_numpg{%(matchers)s}' % $.matchers(), 'PGs per OSD', 'time_series', 1, true - )) + { gridPos: { x: 12, y: 8, w: 8, h: 8 } }, + )) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: 'short', custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: 12, y: 8, w: 8, h: 8 } }, $.gaugeSingleStatPanel( 'percentunit', 'OSD onode Hits Ratio', @@ -300,19 +403,75 @@ local g = import 'grafonnet/grafana.libsonnet'; .addTargets([$.addTargetSchema( 'round(sum(rate(ceph_pool_wr{%(matchers)s}[$__rate_interval])))' % $.matchers(), 'Writes' )]), - $.addTableSchema( - '$datasource', - 'This table shows the 10 OSDs with the highest number of slow ops', - { col: 2, desc: true }, - [ - $.overviewStyle('OSD ID', 'ceph_daemon', 'string', 'short'), - $.overviewStyle('Slow Ops', 'Value', 'number', 'none'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + + $.addTableExtended( + datasource='${datasource}', + title='Top Slow Ops', + description='This table shows the 10 OSDs with the highest number of slow ops', + gridPosition={ h: 8, w: 5, x: 0, y: 25 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'ceph_daemon' }, + properties: [ + { id: 'displayName', value: 'OSD ID' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'Slow Ops' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Top Slow Ops', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + }, + { + id: 'organize', + options: { + excludeByName: { + Time: true, + __name__: true, + instance: true, + job: true, + type: true, + cluster: true, + }, + indexByName: {}, + renameByName: {}, + includeByName: {}, + }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -324,7 +483,7 @@ local g = import 'grafonnet/grafana.libsonnet'; 1, true ) - ) + { gridPos: { x: 0, y: 20, w: 4, h: 8 } }, + ), ]), 'osd-device-details.json': local OsdDeviceDetailsPanel(title, @@ -342,7 +501,7 @@ local g = import 'grafonnet/grafana.libsonnet'; $.graphPanelSchema({}, title, description, - 'null', + 'null as zero', false, formatY1, 'short', @@ -357,7 +516,7 @@ local g = import 'grafonnet/grafana.libsonnet'; legendFormat1), $.addTargetSchema(expr2, legendFormat2), ] - ) + { gridPos: { x: x, y: y, w: w, h: h } }; + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }; $.dashboardSchema( 'OSD device details', @@ -613,6 +772,6 @@ local g = import 'grafonnet/grafana.libsonnet'; ) ||| % $.matchers(), '{{device}} on {{instance}}' - )) + { gridPos: { x: 18, y: 11, w: 6, h: 9 } }, + )) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: 'percentunit', custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: 18, y: 11, w: 6, h: 9 } }, ]), } diff --git a/monitoring/ceph-mixin/dashboards/piechart_panel.libsonnet b/monitoring/ceph-mixin/dashboards/piechart_panel.libsonnet new file mode 100644 index 000000000..68ff71954 --- /dev/null +++ b/monitoring/ceph-mixin/dashboards/piechart_panel.libsonnet @@ -0,0 +1,73 @@ +{ + /** + * Creates a pie chart panel. + * + * @name pieChartPanel.new + * + * @param title The title of the pie chart panel. + * @param description (default `''`) Description of the panel + * @param datasource (optional) Datasource + * @param pieType (default `'pie'`) Type of pie chart (one of pie or donut) + * + * @method addTarget(target) Adds a target object. + */ + new( + title, + description='', + datasource=null, + gridPos={}, + displayMode='table', + placement='bottom', + showLegend=true, + displayLabels=[], + tooltip={}, + pieType='pie', + values=[], + colorMode='auto', + overrides=[], + reduceOptions={}, + ):: { + type: 'piechart', + [if description != null then 'description']: description, + title: title, + gridPos: gridPos, + datasource: datasource, + options: { + legend: { + calcs: [], + values: values, + displayMode: displayMode, + placement: placement, + showLegend: showLegend, + }, + pieType: pieType, + tooltip: tooltip, + displayLabels: displayLabels, + reduceOptions: reduceOptions, + }, + fieldConfig: { + defaults: { + color: { mode: colorMode }, + mappings: [], + custom: { + hideFrom: { + legend: false, + tooltip: false, + viz: false, + }, + }, + }, + overrides: overrides, + }, + targets: [ + ], + _nextTarget:: 0, + addTarget(target):: self { + // automatically ref id in added targets. + local nextTarget = super._nextTarget, + _nextTarget: nextTarget + 1, + targets+: [target { refId: std.char(std.codepoint('A') + nextTarget) }], + }, + addTargets(targets):: std.foldl(function(p, t) p.addTarget(t), targets, self), + }, +} diff --git a/monitoring/ceph-mixin/dashboards/pool.libsonnet b/monitoring/ceph-mixin/dashboards/pool.libsonnet index 6444335d9..87839963f 100644 --- a/monitoring/ceph-mixin/dashboards/pool.libsonnet +++ b/monitoring/ceph-mixin/dashboards/pool.libsonnet @@ -158,36 +158,264 @@ local g = import 'grafonnet/grafana.libsonnet'; 3, 3 ), - $.addTableSchema( - '$datasource', - '', - { col: 5, desc: true }, - [ - $.overviewStyle('', 'Time', 'hidden', 'short'), - $.overviewStyle('', 'instance', 'hidden', 'short'), - $.overviewStyle('', 'job', 'hidden', 'short'), - $.overviewStyle('Pool Name', 'name', 'string', 'short'), - $.overviewStyle('Pool ID', 'pool_id', 'hidden', 'none'), - $.overviewStyle('Compression Factor', 'Value #A', 'number', 'none'), - $.overviewStyle('% Used', 'Value #D', 'number', 'percentunit', 'value', ['70', '85']), - $.overviewStyle('Usable Free', 'Value #B', 'number', 'bytes'), - $.overviewStyle('Compression Eligibility', 'Value #C', 'number', 'percent'), - $.overviewStyle('Compression Savings', 'Value #E', 'number', 'bytes'), - $.overviewStyle('Growth (5d)', 'Value #F', 'number', 'bytes', 'value', ['0', '0']), - $.overviewStyle('IOPS', 'Value #G', 'number', 'none'), - $.overviewStyle('Bandwidth', 'Value #H', 'number', 'Bps'), - $.overviewStyle('', '__name__', 'hidden', 'short'), - $.overviewStyle('', 'type', 'hidden', 'short'), - $.overviewStyle('', 'compression_mode', 'hidden', 'short'), - $.overviewStyle('Type', 'description', 'string', 'short'), - $.overviewStyle('Stored', 'Value #J', 'number', 'bytes'), - $.overviewStyle('', 'Value #I', 'hidden', 'short'), - $.overviewStyle('Compression', 'Value #K', 'string', 'short', null, [], [{ text: 'ON', value: '1' }]), + + $.addTableExtended( + datasource='${datasource}', + title='Pool Overview', + gridPosition={ h: 6, w: 24, x: 0, y: 3 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'auto', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'Time' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'instance' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'job' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'name' }, + properties: [ + { id: 'displayName', value: 'Pool Name' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'pool_id' }, + properties: [ + { id: 'displayName', value: 'Pool ID' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #A' }, + properties: [ + { id: 'displayName', value: 'Compression Factor' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #D' }, + properties: [ + { id: 'displayName', value: '% Used' }, + { id: 'unit', value: 'percentunit' }, + { id: 'decimals', value: 2 }, + { id: 'custom.cellOptions', value: { type: 'color-text' } }, + { + id: 'thresholds', + value: { + mode: 'absolute', + steps: [ + { + color: 'rgba(245, 54, 54, 0.9)', + value: null, + }, + { + color: 'rgba(237, 129, 40, 0.89)', + value: 70, + }, + { + color: 'rgba(50, 172, 45, 0.97)', + value: 85, + }, + ], + }, + }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #B' }, + properties: [ + { id: 'displayName', value: 'Usable Free' }, + { id: 'unit', value: 'bytes' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #C' }, + properties: [ + { id: 'displayName', value: 'Compression Eligibility' }, + { id: 'unit', value: 'percent' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #E' }, + properties: [ + { id: 'displayName', value: 'Compression Savings' }, + { id: 'unit', value: 'bytes' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #F' }, + properties: [ + { id: 'displayName', value: 'Growth (5d)' }, + { id: 'unit', value: 'bytes' }, + { id: 'decimals', value: 2 }, + { id: 'custom.cellOptions', value: { type: 'color-text' } }, + { + id: 'thresholds', + value: { + mode: 'absolute', + steps: [ + { + color: 'rgba(245, 54, 54, 0.9)', + value: null, + }, + { + color: 'rgba(237, 129, 40, 0.89)', + value: 70, + }, + { + color: 'rgba(50, 172, 45, 0.97)', + value: 85, + }, + ], + }, + }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #G' }, + properties: [ + { id: 'displayName', value: 'IOPS' }, + { id: 'unit', value: 'none' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #H' }, + properties: [ + { id: 'displayName', value: 'Bandwidth' }, + { id: 'unit', value: 'Bps' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: '__name__' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'type' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'compression_mode' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'description' }, + properties: [ + { id: 'displayName', value: 'Type' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #J' }, + properties: [ + { id: 'displayName', value: 'Stored' }, + { id: 'unit', value: 'bytes' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #I' }, + properties: [ + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, + { + matcher: { id: 'byName', options: 'Value #K' }, + properties: [ + { id: 'displayName', value: 'Compression' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + ], + }, ], - 'Pool Overview', - 'table' + pluginVersion='10.4.0' ) - .addTargets( + .addTransformations([ + { + id: 'merge', + options: {}, + }, + { + id: 'seriesToRows', + options: {}, + }, + { + id: 'organize', + options: { + excludeByName: { + Time: true, + 'Value #A': true, + instance: true, + job: true, + pool_id: true, + 'Value #B': false, + 'Value #C': true, + __name__: true, + compression_mode: true, + type: true, + 'Value #I': true, + 'Value #K': true, + 'Value #D': false, + 'Value #E': true, + cluster: true, + }, + indexByName: {}, + renameByName: {}, + includeByName: {}, + }, + }, + ]).addTargets( [ $.addTargetSchema( ||| @@ -286,7 +514,8 @@ local g = import 'grafonnet/grafana.libsonnet'; ), $.addTargetSchema('', 'L', '', '', null), ] - ) + { gridPos: { x: 0, y: 3, w: 24, h: 6 } }, + ), + $.simpleGraphPanel( {}, 'Top $topk Client IOPS by Pool', diff --git a/monitoring/ceph-mixin/dashboards/rbd.libsonnet b/monitoring/ceph-mixin/dashboards/rbd.libsonnet index 0eca5a877..36cd3ff1b 100644 --- a/monitoring/ceph-mixin/dashboards/rbd.libsonnet +++ b/monitoring/ceph-mixin/dashboards/rbd.libsonnet @@ -22,7 +22,7 @@ local u = import 'utils.libsonnet'; '{{pool}} Write'), $.addTargetSchema(expr2, '{{pool}} Read'), ] - ) + { gridPos: { x: x, y: y, w: w, h: h } }; + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }; $.dashboardSchema( 'RBD Details', @@ -133,7 +133,7 @@ local u = import 'utils.libsonnet'; $.graphPanelSchema({}, title, '', - 'null', + 'null as zero', false, formatY1, 'short', @@ -149,7 +149,7 @@ local u = import 'utils.libsonnet'; $.addTargetSchema(expr2, legendFormat2), ] - ) + { gridPos: { x: x, y: y, w: w, h: h } }; + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }; $.dashboardSchema( 'RBD Overview', @@ -240,20 +240,68 @@ local u = import 'utils.libsonnet'; 8, 7 ), - $.addTableSchema( - '$datasource', - '', - { col: 3, desc: true }, - [ - $.overviewStyle('Pool', 'pool', 'string', 'short'), - $.overviewStyle('Image', 'image', 'string', 'short'), - $.overviewStyle('IOPS', 'Value', 'number', 'iops'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + + $.addTableExtended( + datasource='${datasource}', + title='Highest IOPS', + description='RBD per-image IO statistics are disabled by default.\n\nPlease refer to https://docs.ceph.com/en/latest/mgr/prometheus/#rbd-io-statistics for information about how to enable those optionally.', + gridPosition={ h: 7, w: 8, x: 0, y: 7 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'pool' }, + properties: [ + { id: 'displayName', value: 'Pool' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'image' }, + properties: [ + { id: 'displayName', value: 'Image' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'IOPS' }, + { id: 'unit', value: 'iops' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Highest IOPS', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -270,21 +318,69 @@ local u = import 'utils.libsonnet'; 1, true ) - ) + { gridPos: { x: 0, y: 7, w: 8, h: 7 } }, - $.addTableSchema( - '$datasource', - '', - { col: 3, desc: true }, - [ - $.overviewStyle('Pool', 'pool', 'string', 'short'), - $.overviewStyle('Image', 'image', 'string', 'short'), - $.overviewStyle('Throughput', 'Value', 'number', 'Bps'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + ), + + $.addTableExtended( + datasource='${datasource}', + title='Highest Throughput', + description='RBD per-image IO statistics are disabled by default.\n\nPlease refer to https://docs.ceph.com/en/latest/mgr/prometheus/#rbd-io-statistics for information about how to enable those optionally.', + gridPosition={ h: 7, w: 8, x: 8, y: 7 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'pool' }, + properties: [ + { id: 'displayName', value: 'Pool' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'image' }, + properties: [ + { id: 'displayName', value: 'Image' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'Throughput' }, + { id: 'unit', value: 'Bps' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Highest Throughput', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -301,21 +397,69 @@ local u = import 'utils.libsonnet'; 1, true ) - ) + { gridPos: { x: 8, y: 7, w: 8, h: 7 } }, - $.addTableSchema( - '$datasource', - '', - { col: 3, desc: true }, - [ - $.overviewStyle('Pool', 'pool', 'string', 'short'), - $.overviewStyle('Image', 'image', 'string', 'short'), - $.overviewStyle('Latency', 'Value', 'number', 'ns'), - $.overviewStyle('', '/.*/', 'hidden', 'short'), + ), + + $.addTableExtended( + datasource='${datasource}', + title='Highest Latency', + description='RBD per-image IO statistics are disabled by default.\n\nPlease refer to https://docs.ceph.com/en/latest/mgr/prometheus/#rbd-io-statistics for information about how to enable those optionally.', + gridPosition={ h: 7, w: 8, x: 16, y: 7 }, + options={ + footer: { + fields: '', + reducer: ['sum'], + countRows: false, + enablePagination: false, + show: false, + }, + frameIndex: 1, + showHeader: true, + }, + custom={ align: 'null', cellOptions: { type: 'auto' }, filterable: true, inspect: false }, + thresholds={ + mode: 'absolute', + steps: [ + { color: 'green', value: null }, + { color: 'red', value: 80 }, + ], + }, + overrides=[ + { + matcher: { id: 'byName', options: 'pool' }, + properties: [ + { id: 'displayName', value: 'Pool' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'image' }, + properties: [ + { id: 'displayName', value: 'Image' }, + { id: 'unit', value: 'short' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, + { + matcher: { id: 'byName', options: 'Value' }, + properties: [ + { id: 'displayName', value: 'Latency' }, + { id: 'unit', value: 'ns' }, + { id: 'decimals', value: 2 }, + { id: 'custom.align', value: null }, + ], + }, ], - 'Highest Latency', - 'table' + pluginVersion='10.4.0' ) - .addTarget( + .addTransformations([ + { + id: 'merge', + options: { reducers: [] }, + }, + ]).addTarget( $.addTargetSchema( ||| topk(10, @@ -332,6 +476,6 @@ local u = import 'utils.libsonnet'; 1, true ) - ) + { gridPos: { x: 16, y: 7, w: 8, h: 7 } }, + ), ]), } diff --git a/monitoring/ceph-mixin/dashboards/rgw.libsonnet b/monitoring/ceph-mixin/dashboards/rgw.libsonnet index 892480d1c..557f1ddcc 100644 --- a/monitoring/ceph-mixin/dashboards/rgw.libsonnet +++ b/monitoring/ceph-mixin/dashboards/rgw.libsonnet @@ -24,7 +24,7 @@ local u = import 'utils.libsonnet'; '{{source_zone}}' ), ] - ) + { gridPos: { x: x, y: y, w: w, h: h } }; + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }; $.dashboardSchema( 'RGW Sync Overview', @@ -140,7 +140,7 @@ local u = import 'utils.libsonnet'; {}, title, description, - 'null', + 'null as zero', false, formatY1, formatY2, @@ -158,7 +158,7 @@ local u = import 'utils.libsonnet'; ) .addTargets( [$.addTargetSchema(expr1, legendFormat1)] - ) + { gridPos: { x: x, y: y, w: w, h: h } }; + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }; $.dashboardSchema( 'RGW Overview', @@ -658,7 +658,7 @@ local u = import 'utils.libsonnet'; $.graphPanelSchema(aliasColors, title, description, - 'null', + 'null as zero', false, formatY1, formatY2, @@ -669,7 +669,7 @@ local u = import 'utils.libsonnet'; '$datasource') .addTargets( [$.addTargetSchema(expr1, legendFormat1), $.addTargetSchema(expr2, legendFormat2)] - ) + { gridPos: { x: x, y: y, w: w, h: h } }; + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }; $.dashboardSchema( 'RGW Instance Detail', @@ -825,15 +825,52 @@ local u = import 'utils.libsonnet'; ), ] ), - $.simplePieChart( - { - GETs: '#7eb26d', - 'Other (HEAD,POST,DELETE)': '#447ebc', - PUTs: '#eab839', - Requests: '#3f2b5b', - Failures: '#bf1b00', - }, '', 'Workload Breakdown' - ) + + $.pieChartPanel('Workload Breakdown', + '', + '$datasource', + { x: 20, y: 1, w: 4, h: 8 }, + 'table', + 'bottom', + true, + [], + { mode: 'single', sort: 'none' }, + 'pie', + ['percent', 'value'], + 'palette-classic', + overrides=[ + { + matcher: { id: 'byName', options: 'Failures' }, + properties: [ + { id: 'color', value: { mode: 'fixed', fixedColor: '#bf1b00' } }, + ], + }, + { + matcher: { id: 'byName', options: 'GETs' }, + properties: [ + { id: 'color', value: { mode: 'fixed', fixedColor: '#7eb26d' } }, + ], + }, + { + matcher: { id: 'byName', options: 'Other (HEAD,POST,DELETE)' }, + properties: [ + { id: 'color', value: { mode: 'fixed', fixedColor: '#447ebc' } }, + ], + }, + { + matcher: { id: 'byName', options: 'PUTs' }, + properties: [ + { id: 'color', value: { mode: 'fixed', fixedColor: '#eab839' } }, + ], + }, + { + matcher: { id: 'byName', options: 'Requests' }, + properties: [ + { id: 'color', value: { mode: 'fixed', fixedColor: '#3f2b5b' } }, + ], + }, + ], + reduceOptions={ values: false, calcs: ['lastNotNull'], fields: '' }) .addTarget($.addTargetSchema( ||| rate(ceph_rgw_failed_req{%(matchers)s}[$__rate_interval]) * @@ -867,6 +904,6 @@ local u = import 'utils.libsonnet'; ceph_rgw_metadata{%(matchers)s, ceph_daemon=~"$rgw_servers"} ||| % $.matchers(), 'Other (DELETE,LIST) {{ceph_daemon}}' - )) + { gridPos: { x: 20, y: 1, w: 4, h: 8 } }, + )), ]), } diff --git a/monitoring/ceph-mixin/dashboards/utils.libsonnet b/monitoring/ceph-mixin/dashboards/utils.libsonnet index a7774c7ce..5575d6205 100644 --- a/monitoring/ceph-mixin/dashboards/utils.libsonnet +++ b/monitoring/ceph-mixin/dashboards/utils.libsonnet @@ -1,4 +1,5 @@ local g = import 'grafonnet/grafana.libsonnet'; +local pieChartPanel = import 'piechart_panel.libsonnet'; { _config:: error 'must provide _config', @@ -144,14 +145,6 @@ local g = import 'grafonnet/grafana.libsonnet'; title=title, valueName=valueName), - addTableSchema(datasource, description, sort, styles, title, transform):: - g.tablePanel.new(datasource=datasource, - description=description, - sort=sort, - styles=styles, - title=title, - transform=transform), - addStyle(alias, colorMode, colors, @@ -266,7 +259,7 @@ local g = import 'grafonnet/grafana.libsonnet'; '$datasource') .addTargets( [$.addTargetSchema(expr, legendFormat)] - ) + { gridPos: { x: x, y: y, w: w, h: h } }, + ) + { type: 'timeseries' } + { fieldConfig: { defaults: { unit: formatY1, custom: { fillOpacity: 8, showPoints: 'never' } } } } + { gridPos: { x: x, y: y, w: w, h: h } }, simpleSingleStatPanel(format, title, @@ -330,4 +323,76 @@ local g = import 'grafonnet/grafana.libsonnet'; 'pie', title, 'current'), + + pieChartPanel( + title, + description='', + datasource=null, + gridPos={}, + displayMode='table', + placement='bottom', + showLegend=true, + displayLabels=[], + tooltip={}, + pieType='pie', + values=[], + colorMode='auto', + overrides=[], + reduceOptions={}, + ):: + pieChartPanel.new( + title, + description=description, + datasource=datasource, + gridPos=gridPos, + displayMode=displayMode, + placement=placement, + showLegend=showLegend, + displayLabels=displayLabels, + tooltip=tooltip, + pieType=pieType, + values=values, + colorMode=colorMode, + overrides=overrides, + reduceOptions=reduceOptions, + ), + + addTableExtended( + title='', + datasource=null, + description=null, + sort=null, + styles='', + transform=null, + pluginVersion='9.1.3', + options=null, + gridPosition={}, + custom=null, + decimals=null, + thresholds=null, + unit=null, + overrides=[], + color=null + ):: + g.tablePanel.new(datasource=datasource, + description=description, + sort=sort, + styles=styles, + title=title, + transform=transform) + { + pluginVersion: pluginVersion, + gridPos: gridPosition, + [if options != null then 'options']: options, + fieldConfig+: { + defaults+: { + [if custom != null then 'custom']: custom, + [if decimals != null then 'decimals']: decimals, + [if thresholds != null then 'thresholds']: thresholds, + [if unit != null then 'unit']: unit, + [if color != null then 'color']: color, + + }, + overrides: overrides, + }, + }, } -- cgit v1.2.3