local grafana = import 'grafonnet-lib/grafonnet/grafana.libsonnet'; local dashboard = grafana.dashboard; local row = grafana.row; local graphPanel = grafana.graphPanel; local prometheus = grafana.prometheus; local template = grafana.template; local myNameFlag = 'DS_TEST-CLUSTER'; local myDS = '${' + myNameFlag + '}'; // A new dashboard local newDash = dashboard.new( title='Test-Cluster-TiCI-Meta', editable=true, graphTooltip='shared_crosshair', refresh='30s', time_from='now-1h', ) .addInput( name=myNameFlag, label='test-cluster', type='datasource', pluginId='prometheus', pluginName='Prometheus', ) .addTemplate( template.new( datasource=myDS, hide= 2, label='K8s-cluster', name='k8s_cluster', query='label_values(pd_cluster_status, k8s_cluster)', refresh='time', sort=1, ) ) .addTemplate( // Default template for tidb-cloud template.new( allValues=null, current=null, datasource=myDS, hide='all', includeAll=false, label='tidb_cluster', multi=false, name='tidb_cluster', query='label_values(pd_cluster_status{k8s_cluster="$k8s_cluster"}, tidb_cluster)', refresh='time', regex='', sort=1, tagValuesQuery='', ) ).addTemplate( // Default template for tidb-cloud template.new( allValues=null, current=null, datasource=myDS, hide='', includeAll=true, label='Instance', multi=false, name='instance', query='query_result(max by (instance) (up{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", component="tici-meta"} or up{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", job="tici-meta"} or up{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"tici-meta-.+"} or up{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", job="tici"}))', refresh='time', regex='/.*instance="([^"]+)".*/', sort=1, tagValuesQuery='', ) ); local metaMetricMatcher = 'k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"'; // Server row and its panels local serverRow = row.new(collapse=true, title='Server'); local uptimeP = graphPanel.new( title='Uptime', datasource=myDS, legend_rightSide=true, format='s', description='Uptime since the last restart.', ) .addTarget( prometheus.target( 'time() - process_start_time_seconds{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{instance}}', ) ); local cpuP = graphPanel.new( title='CPU Usage', datasource=myDS, legend_rightSide=true, description='', format='percentunit', ) .addTarget( prometheus.target( 'rate(process_cpu_seconds_total{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])', legendFormat='{{instance}}', ) ); /* // TODO: Add cpu quota .addTarget( prometheus.target( 'tidb_server_maxprocs{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='quota-{{instance}}', ) ); */ local memP = graphPanel.new( title='Memory Usage', datasource=myDS, legend_rightSide=true, description='', format='bytes', ) .addTarget( prometheus.target( 'process_resident_memory_bytes{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{instance}}', ) ); local processMemoryStatusPanel = graphPanel.new( title='Process Memory Status', datasource=myDS, legend_rightSide=true, fill=0, description= 'Process memory fields collected from /proc/self/status. Values are converted from kB to bytes.\n\n' + 'VmRSS: current resident set size in physical memory.\n\n' + 'RssAnon: resident anonymous memory such as heap and stack.\n\n' + 'RssFile: resident file-backed memory such as mapped files and shared libraries.\n\n' + 'RssShmem: resident shared memory including tmpfs and shared anonymous mappings.\n\n' + 'VmHWM: peak resident set size since process start.', format='bytes', ) .addTarget( prometheus.target( 'tici_process_memory_status_bytes{' + metaMetricMatcher + '}', legendFormat='{{type}}-{{instance}}', ) ); local leaderP = graphPanel.new( title='Meta Leader', datasource=myDS, legend_rightSide=true, description='Whether meta believes it is leader (1) or not (0).', format='none', ) .addTarget( prometheus.target( 'tici_meta_is_leader{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{instance}}', ) ); /* // TODO: Add memory quota .addTarget( prometheus.target( 'tidb_server_memory_quota_bytes{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='quota-{{instance}}', ) );*/ // Summary row and its panels local shardSummaryRow = row.new(collapse=true, title='Shard Summary'); local shardCount = graphPanel.new( title='Shard count', datasource=myDS, legend_rightSide=true, format='none', description='', ) .addTarget( prometheus.target( 'tici_meta_shard_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{type}}', ) ); local unscheduledShards = graphPanel.new( title='Unscheduled shards', datasource=myDS, legend_rightSide=true, format='none', description='Current number of shards without an assigned writer.', ) .addTarget( prometheus.target( 'tici_unscheduled_shards_total{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{instance}}', ) ); local indexCount = graphPanel.new( title='Index count', datasource=myDS, legend_rightSide=true, format='none', description='', ) .addTarget( prometheus.target( 'tici_meta_index_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{type}}', ) ); local shardByNodeCount = graphPanel.new( title='Shard count (by worker)', datasource=myDS, legend_rightSide=true, format='none', description='', ) .addTarget( prometheus.target( 'tici_meta_shard_by_writer_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{node}}', ) ); local compactionByWorkerCount = graphPanel.new( title='Compaction count (by worker)', datasource=myDS, legend_rightSide=true, format='none', description='', ) .addTarget( prometheus.target( 'tici_meta_compaction_by_writer_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{node}}', ) ); local shardEvents = graphPanel.new( title='Shard Events', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'sum by (type) (rate(tici_meta_shard_event_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m]))', legendFormat='{{type}}', ) ); local workerHeartbeats = graphPanel.new( title='Worker Heartbeats', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'sum by (addr) (rate(tici_meta_worker_heartbeats_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m]))', legendFormat='{{addr}}', ) ); local shardEventDurations = graphPanel.new( title='Shard Event Duration', datasource=myDS, legend_rightSide=true, format='s', logBase1Y=2, ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_meta_shard_event_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local shardTaskCount = graphPanel.new( title='Shard Tasks', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'sum by (type) (rate(tici_meta_shard_task_duration_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m]))', legendFormat='{{type}}', ) ); local shardTaskDurations = graphPanel.new( title='Shard Task Duration', datasource=myDS, legend_rightSide=true, format='ms', logBase1Y=2, ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_meta_shard_task_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local shardTaskTriggerReason = graphPanel.new( title='Shard Task Trigger Reason', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'sum by (reason) (rate(tici_meta_shard_task_trigger_reason_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m]))', legendFormat='{{type}}', ) ); local backEndDelayDuration = graphPanel.new( title='Backend Delay Duration', datasource=myDS, legend_rightSide=true, format='s', logBase1Y=2, ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_backend_delay_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local shardTaskQueueDuration = graphPanel.new( title='Shard Task Queued Duration', datasource=myDS, legend_rightSide=true, format='s', logBase1Y=2, ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_meta_shard_task_queued_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local shardTasksByRunner = graphPanel.new( title='Shard Tasks By Runner', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'sum by (id, type) (rate(tici_meta_shard_task_by_runner_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m]))', legendFormat='{{id}}-{{type}}', ) ); local compactionRatio = graphPanel.new( title='Compaction IO Ratio', datasource=myDS, legend_rightSide=true, format='none', logBase1Y=2, ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_meta_compaction_ratio_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local compactionFragments = graphPanel.new( title='Compaction Fragment Count', datasource=myDS, legend_rightSide=true, format='none', ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_meta_compaction_input_fragment_count_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local compactionInputSize = graphPanel.new( title='Compaction Input Size', datasource=myDS, legend_rightSide=true, format='bytes', logBase1Y=2, description='Per-compaction sum of input fragment sizes (bytes), histogram buckets 1KiB..4GiB (×4).', ) .addTarget( prometheus.target( 'histogram_quantile(0.5, sum by (le) (rate(tici_meta_compaction_input_size_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])))', legendFormat='P50', ) ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum by (le) (rate(tici_meta_compaction_input_size_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])))', legendFormat='P99', ) ); local splitImbalanceRatio = graphPanel.new( title='Split Imbalance Ratio', datasource=myDS, legend_rightSide=true, format='none', logBase1Y=2, ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_meta_shard_split_imbalance_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ) .addTarget( prometheus.target( 'histogram_quantile(0.5, sum(rate(tici_meta_shard_split_imbalance_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])) by (le, type))', legendFormat='{{type}}-50%', ) ); local shardSizeQuantiles = graphPanel.new( title='Shard size (P50 / P90)', datasource=myDS, legend_rightSide=true, format='bytes', logBase1Y=2, description='Approximate shard size distribution from tici_meta_shard_size.', ) .addTarget( prometheus.target( 'histogram_quantile(0.5, sum by (le) (rate(tici_meta_shard_size_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])))', legendFormat='P50', ) ) .addTarget( prometheus.target( 'histogram_quantile(0.9, sum by (le) (rate(tici_meta_shard_size_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])))', legendFormat='P90', ) ); local shardFragmentsQuantiles = graphPanel.new( title='Shard fragments (P50 / P90)', datasource=myDS, legend_rightSide=true, format='none', logBase1Y=2, description='Fragment count per shard from tici_meta_shard_fragments.', ) .addTarget( prometheus.target( 'histogram_quantile(0.5, sum by (le) (rate(tici_meta_shard_fragments_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])))', legendFormat='P50', ) ) .addTarget( prometheus.target( 'histogram_quantile(0.9, sum by (le) (rate(tici_meta_shard_fragments_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[1m])))', legendFormat='P90', ) ); // GRPC Row local grpcRow = row.new(collapse=true, title='GRPC'); local grpcRequestDuration = graphPanel.new( title='Grpc Request Duration', datasource=myDS, legend_rightSide=true, format='s', ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_grpc_handle_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service=~"meta.*"}[1m])) by (le, type))', legendFormat='{{type}}-99%', ) ); local grpcRequestOPS = graphPanel.new( title='Grpc Request OPS', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'sum by (service, type, result) (rate(tici_grpc_handle_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service=~"meta.*"}[1m]))', legendFormat='{{service}}-{{type}}-{{result}}', ) ); local grpcRequestInflight = graphPanel.new( title='Grpc Request Inflight', datasource=myDS, legend_rightSide=true, format='none', ) .addTarget( prometheus.target( 'sum by (service, type) (tici_grpc_handle_inflight{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service=~"meta.*"})', legendFormat='{{service}}-{{type}}', ) ); // Shard Cache row and its panels local shardCacheRow = row.new(collapse=true, title='Shard Cache'); local readerCount = graphPanel.new( title='Active Readers', datasource=myDS, legend_rightSide=true, format='none', description='Active reader nodes in pool', ) .addTarget( prometheus.target( 'tici_meta_shard_cache_reader_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='active-readers', ) ); local cacheHitMiss = graphPanel.new( title='Cache Hit/Miss Rate', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'rate(tici_meta_shard_cache_query_duration_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", type=~"hit"}[5m])', legendFormat='hit-{{instance}}', ) ) .addTarget( prometheus.target( 'rate(tici_meta_shard_cache_query_duration_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", type=~"miss"}[5m])', legendFormat='miss-{{instance}}', ) ); local cacheHitRatio = graphPanel.new( title='Cache Hit Ratio', datasource=myDS, legend_rightSide=true, format='percentunit', ) .addTarget( prometheus.target( 'sum(rate(tici_meta_shard_cache_query_duration_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", type=~"hit"}[5m])) / sum(rate(tici_meta_shard_cache_query_duration_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[5m]))', legendFormat='hit-ratio', ) ); local warmupReqP95 = graphPanel.new( title='Warmup req P95', datasource=myDS, legend_rightSide=true, format='s', description='Shard cache warmup latency p95', ) .addTarget( prometheus.target( 'histogram_quantile(0.95, sum by (le) (rate(tici_meta_shard_cache_warm_up_req_latency_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[5m])))', legendFormat='p95', ) ); local warmupQueueP95 = graphPanel.new( title='Warmup queue P95', datasource=myDS, legend_rightSide=true, format='s', description='Shard cache warmup queue latency p95', ) .addTarget( prometheus.target( 'histogram_quantile(0.95, sum by (le) (rate(tici_meta_shard_cache_warm_up_queued_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[5m])))', legendFormat='p95', ) ); local shardCacheCount = graphPanel.new( title='Shard Cache Count', datasource=myDS, legend_rightSide=true, format='none', description='Current number of shard cache allocations', ) .addTarget( prometheus.target( 'tici_meta_shard_cache_count_gauge{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}', legendFormat='{{type}}', ) ); local queryDurationP95 = graphPanel.new( title='Query duration P95', datasource=myDS, legend_rightSide=true, format='s', description='Shard cache warmup queue latency p95', ) .addTarget( prometheus.target( 'histogram_quantile(0.95, sum by (le) (rate(tici_meta_shard_cache_query_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", type=~"hit"}[5m])))', legendFormat='hit-p95', ) ) .addTarget( prometheus.target( 'histogram_quantile(0.95, sum by (le) (rate(tici_meta_shard_cache_query_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", type=~"need_warm"}[5m])))', legendFormat='need_warm-p95', ) ); local shardCacheEvent = graphPanel.new( title='Shard Cache Event', datasource=myDS, legend_rightSide=true, format='ops', ) .addTarget( prometheus.target( 'rate(tici_meta_shard_cache_event_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"}[5m])', legendFormat='{{type}}', ) ); // Import row and its panels local importRow = row.new(collapse=true, title='Import Into'); local importPartitionUploadFinishRate = graphPanel.new( title='Upload Task Count (Stage-1)', datasource=myDS, legend_rightSide=true, format='none', description='Total processed task count at stage-1 (partition-upload), grouped by result.', ) .addTarget( prometheus.target( 'sum by (result) (tici_meta_import_partition_upload_finish_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"})', legendFormat='{{result}}', ) ); local importIndexUploadFinishRate = graphPanel.new( title='Upload Index Count', datasource=myDS, legend_rightSide=true, format='none', description='Total processed index count at stage-1 (partition-upload), grouped by result.', ) .addTarget( prometheus.target( 'sum by (result) (tici_meta_import_index_upload_finish_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"})', legendFormat='{{result}}', ) ); local importPartitionBuildFinishRate = graphPanel.new( title='Build Task Count (Stage-2)', datasource=myDS, legend_rightSide=true, format='none', description='Total processed task count at stage-2 (partition-build), grouped by result.', ) .addTarget( prometheus.target( 'sum by (result) (tici_meta_import_partition_build_finish_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance"})', legendFormat='{{result}}', ) ); // Storage row and its panels local storageRow = row.new(collapse=true, title='Storage'); local storageHandleDuration = graphPanel.new( title='Storage Handle Duration', datasource=myDS, legend_rightSide=true, format='s', description='Backend storage request duration by backend and operation type', ) .addTarget( prometheus.target( 'histogram_quantile(0.99, sum(rate(tici_storage_handle_duration_bucket{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service="meta"}[1m])) by (le, backend, type))', legendFormat='{{backend}}/{{type}}-99', ) ) .addTarget( prometheus.target( 'sum(rate(tici_storage_handle_duration_sum{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service="meta"}[1m])) by (backend, type) / sum(rate(tici_storage_handle_duration_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service="meta"}[1m])) by (backend, type)', legendFormat='{{backend}}/{{type}}-avg', ) ); local storageHandleCount = graphPanel.new( title='Storage Handle Count', datasource=myDS, legend_rightSide=true, format='ops', description='Backend storage request rate by backend, operation type, and result', ) .addTarget( prometheus.target( 'sum by (backend, type, result) (rate(tici_storage_handle_count{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service="meta"}[1m]))', legendFormat='{{backend}}/{{type}}-{{result}}', ) ); local storageHandleInflight = graphPanel.new( title='Storage Handle Inflight', datasource=myDS, legend_rightSide=true, format='none', description='Inflight backend storage requests by backend and operation type', ) .addTarget( prometheus.target( 'sum by (backend, type) (tici_storage_handle_inflight{k8s_cluster="$k8s_cluster", tidb_cluster="$tidb_cluster", instance=~"$instance", service="meta"})', legendFormat='{{backend}}/{{type}}', ) ); // Merge together. local panelW = 12; local panelH = 7; local rowW = 24; local rowH = 1; local rowPos = {x:0, y:0, w:rowW, h:rowH}; local fullPanelPos = {x:0, y:0, w:rowW, h:panelH}; local leftPanelPos = {x:0, y:0, w:panelW, h:panelH}; local rightPanelPos = {x:panelW, y:0, w:panelW, h:panelH}; newDash .addPanel( serverRow .addPanel(uptimeP, gridPos=leftPanelPos) .addPanel(cpuP, gridPos=rightPanelPos) .addPanel(memP, gridPos=leftPanelPos) .addPanel(leaderP, gridPos=rightPanelPos) .addPanel(processMemoryStatusPanel, gridPos=leftPanelPos) , gridPos=rowPos ) .addPanel( shardSummaryRow .addPanel(shardCount, gridPos=leftPanelPos) .addPanel(indexCount, gridPos=rightPanelPos) .addPanel(unscheduledShards, gridPos=leftPanelPos) .addPanel(shardByNodeCount, gridPos=leftPanelPos) .addPanel(compactionByWorkerCount, gridPos=rightPanelPos) .addPanel(shardEvents, gridPos=leftPanelPos) .addPanel(shardEventDurations, gridPos=rightPanelPos) .addPanel(workerHeartbeats, gridPos=leftPanelPos) .addPanel(shardTaskCount, gridPos=leftPanelPos) .addPanel(shardTaskDurations, gridPos=rightPanelPos) .addPanel(shardTaskTriggerReason, gridPos=leftPanelPos) .addPanel(shardTaskQueueDuration, gridPos=rightPanelPos) .addPanel(backEndDelayDuration, gridPos=leftPanelPos) .addPanel(shardTasksByRunner, gridPos=rightPanelPos) .addPanel(compactionFragments, gridPos=leftPanelPos) .addPanel(compactionRatio, gridPos=rightPanelPos) .addPanel(splitImbalanceRatio, gridPos=leftPanelPos) .addPanel(compactionInputSize, gridPos=rightPanelPos) .addPanel(shardSizeQuantiles, gridPos=leftPanelPos) .addPanel(shardFragmentsQuantiles, gridPos=rightPanelPos) , gridPos=rowPos ) .addPanel( shardCacheRow .addPanel(readerCount, gridPos=leftPanelPos) .addPanel(shardCacheCount, gridPos=rightPanelPos) .addPanel(cacheHitRatio, gridPos=leftPanelPos) .addPanel(cacheHitMiss, gridPos=rightPanelPos) .addPanel(warmupQueueP95, gridPos=leftPanelPos) .addPanel(warmupReqP95, gridPos=rightPanelPos) .addPanel(queryDurationP95, gridPos=leftPanelPos) .addPanel(shardCacheEvent, gridPos=rightPanelPos) , gridPos=rowPos ) .addPanel( importRow .addPanel(importPartitionUploadFinishRate, gridPos=leftPanelPos) .addPanel(importIndexUploadFinishRate, gridPos=rightPanelPos) .addPanel(importPartitionBuildFinishRate, gridPos=leftPanelPos) , gridPos=rowPos ) .addPanel( grpcRow .addPanel(grpcRequestDuration, gridPos=leftPanelPos) .addPanel(grpcRequestOPS, gridPos=rightPanelPos) .addPanel(grpcRequestInflight, gridPos=leftPanelPos) , gridPos=rowPos ) .addPanel( storageRow .addPanel(storageHandleDuration, gridPos=leftPanelPos) .addPanel(storageHandleCount, gridPos=rightPanelPos) .addPanel(storageHandleInflight, gridPos=leftPanelPos) , gridPos=rowPos )