mirror of https://github.com/apache/druid.git
Web console: better tooltip when no size is available (#17008)
* better tooltip when no size is available * better labels for columns * fix label in segments view
This commit is contained in:
parent
ba6f804f48
commit
dc5c55a836
|
@ -67,17 +67,35 @@ exports[`DatasourcesView matches snapshot 1`] = `
|
||||||
"Availability",
|
"Availability",
|
||||||
"Historical load/drop queues",
|
"Historical load/drop queues",
|
||||||
"Total data size",
|
"Total data size",
|
||||||
"Running tasks",
|
{
|
||||||
|
"label": "sys.tasks",
|
||||||
|
"text": "Running tasks",
|
||||||
|
},
|
||||||
"Segment rows",
|
"Segment rows",
|
||||||
"Segment size",
|
"Segment size",
|
||||||
"Segment granularity",
|
{
|
||||||
|
"label": "𝑓(sys.segments)",
|
||||||
|
"text": "Segment granularity",
|
||||||
|
},
|
||||||
"Total rows",
|
"Total rows",
|
||||||
"Avg. row size",
|
"Avg. row size",
|
||||||
"Replicated size",
|
"Replicated size",
|
||||||
"Compaction",
|
{
|
||||||
"% Compacted",
|
"label": "compaction API",
|
||||||
"Left to be compacted",
|
"text": "Compaction",
|
||||||
"Retention",
|
},
|
||||||
|
{
|
||||||
|
"label": "compaction API",
|
||||||
|
"text": "% Compacted",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "compaction API",
|
||||||
|
"text": "Left to be compacted",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "rules API",
|
||||||
|
"text": "Retention",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import type { Filter } from 'react-table';
|
||||||
import ReactTable from 'react-table';
|
import ReactTable from 'react-table';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
type TableColumnSelectorColumn,
|
||||||
ACTION_COLUMN_ID,
|
ACTION_COLUMN_ID,
|
||||||
ACTION_COLUMN_LABEL,
|
ACTION_COLUMN_LABEL,
|
||||||
ACTION_COLUMN_WIDTH,
|
ACTION_COLUMN_WIDTH,
|
||||||
|
@ -86,44 +87,44 @@ import { RuleUtil } from '../../utils/load-rule';
|
||||||
|
|
||||||
import './datasources-view.scss';
|
import './datasources-view.scss';
|
||||||
|
|
||||||
const tableColumns: Record<CapabilitiesMode, string[]> = {
|
const TABLE_COLUMNS_BY_MODE: Record<CapabilitiesMode, TableColumnSelectorColumn[]> = {
|
||||||
'full': [
|
'full': [
|
||||||
'Datasource name',
|
'Datasource name',
|
||||||
'Availability',
|
'Availability',
|
||||||
'Historical load/drop queues',
|
'Historical load/drop queues',
|
||||||
'Total data size',
|
'Total data size',
|
||||||
'Running tasks',
|
{ text: 'Running tasks', label: 'sys.tasks' },
|
||||||
'Segment rows',
|
'Segment rows',
|
||||||
'Segment size',
|
'Segment size',
|
||||||
'Segment granularity',
|
{ text: 'Segment granularity', label: '𝑓(sys.segments)' },
|
||||||
'Total rows',
|
'Total rows',
|
||||||
'Avg. row size',
|
'Avg. row size',
|
||||||
'Replicated size',
|
'Replicated size',
|
||||||
'Compaction',
|
{ text: 'Compaction', label: 'compaction API' },
|
||||||
'% Compacted',
|
{ text: '% Compacted', label: 'compaction API' },
|
||||||
'Left to be compacted',
|
{ text: 'Left to be compacted', label: 'compaction API' },
|
||||||
'Retention',
|
{ text: 'Retention', label: 'rules API' },
|
||||||
],
|
],
|
||||||
'no-sql': [
|
'no-sql': [
|
||||||
'Datasource name',
|
'Datasource name',
|
||||||
'Availability',
|
'Availability',
|
||||||
'Historical load/drop queues',
|
'Historical load/drop queues',
|
||||||
'Total data size',
|
'Total data size',
|
||||||
'Running tasks',
|
{ text: 'Running tasks', label: 'tasks API' },
|
||||||
'Compaction',
|
{ text: 'Compaction', label: 'compaction API' },
|
||||||
'% Compacted',
|
{ text: '% Compacted', label: 'compaction API' },
|
||||||
'Left to be compacted',
|
{ text: 'Left to be compacted', label: 'compaction API' },
|
||||||
'Retention',
|
{ text: 'Retention', label: 'rules API' },
|
||||||
],
|
],
|
||||||
'no-proxy': [
|
'no-proxy': [
|
||||||
'Datasource name',
|
'Datasource name',
|
||||||
'Availability',
|
'Availability',
|
||||||
'Historical load/drop queues',
|
'Historical load/drop queues',
|
||||||
'Total data size',
|
'Total data size',
|
||||||
'Running tasks',
|
{ text: 'Running tasks', label: 'sys.tasks' },
|
||||||
'Segment rows',
|
'Segment rows',
|
||||||
'Segment size',
|
'Segment size',
|
||||||
'Segment granularity',
|
{ text: 'Segment granularity', label: '𝑓(sys.segments)' },
|
||||||
'Total rows',
|
'Total rows',
|
||||||
'Avg. row size',
|
'Avg. row size',
|
||||||
'Replicated size',
|
'Replicated size',
|
||||||
|
@ -517,21 +518,18 @@ GROUP BY 1, 2`;
|
||||||
if (capabilities.hasOverlordAccess()) {
|
if (capabilities.hasOverlordAccess()) {
|
||||||
auxiliaryQueries.push(async (datasourcesAndDefaultRules, cancelToken) => {
|
auxiliaryQueries.push(async (datasourcesAndDefaultRules, cancelToken) => {
|
||||||
try {
|
try {
|
||||||
const runningTasks = await queryDruidSql<RunningTaskRow>(
|
const taskList = (
|
||||||
{
|
await Api.instance.get(`/druid/indexer/v1/tasks?state=running`, { cancelToken })
|
||||||
query: DatasourcesView.RUNNING_TASK_SQL,
|
).data;
|
||||||
},
|
|
||||||
cancelToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
const runningTasksByDatasource = groupByAsMap(
|
const runningTasksByDatasource = groupByAsMap(
|
||||||
runningTasks,
|
taskList,
|
||||||
x => x.datasource,
|
(t: any) => t.dataSource,
|
||||||
xs =>
|
xs =>
|
||||||
groupByAsMap(
|
groupByAsMap(
|
||||||
xs,
|
xs,
|
||||||
x => normalizeTaskType(x.type),
|
x => normalizeTaskType(x.type),
|
||||||
ys => sum(ys, y => y.num_running_tasks),
|
ys => ys.length,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1703,7 +1701,7 @@ GROUP BY 1, 2`;
|
||||||
disabled={!capabilities.hasSqlOrCoordinatorAccess()}
|
disabled={!capabilities.hasSqlOrCoordinatorAccess()}
|
||||||
/>
|
/>
|
||||||
<TableColumnSelector
|
<TableColumnSelector
|
||||||
columns={tableColumns[capabilities.getMode()]}
|
columns={TABLE_COLUMNS_BY_MODE[capabilities.getMode()]}
|
||||||
onChange={column =>
|
onChange={column =>
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
visibleColumns: prevState.visibleColumns.toggle(column),
|
visibleColumns: prevState.visibleColumns.toggle(column),
|
||||||
|
|
|
@ -55,7 +55,10 @@ exports[`SegmentsView matches snapshot 1`] = `
|
||||||
"Start",
|
"Start",
|
||||||
"End",
|
"End",
|
||||||
"Version",
|
"Version",
|
||||||
"Time span",
|
{
|
||||||
|
"label": "𝑓(sys.segments)",
|
||||||
|
"text": "Time span",
|
||||||
|
},
|
||||||
"Shard type",
|
"Shard type",
|
||||||
"Shard spec",
|
"Shard spec",
|
||||||
"Partition",
|
"Partition",
|
||||||
|
|
|
@ -26,6 +26,7 @@ import type { Filter } from 'react-table';
|
||||||
import ReactTable from 'react-table';
|
import ReactTable from 'react-table';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
type TableColumnSelectorColumn,
|
||||||
ACTION_COLUMN_ID,
|
ACTION_COLUMN_ID,
|
||||||
ACTION_COLUMN_LABEL,
|
ACTION_COLUMN_LABEL,
|
||||||
ACTION_COLUMN_WIDTH,
|
ACTION_COLUMN_WIDTH,
|
||||||
|
@ -76,14 +77,14 @@ import type { BasicAction } from '../../utils/basic-action';
|
||||||
|
|
||||||
import './segments-view.scss';
|
import './segments-view.scss';
|
||||||
|
|
||||||
const tableColumns: Record<CapabilitiesMode, string[]> = {
|
const TABLE_COLUMNS_BY_MODE: Record<CapabilitiesMode, TableColumnSelectorColumn[]> = {
|
||||||
'full': [
|
'full': [
|
||||||
'Segment ID',
|
'Segment ID',
|
||||||
'Datasource',
|
'Datasource',
|
||||||
'Start',
|
'Start',
|
||||||
'End',
|
'End',
|
||||||
'Version',
|
'Version',
|
||||||
'Time span',
|
{ text: 'Time span', label: '𝑓(sys.segments)' },
|
||||||
'Shard type',
|
'Shard type',
|
||||||
'Shard spec',
|
'Shard spec',
|
||||||
'Partition',
|
'Partition',
|
||||||
|
@ -105,6 +106,7 @@ const tableColumns: Record<CapabilitiesMode, string[]> = {
|
||||||
'Start',
|
'Start',
|
||||||
'End',
|
'End',
|
||||||
'Version',
|
'Version',
|
||||||
|
{ text: 'Time span', label: '𝑓(sys.segments)' },
|
||||||
'Shard type',
|
'Shard type',
|
||||||
'Shard spec',
|
'Shard spec',
|
||||||
'Partition',
|
'Partition',
|
||||||
|
@ -260,7 +262,7 @@ END AS "time_span"`,
|
||||||
if (capabilities.hasSql()) {
|
if (capabilities.hasSql()) {
|
||||||
const whereParts = filterMap(filtered, (f: Filter) => {
|
const whereParts = filterMap(filtered, (f: Filter) => {
|
||||||
if (f.id === 'shard_type') {
|
if (f.id === 'shard_type') {
|
||||||
// Special handling for shard_type that needs to be search in the shard_spec
|
// Special handling for shard_type that needs to be searched for in the shard_spec
|
||||||
// Creates filters like `shard_spec LIKE '%"type":"numbered"%'`
|
// Creates filters like `shard_spec LIKE '%"type":"numbered"%'`
|
||||||
const modeAndNeedle = parseFilterModeAndNeedle(f);
|
const modeAndNeedle = parseFilterModeAndNeedle(f);
|
||||||
if (!modeAndNeedle) return;
|
if (!modeAndNeedle) return;
|
||||||
|
@ -1008,7 +1010,7 @@ END AS "time_span"`,
|
||||||
disabled={!capabilities.hasSqlOrCoordinatorAccess()}
|
disabled={!capabilities.hasSqlOrCoordinatorAccess()}
|
||||||
/>
|
/>
|
||||||
<TableColumnSelector
|
<TableColumnSelector
|
||||||
columns={tableColumns[capabilities.getMode()]}
|
columns={TABLE_COLUMNS_BY_MODE[capabilities.getMode()]}
|
||||||
onChange={column =>
|
onChange={column =>
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
visibleColumns: prevState.visibleColumns.toggle(column),
|
visibleColumns: prevState.visibleColumns.toggle(column),
|
||||||
|
|
|
@ -24,6 +24,7 @@ import type { Filter } from 'react-table';
|
||||||
import ReactTable from 'react-table';
|
import ReactTable from 'react-table';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
type TableColumnSelectorColumn,
|
||||||
ACTION_COLUMN_ID,
|
ACTION_COLUMN_ID,
|
||||||
ACTION_COLUMN_LABEL,
|
ACTION_COLUMN_LABEL,
|
||||||
ACTION_COLUMN_WIDTH,
|
ACTION_COLUMN_WIDTH,
|
||||||
|
@ -59,7 +60,7 @@ import type { BasicAction } from '../../utils/basic-action';
|
||||||
|
|
||||||
import './services-view.scss';
|
import './services-view.scss';
|
||||||
|
|
||||||
const tableColumns: Record<CapabilitiesMode, string[]> = {
|
const TABLE_COLUMNS_BY_MODE: Record<CapabilitiesMode, TableColumnSelectorColumn[]> = {
|
||||||
'full': [
|
'full': [
|
||||||
'Service',
|
'Service',
|
||||||
'Type',
|
'Type',
|
||||||
|
@ -804,7 +805,7 @@ ORDER BY
|
||||||
/>
|
/>
|
||||||
{this.renderBulkServicesActions()}
|
{this.renderBulkServicesActions()}
|
||||||
<TableColumnSelector
|
<TableColumnSelector
|
||||||
columns={tableColumns[capabilities.getMode()]}
|
columns={TABLE_COLUMNS_BY_MODE[capabilities.getMode()]}
|
||||||
onChange={column =>
|
onChange={column =>
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
visibleColumns: prevState.visibleColumns.toggle(column),
|
visibleColumns: prevState.visibleColumns.toggle(column),
|
||||||
|
|
|
@ -61,6 +61,7 @@ import './execution-stages-pane.scss';
|
||||||
const MAX_STAGE_ROWS = 20;
|
const MAX_STAGE_ROWS = 20;
|
||||||
const MAX_DETAIL_ROWS = 20;
|
const MAX_DETAIL_ROWS = 20;
|
||||||
const NOT_SIZE_ON_DISK = '(does not represent size on disk)';
|
const NOT_SIZE_ON_DISK = '(does not represent size on disk)';
|
||||||
|
const NO_SIZE_INFO = 'no size info';
|
||||||
|
|
||||||
function summarizeTableInput(tableStageInput: StageInput): string {
|
function summarizeTableInput(tableStageInput: StageInput): string {
|
||||||
if (tableStageInput.type !== 'table') return '';
|
if (tableStageInput.type !== 'table') return '';
|
||||||
|
@ -271,7 +272,7 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
|
||||||
title={
|
title={
|
||||||
c.bytes
|
c.bytes
|
||||||
? `Uncompressed size: ${formatBytesCompact(c.bytes)} ${NOT_SIZE_ON_DISK}`
|
? `Uncompressed size: ${formatBytesCompact(c.bytes)} ${NOT_SIZE_ON_DISK}`
|
||||||
: undefined
|
: NO_SIZE_INFO
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{Boolean(c.totalFiles) && (
|
{Boolean(c.totalFiles) && (
|
||||||
|
@ -378,7 +379,7 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
|
||||||
title={
|
title={
|
||||||
c.bytes
|
c.bytes
|
||||||
? `Uncompressed size: ${formatBytesCompact(c.bytes)} ${NOT_SIZE_ON_DISK}`
|
? `Uncompressed size: ${formatBytesCompact(c.bytes)} ${NOT_SIZE_ON_DISK}`
|
||||||
: undefined
|
: NO_SIZE_INFO
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -395,19 +396,15 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
|
||||||
const hasCounter = stages.hasCounterForStage(stage, inputCounter);
|
const hasCounter = stages.hasCounterForStage(stage, inputCounter);
|
||||||
const bytes = stages.getTotalCounterForStage(stage, inputCounter, 'bytes');
|
const bytes = stages.getTotalCounterForStage(stage, inputCounter, 'bytes');
|
||||||
const inputFileCount = stages.getTotalCounterForStage(stage, inputCounter, 'totalFiles');
|
const inputFileCount = stages.getTotalCounterForStage(stage, inputCounter, 'totalFiles');
|
||||||
|
const inputLabel = `${formatInputLabel(stage, inputNumber)} (input${inputNumber})`;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="data-transfer"
|
className="data-transfer"
|
||||||
key={inputNumber}
|
key={inputNumber}
|
||||||
title={
|
title={
|
||||||
bytes
|
bytes
|
||||||
? `${formatInputLabel(
|
? `${inputLabel} uncompressed size: ${formatBytesCompact(bytes)} ${NOT_SIZE_ON_DISK}`
|
||||||
stage,
|
: `${inputLabel}: ${NO_SIZE_INFO}`
|
||||||
inputNumber,
|
|
||||||
)} (input${inputNumber}) uncompressed size: ${formatBytesCompact(
|
|
||||||
bytes,
|
|
||||||
)} ${NOT_SIZE_ON_DISK}`
|
|
||||||
: undefined
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<BracedText
|
<BracedText
|
||||||
|
@ -510,7 +507,7 @@ ${title} uncompressed size: ${formatBytesCompact(
|
||||||
if (!stages.hasCounterForStage(stage, 'segmentGenerationProgress')) return;
|
if (!stages.hasCounterForStage(stage, 'segmentGenerationProgress')) return;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="data-transfer">
|
<div className="data-transfer" title={NO_SIZE_INFO}>
|
||||||
<BracedText
|
<BracedText
|
||||||
text={formatRows(stages.getTotalSegmentGenerationProgressForStage(stage, field))}
|
text={formatRows(stages.getTotalSegmentGenerationProgressForStage(stage, field))}
|
||||||
braces={rowsValues}
|
braces={rowsValues}
|
||||||
|
|
Loading…
Reference in New Issue