Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: Add filter compaction UI #4576

Merged
merged 3 commits into from
Nov 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re
- [#4764](https://github.com/thanos-io/thanos/pull/4764) Compactor: add `block-viewer.global.sync-block-timeout` flag to set the timeout of synchronization block metas.
- [#4801](https://github.com/thanos-io/thanos/pull/4801) Compactor: added Prometheus metrics for tracking the progress of compaction and downsampling.
- [#4444](https://github.com/thanos-io/thanos/pull/4444) UI: add mark deletion and no compaction to the Block UI.
- [#4576](https://github.com/thanos-io/thanos/pull/4576) UI: add filter compaction level to the Block UI.

### Fixed

Expand Down
98 changes: 49 additions & 49 deletions pkg/ui/bindata.go

Large diffs are not rendered by default.

6,702 changes: 101 additions & 6,601 deletions pkg/ui/react-app/package-lock.json

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions pkg/ui/react-app/src/thanos/pages/blocks/BlockFilterCompaction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { FC, ChangeEvent } from 'react';
import Checkbox from '../../../components/Checkbox';
import { Input } from 'reactstrap';
import styles from './blocks.module.css';

interface BlockFilterCompactionProps {
id: string;
defaultChecked: boolean;
onChangeCheckbox: ({ target }: ChangeEvent<HTMLInputElement>) => void;
onChangeInput: ({ target }: ChangeEvent<HTMLInputElement>) => void;
defaultValue: string;
}

export const BlockFilterCompaction: FC<BlockFilterCompactionProps> = ({
id,
defaultChecked,
onChangeCheckbox,
onChangeInput,
defaultValue,
}) => {
return (
<div className={styles.blockFilter} style={{ marginLeft: '24px' }}>
<Checkbox style={{ marginRight: '4px' }} id={id} defaultChecked={defaultChecked} onChange={onChangeCheckbox} />
<p style={{ marginRight: '4px' }}>Filter by compaction level</p>
<Input
type="number"
style={{ width: '80px', marginBottom: '1rem' }}
onChange={onChangeInput}
defaultValue={defaultValue}
min={0}
/>
</div>
);
};
80 changes: 67 additions & 13 deletions pkg/ui/react-app/src/thanos/pages/blocks/Blocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Block } from './block';
import { SourceView } from './SourceView';
import { BlockDetails } from './BlockDetails';
import { BlockSearchInput } from './BlockSearchInput';
import { BlockFilterCompaction } from './BlockFilterCompaction';
import { sortBlocks } from './helpers';
import styles from './blocks.module.css';
import TimeRange from './TimeRange';
Expand All @@ -24,6 +25,7 @@ export interface BlockListProps {
export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => {
const [selectedBlock, selectBlock] = useState<Block>();
const [searchState, setSearchState] = useState<string>('');

const { blocks, label, err } = data;

const [gridMinTime, gridMaxTime] = useMemo(() => {
Expand All @@ -44,16 +46,28 @@ export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => {
}, [blocks, err]);

const [
{ 'min-time': viewMinTime, 'max-time': viewMaxTime, ulid: blockSearchParam, 'find-overlapping': findOverlappingParam },
{
'min-time': viewMinTime,
'max-time': viewMaxTime,
ulid: blockSearchParam,
'find-overlapping': findOverlappingParam,
'filter-compaction': filterCompactionParam,
'compaction-level': compactionLevelParam,
},
setQuery,
] = useQueryParams({
'min-time': withDefault(NumberParam, gridMinTime),
'max-time': withDefault(NumberParam, gridMaxTime),
ulid: withDefault(StringParam, ''),
'find-overlapping': withDefault(BooleanParam, false),
'filter-compaction': withDefault(BooleanParam, false),
'compaction-level': withDefault(NumberParam, 0),
});

const [filterCompaction, setFilterCompaction] = useState<boolean>(filterCompactionParam);
const [findOverlappingBlocks, setFindOverlappingBlocks] = useState<boolean>(findOverlappingParam);
const [compactionLevel, setCompactionLevel] = useState<number>(compactionLevelParam);
const [compactionLevelInput, setCompactionLevelInput] = useState<string>(compactionLevelParam.toString());
const [blockSearch, setBlockSearch] = useState<string>(blockSearchParam);

const blockPools = useMemo(() => sortBlocks(blocks, label, findOverlappingBlocks), [blocks, label, findOverlappingBlocks]);
Expand All @@ -72,6 +86,34 @@ export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => {
setBlockSearch(searchState);
};

const onChangeCompactionCheckbox = (target: EventTarget & HTMLInputElement) => {
setFilterCompaction(target.checked);
if (target.checked) {
let compactionLevel: number = parseInt(compactionLevelInput);
setQuery({
'filter-compaction': target.checked,
'compaction-level': compactionLevel,
});
setCompactionLevel(compactionLevel);
} else {
setQuery({
'filter-compaction': target.checked,
'compaction-level': 0,
});
setCompactionLevel(0);
}
};

const onChangeCompactionInput = (target: HTMLInputElement) => {
if (filterCompaction) {
setQuery({
'compaction-level': parseInt(target.value),
});
setCompactionLevel(parseInt(target.value));
}
setCompactionLevelInput(target.value);
};

if (err) return <UncontrolledAlert color="danger">{err.toString()}</UncontrolledAlert>;

return (
Expand All @@ -83,18 +125,29 @@ export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => {
onClick={() => setBlockSearchInput(searchState)}
defaultValue={blockSearchParam}
/>
<Checkbox
id="find-overlap-block-checkbox"
onChange={({ target }) => {
setQuery({
'find-overlapping': target.checked,
});
setFindOverlappingBlocks(target.checked);
}}
defaultChecked={findOverlappingBlocks}
>
Enable finding overlapping blocks
</Checkbox>
<div className={styles.blockFilter}>
<Checkbox
id="find-overlap-block-checkbox"
onChange={({ target }) => {
setQuery({
'find-overlapping': target.checked,
});
setFindOverlappingBlocks(target.checked);
}}
defaultChecked={findOverlappingBlocks}
>
Enable finding overlapping blocks
</Checkbox>
<BlockFilterCompaction
id="filter-compaction-checkbox"
defaultChecked={filterCompaction}
onChangeCheckbox={({ target }) => onChangeCompactionCheckbox(target)}
onChangeInput={({ target }: ChangeEvent<HTMLInputElement>): void => {
onChangeCompactionInput(target);
}}
defaultValue={compactionLevelInput}
/>
</div>
<div className={styles.container}>
<div className={styles.grid}>
<div className={styles.sources}>
Expand All @@ -107,6 +160,7 @@ export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => {
gridMinTime={viewMinTime}
gridMaxTime={viewMaxTime}
blockSearch={blockSearch}
compactionLevel={compactionLevel}
/>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('Blocks SourceView', () => {
gridMinTime: 1596096000000,
gridMaxTime: 1595108031471,
blockSearch: '',
compactionLevel: 0,
};

const sourceView = mount(<SourceView {...defaultProps} />);
Expand Down
22 changes: 17 additions & 5 deletions pkg/ui/react-app/src/thanos/pages/blocks/SourceView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@ import React, { FC } from 'react';
import { Block, BlocksPool } from './block';
import { BlockSpan } from './BlockSpan';
import styles from './blocks.module.css';
import { getBlockByUlid } from './helpers';
import { getBlockByUlid, getBlocksByCompactionLevel } from './helpers';

export const BlocksRow: FC<{
blocks: Block[];
gridMinTime: number;
gridMaxTime: number;
selectBlock: React.Dispatch<React.SetStateAction<Block | undefined>>;
blockSearch: string;
}> = ({ blocks, gridMinTime, gridMaxTime, selectBlock, blockSearch }) => {
const blockSearchValue = getBlockByUlid(blocks, blockSearch);
compactionLevel: number;
}> = ({ blocks, gridMinTime, gridMaxTime, selectBlock, blockSearch, compactionLevel }) => {
let filteredBlocks = getBlockByUlid(blocks, blockSearch);
filteredBlocks = getBlocksByCompactionLevel(filteredBlocks, compactionLevel);

return (
<div className={styles.row}>
{blockSearchValue.map<JSX.Element>((b) => (
{filteredBlocks.map<JSX.Element>((b) => (
<BlockSpan selectBlock={selectBlock} block={b} gridMaxTime={gridMaxTime} gridMinTime={gridMinTime} key={b.ulid} />
))}
</div>
Expand All @@ -29,9 +31,18 @@ export interface SourceViewProps {
gridMaxTime: number;
selectBlock: React.Dispatch<React.SetStateAction<Block | undefined>>;
blockSearch: string;
compactionLevel: number;
}

export const SourceView: FC<SourceViewProps> = ({ data, title, gridMaxTime, gridMinTime, selectBlock, blockSearch }) => {
export const SourceView: FC<SourceViewProps> = ({
data,
title,
gridMaxTime,
gridMinTime,
selectBlock,
blockSearch,
compactionLevel,
}) => {
return (
<>
<div className={styles.source}>
Expand All @@ -49,6 +60,7 @@ export const SourceView: FC<SourceViewProps> = ({ data, title, gridMaxTime, grid
gridMaxTime={gridMaxTime}
gridMinTime={gridMinTime}
blockSearch={blockSearch}
compactionLevel={compactionLevel}
/>
))}
</React.Fragment>
Expand Down
6 changes: 6 additions & 0 deletions pkg/ui/react-app/src/thanos/pages/blocks/blocks.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,9 @@
.blockInput {
margin-bottom: 12px;
}

.blockFilter {
display: flex;
flex-direction: row;
align-items: center;
}
9 changes: 9 additions & 0 deletions pkg/ui/react-app/src/thanos/pages/blocks/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,12 @@ export const getBlockByUlid = (blocks: Block[], ulid: string): Block[] => {
const blockResult = blocks.filter((block, index) => resultIndex.includes(index));
return blockResult;
};

export const getBlocksByCompactionLevel = (blocks: Block[], compactionLevel: number): Block[] => {
if (compactionLevel === 0 || Number.isNaN(compactionLevel)) {
return blocks;
}

const blockResult = blocks.filter((block) => block.compaction.level === compactionLevel);
return blockResult;
};