Skip to content

Commit

Permalink
ui: React: Separate dedupe and partial response checkboxes per panel (#…
Browse files Browse the repository at this point in the history
…2902)

* ui: React: Seperate deduplication and partial response checkboxes per panel

Signed-off-by: Prem Kumar <[email protected]>

* ui: React: update favicon

Signed-off-by: Prem Kumar <[email protected]>

* Encode dedupe and max source res in the URL

Signed-off-by: Prem Kumar <[email protected]>

* Fix and add new tests for query string options

Signed-off-by: Prem Kumar <[email protected]>

* Rename max_source_res query parameter to max_source_resolution

Signed-off-by: Prem Kumar <[email protected]>
  • Loading branch information
onprem authored Jul 28, 2020
1 parent bbbd78e commit c25e4cd
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 92 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ We use *breaking* word for marking changes that are not backward compatible (rel
- [#2893](https://github.com/thanos-io/thanos/pull/2893) Store: Rename metric `thanos_bucket_store_cached_postings_compression_time_seconds` to `thanos_bucket_store_cached_postings_compression_time_seconds_total`.
- [#2915](https://github.com/thanos-io/thanos/pull/2915) Receive,Ruler: Enable TSDB directory locking by default. Add a new flag (`--tsdb.no-lockfile`) to override behavior.

### Changed

- [#2902](https://github.com/thanos-io/thanos/pull/2902) ui: React: Separate dedupe and partial response checkboxes per panel.

## [v0.14.0](https://github.com/thanos-io/thanos/releases/tag/v0.14.0) - 2020.07.10

### Fixed
Expand Down
106 changes: 53 additions & 53 deletions pkg/ui/bindata.go

Large diffs are not rendered by default.

Binary file modified pkg/ui/react-app/public/favicon.ico
Binary file not shown.
10 changes: 8 additions & 2 deletions pkg/ui/react-app/src/pages/graph/Panel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ import DataTable from './DataTable';
import { GraphTabContent } from './GraphTabContent';

const defaultProps = {
id: 'abc123',
useLocalTime: false,
useDeduplication: true,
usePartialResponse: false,
options: {
expr: 'prometheus_engine',
type: PanelType.Table,
range: 10,
endTime: 1572100217898,
resolution: 28,
stacked: false,
maxSourceResolution: 'auto',
useDeduplication: true,
usePartialResponse: false,
},
onOptionsChanged: (): void => {
// Do nothing.
Expand Down Expand Up @@ -91,6 +93,9 @@ describe('Panel', () => {
endTime: 1572100217898,
resolution: 28,
stacked: false,
maxSourceResolution: 'auto',
useDeduplication: true,
usePartialResponse: false,
};
const graphPanel = mount(<Panel {...defaultProps} options={options} />);
const controls = graphPanel.find(GraphControls);
Expand All @@ -101,6 +106,7 @@ describe('Panel', () => {
expect(controls.prop('resolution')).toEqual(options.resolution);
expect(controls.prop('stacked')).toEqual(options.stacked);
expect(graph.prop('stacked')).toEqual(options.stacked);
expect(controls.prop('maxSourceResolution')).toEqual(options.maxSourceResolution);
});

describe('when switching between modes', () => {
Expand Down
59 changes: 52 additions & 7 deletions pkg/ui/react-app/src/pages/graph/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Alert, Button, Col, Nav, NavItem, NavLink, Row, TabContent, TabPane } f

import moment from 'moment-timezone';

import Checkbox from '../../components/Checkbox';
import ExpressionInput from './ExpressionInput';
import GraphControls from './GraphControls';
import { GraphTabContent } from './GraphTabContent';
Expand All @@ -14,11 +15,10 @@ import PathPrefixProps from '../../types/PathPrefixProps';
import { QueryParams } from '../../types/types';

interface PanelProps {
id: string;
options: PanelOptions;
onOptionsChanged: (opts: PanelOptions) => void;
useLocalTime: boolean;
useDeduplication: boolean;
usePartialResponse: boolean;
pastQueries: string[];
metricNames: string[];
removePanel: () => void;
Expand All @@ -42,6 +42,8 @@ export interface PanelOptions {
resolution: number | null; // Resolution in seconds.
stacked: boolean;
maxSourceResolution: string;
useDeduplication: boolean;
usePartialResponse: boolean;
}

export enum PanelType {
Expand All @@ -57,6 +59,8 @@ export const PanelDefaultOptions: PanelOptions = {
resolution: null,
stacked: false,
maxSourceResolution: '0s',
useDeduplication: true,
usePartialResponse: false,
};

class Panel extends Component<PanelProps & PathPrefixProps, PanelState> {
Expand All @@ -73,16 +77,29 @@ class Panel extends Component<PanelProps & PathPrefixProps, PanelState> {
stats: null,
exprInputValue: props.options.expr,
};

this.handleChangeDeduplication = this.handleChangeDeduplication.bind(this);
this.handleChangePartialResponse = this.handleChangePartialResponse.bind(this);
}

componentDidUpdate({ options: prevOpts }: PanelProps) {
const { endTime, range, resolution, type, maxSourceResolution } = this.props.options;
const {
endTime,
range,
resolution,
type,
maxSourceResolution,
useDeduplication,
usePartialResponse,
} = this.props.options;
if (
prevOpts.endTime !== endTime ||
prevOpts.range !== range ||
prevOpts.resolution !== resolution ||
prevOpts.type !== type ||
prevOpts.maxSourceResolution !== maxSourceResolution
prevOpts.maxSourceResolution !== maxSourceResolution ||
prevOpts.useDeduplication !== useDeduplication ||
prevOpts.usePartialResponse !== usePartialResponse
) {
this.executeQuery();
}
Expand Down Expand Up @@ -117,8 +134,8 @@ class Panel extends Component<PanelProps & PathPrefixProps, PanelState> {
const resolution = this.props.options.resolution || Math.max(Math.floor(this.props.options.range / 250), 1);
const params: URLSearchParams = new URLSearchParams({
query: expr,
dedup: this.props.useDeduplication.toString(),
partial_response: this.props.useDeduplication.toString(),
dedup: this.props.options.useDeduplication.toString(),
partial_response: this.props.options.usePartialResponse.toString(),
});

let path: string;
Expand Down Expand Up @@ -230,8 +247,16 @@ class Panel extends Component<PanelProps & PathPrefixProps, PanelState> {
this.setOptions({ stacked: stacked });
};

handleChangeDeduplication = (event: React.ChangeEvent<HTMLInputElement>): void => {
this.setOptions({ useDeduplication: event.target.checked });
};

handleChangePartialResponse = (event: React.ChangeEvent<HTMLInputElement>): void => {
this.setOptions({ usePartialResponse: event.target.checked });
};

render() {
const { pastQueries, metricNames, options } = this.props;
const { pastQueries, metricNames, options, id } = this.props;
return (
<div className="panel">
<Row>
Expand All @@ -251,6 +276,26 @@ class Panel extends Component<PanelProps & PathPrefixProps, PanelState> {
<Row>
<Col>{this.state.error && <Alert color="danger">{this.state.error}</Alert>}</Col>
</Row>
<Row>
<Col>
<Checkbox
wrapperStyles={{ marginLeft: 20, display: 'inline-block' }}
id={`use-deduplication-checkbox-${id}`}
onChange={this.handleChangeDeduplication}
defaultChecked={options.useDeduplication}
>
Use Deduplication
</Checkbox>
<Checkbox
wrapperStyles={{ marginLeft: 20, display: 'inline-block' }}
id={`use-partial-resp-checkbox-${id}`}
onChange={this.handleChangePartialResponse}
defaultChecked={options.usePartialResponse}
>
Use Partial Response
</Checkbox>
</Col>
</Row>
<Row>
<Col>
<Nav tabs>
Expand Down
27 changes: 1 addition & 26 deletions pkg/ui/react-app/src/pages/graph/PanelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@ interface PanelListProps extends PathPrefixProps, RouteComponentProps {
metrics: string[];
useLocalTime: boolean;
queryHistoryEnabled: boolean;
useDeduplication: boolean;
usePartialResponse: boolean;
}

export const PanelListContent: FC<PanelListProps> = ({
metrics = [],
useLocalTime,
useDeduplication,
usePartialResponse,
pathPrefix,
queryHistoryEnabled,
...rest
Expand Down Expand Up @@ -84,6 +80,7 @@ export const PanelListContent: FC<PanelListProps> = ({
onExecuteQuery={handleExecuteQuery}
key={id}
options={options}
id={id}
onOptionsChanged={opts =>
callAll(setPanels, updateURL)(panels.map(p => (id === p.id ? { ...p, options: opts } : p)))
}
Expand All @@ -99,8 +96,6 @@ export const PanelListContent: FC<PanelListProps> = ({
)
}
useLocalTime={useLocalTime}
useDeduplication={useDeduplication}
usePartialResponse={usePartialResponse}
metricNames={metrics}
pastQueries={queryHistoryEnabled ? historyItems : []}
pathPrefix={pathPrefix}
Expand All @@ -117,8 +112,6 @@ const PanelList: FC<RouteComponentProps & PathPrefixProps> = ({ pathPrefix = ''
const [delta, setDelta] = useState(0);
const [useLocalTime, setUseLocalTime] = useLocalStorage('use-local-time', false);
const [enableQueryHistory, setEnableQueryHistory] = useLocalStorage('enable-query-history', false);
const [useDeduplication, setUseDeduplication] = useLocalStorage('use-deduplication', true);
const [usePartialResponse, setUsePartialResponse] = useLocalStorage('use-partial-response', false);

const { response: metricsRes, error: metricsErr } = useFetch<string[]>(`${pathPrefix}/api/v1/label/__name__/values`);

Expand Down Expand Up @@ -156,22 +149,6 @@ const PanelList: FC<RouteComponentProps & PathPrefixProps> = ({ pathPrefix = ''
>
Use local time
</Checkbox>
<Checkbox
wrapperStyles={{ marginLeft: 20, display: 'inline-block' }}
id="use-deduplication-checkbox"
onChange={({ target }) => setUseDeduplication(target.checked)}
defaultChecked={useDeduplication}
>
Use Deduplication
</Checkbox>
<Checkbox
wrapperStyles={{ marginLeft: 20, display: 'inline-block' }}
id="use-partial-response-checkbox"
onChange={({ target }) => setUsePartialResponse(target.checked)}
defaultChecked={usePartialResponse}
>
Use Partial Response
</Checkbox>
{(delta > 30 || timeErr) && (
<Alert color="danger">
<strong>Warning: </strong>
Expand All @@ -190,8 +167,6 @@ const PanelList: FC<RouteComponentProps & PathPrefixProps> = ({ pathPrefix = ''
panels={decodePanelOptionsFromQueryString(window.location.search)}
pathPrefix={pathPrefix}
useLocalTime={useLocalTime}
usePartialResponse={usePartialResponse}
useDeduplication={useDeduplication}
metrics={metricsRes.data}
queryHistoryEnabled={enableQueryHistory}
/>
Expand Down
24 changes: 23 additions & 1 deletion pkg/ui/react-app/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ export const parseOption = (param: string): Partial<PanelOptions> => {
case 'step_input':
const resolution = parseInt(decodedValue);
return resolution > 0 ? { resolution } : {};

case 'max_source_resolution':
return { maxSourceResolution: decodedValue };

case 'deduplicate':
return { useDeduplication: decodedValue === '1' };

case 'partial_response':
return { usePartialResponse: decodedValue === '1' };
}
return {};
};
Expand All @@ -181,13 +190,26 @@ export const formatParam = (key: string) => (paramName: string, value: number |

export const toQueryString = ({ key, options }: PanelMeta) => {
const formatWithKey = formatParam(key);
const { expr, type, stacked, range, endTime, resolution } = options;
const {
expr,
type,
stacked,
range,
endTime,
resolution,
maxSourceResolution,
useDeduplication,
usePartialResponse,
} = options;
const time = isPresent(endTime) ? formatTime(endTime) : false;
const urlParams = [
formatWithKey('expr', expr),
formatWithKey('tab', type === PanelType.Graph ? 0 : 1),
formatWithKey('stacked', stacked ? 1 : 0),
formatWithKey('range_input', formatRange(range)),
formatWithKey('max_source_resolution', maxSourceResolution),
formatWithKey('deduplicate', useDeduplication ? 1 : 0),
formatWithKey('partial_response', usePartialResponse ? 1 : 0),
time ? `${formatWithKey('end_input', time)}&${formatWithKey('moment_input', time)}` : '',
isPresent(resolution) ? formatWithKey('step_input', resolution) : '',
];
Expand Down
34 changes: 31 additions & 3 deletions pkg/ui/react-app/src/utils/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ describe('Utils', () => {
range: 3600,
resolution: null,
stacked: false,
maxSourceResolution: 'raw',
useDeduplication: true,
usePartialResponse: false,
type: PanelType.Graph,
},
},
Expand All @@ -154,12 +157,15 @@ describe('Utils', () => {
range: 3600,
resolution: null,
stacked: false,
maxSourceResolution: 'auto',
useDeduplication: false,
usePartialResponse: true,
type: PanelType.Table,
},
},
];
const query =
'?g0.expr=rate(node_cpu_seconds_total%7Bmode%3D%22system%22%7D%5B1m%5D)&g0.tab=0&g0.stacked=0&g0.range_input=1h&g0.end_input=2019-10-25%2023%3A37%3A00&g0.moment_input=2019-10-25%2023%3A37%3A00&g1.expr=node_filesystem_avail_bytes&g1.tab=1&g1.stacked=0&g1.range_input=1h';
'?g0.expr=rate(node_cpu_seconds_total%7Bmode%3D%22system%22%7D%5B1m%5D)&g0.tab=0&g0.stacked=0&g0.range_input=1h&g0.max_source_resolution=raw&g0.deduplicate=1&g0.partial_response=0&g0.end_input=2019-10-25%2023%3A37%3A00&g0.moment_input=2019-10-25%2023%3A37%3A00&g1.expr=node_filesystem_avail_bytes&g1.tab=1&g1.stacked=0&g1.range_input=1h&g1.max_source_resolution=auto&g1.deduplicate=0&g1.partial_response=1';

describe('decodePanelOptionsFromQueryString', () => {
it('returns [] when query is empty', () => {
Expand Down Expand Up @@ -189,6 +195,16 @@ describe('Utils', () => {
});
});

it('should parse max source res', () => {
expect(parseOption('max_source_resolution=auto')).toEqual({ maxSourceResolution: 'auto' });
});
it('should parse use deduplicate', () => {
expect(parseOption('deduplicate=1')).toEqual({ useDeduplication: true });
});
it('should parse partial_response', () => {
expect(parseOption('partial_response=1')).toEqual({ usePartialResponse: true });
});

describe('step_input', () => {
it('should return step_input parsed if > 0', () => {
expect(parseOption('step_input=2')).toEqual({ resolution: 2 });
Expand Down Expand Up @@ -223,9 +239,21 @@ describe('Utils', () => {
toQueryString({
id: 'asdf',
key: '0',
options: { expr: 'foo', type: PanelType.Graph, stacked: true, range: 0, endTime: null, resolution: 1 },
options: {
expr: 'foo',
type: PanelType.Graph,
stacked: true,
range: 0,
endTime: null,
resolution: 1,
maxSourceResolution: 'raw',
useDeduplication: true,
usePartialResponse: false,
},
})
).toEqual('g0.expr=foo&g0.tab=0&g0.stacked=1&g0.range_input=0y&g0.step_input=1');
).toEqual(
'g0.expr=foo&g0.tab=0&g0.stacked=1&g0.range_input=0y&g0.max_source_resolution=raw&g0.deduplicate=1&g0.partial_response=0&g0.step_input=1'
);
});
});

Expand Down

0 comments on commit c25e4cd

Please sign in to comment.