vmui: enhancements to top queries page (#4299)

* feat: improvement of the top queries page

* vmui/docs: enhancements to top queries page

* Apply suggestions from code review

---------

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Yury Molodov 2023-05-11 22:47:32 +02:00 committed by GitHub
parent 9855b38da2
commit 1e4a9a8dfe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 11 deletions

View file

@ -11,7 +11,7 @@ import useDeviceDetect from "../../../hooks/useDeviceDetect";
export interface TopQueryPanelProps {
rows: TopQuery[],
title?: string,
columns: {title?: string, key: (keyof TopQuery)}[],
columns: {title?: string, key: (keyof TopQuery), sortBy?: (keyof TopQuery)}[],
defaultOrderBy?: keyof TopQuery,
}
const tabs = ["table", "JSON"].map((t, i) => ({

View file

@ -3,14 +3,20 @@ import { TopQuery } from "../../../types";
import { getComparator, stableSort } from "../../CardinalityPanel/Table/helpers";
import { TopQueryPanelProps } from "../TopQueryPanel/TopQueryPanel";
import classNames from "classnames";
import { ArrowDropDownIcon } from "../../../components/Main/Icons";
import { ArrowDropDownIcon, CopyIcon, PlayCircleOutlineIcon } from "../../../components/Main/Icons";
import Button from "../../../components/Main/Button/Button";
import Tooltip from "../../../components/Main/Tooltip/Tooltip";
import { useSnack } from "../../../contexts/Snackbar";
import { Link } from "react-router-dom";
import router from "../../../router";
const TopQueryTable:FC<TopQueryPanelProps> = ({ rows, columns, defaultOrderBy }) => {
const { showInfoMessage } = useSnack();
const [orderBy, setOrderBy] = useState<keyof TopQuery>(defaultOrderBy || "count");
const [orderDir, setOrderDir] = useState<"asc" | "desc">("desc");
const sortedList = useMemo(() => stableSort(rows as [], getComparator(orderDir, orderBy)),
const sortedList = useMemo(() => stableSort(rows as [], getComparator(orderDir, orderBy)) as TopQuery[],
[rows, orderBy, orderDir]);
const onSortHandler = (key: keyof TopQuery) => {
@ -22,6 +28,12 @@ const TopQueryTable:FC<TopQueryPanelProps> = ({ rows, columns, defaultOrderBy })
onSortHandler(col);
};
const createCopyHandler = ({ query }: TopQuery) => () => {
// TODO add useCopyToClipboard after merge https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4145
navigator.clipboard.writeText(query);
showInfoMessage({ text: "Query has been copied", type: "success" });
};
return (
<table className="vm-table">
<thead className="vm-table-header">
@ -29,7 +41,7 @@ const TopQueryTable:FC<TopQueryPanelProps> = ({ rows, columns, defaultOrderBy })
{columns.map((col) => (
<th
className="vm-table-cell vm-table-cell_header vm-table-cell_sort"
onClick={createSortHandler(col.key)}
onClick={createSortHandler(col.sortBy || col.key)}
key={col.key}
>
<div className="vm-table-cell__content">
@ -46,6 +58,7 @@ const TopQueryTable:FC<TopQueryPanelProps> = ({ rows, columns, defaultOrderBy })
</div>
</th>
))}
<th className="vm-table-cell vm-table-cell_header"/> {/* empty cell for actions */}
</tr>
</thead>
<tbody className="vm-table-body">
@ -62,6 +75,31 @@ const TopQueryTable:FC<TopQueryPanelProps> = ({ rows, columns, defaultOrderBy })
{row[col.key] || "-"}
</td>
))}
<td className="vm-table-cell vm-table-cell_no-padding">
<div className="vm-top-queries-panels__table-actions">
<Tooltip title={"Execute query"}>
<Link
to={`${router.home}?g0.expr=${encodeURIComponent(row.query)}`}
target="_blank"
rel="noreferrer"
>
<Button
variant="text"
size="small"
startIcon={<PlayCircleOutlineIcon/>}
/>
</Link>
</Tooltip>
<Tooltip title={"Copy query"}>
<Button
variant="text"
size="small"
startIcon={<CopyIcon/>}
onClick={createCopyHandler(row)}
/>
</Tooltip>
</div>
</td>
</tr>
))}
</tbody>

View file

@ -5,6 +5,7 @@ import { useMemo } from "preact/compat";
import { getTopQueries } from "../../../api/top-queries";
import { TopQueriesData } from "../../../types";
import { useTopQueriesState } from "../../../state/topQueries/TopQueriesStateContext";
import { getDurationFromMilliseconds } from "../../../utils/time";
export const useFetchTopQueries = () => {
const { serverUrl } = useAppState();
@ -26,7 +27,7 @@ export const useFetchTopQueries = () => {
list.forEach(key => {
const target = resp[key];
if (Array.isArray(target)) {
target.forEach(t => t.timeRangeHours = +(t.timeRangeSeconds/3600).toFixed(2));
target.forEach(t => t.timeRange = getDurationFromMilliseconds(t.timeRangeSeconds*1000));
}
});
}

View file

@ -147,7 +147,7 @@ const TopQueries: FC = () => {
title={"Most frequently executed queries"}
columns={[
{ key: "query" },
{ key: "timeRangeHours", title: "time range, hours" },
{ key: "timeRange", sortBy: "timeRangeSeconds", title: "Query Time Interval" },
{ key: "count" }
]}
/>
@ -156,8 +156,8 @@ const TopQueries: FC = () => {
title={"Most heavy queries"}
columns={[
{ key: "query" },
{ key: "avgDurationSeconds", title: "avg duration, seconds" },
{ key: "timeRangeHours", title: "time range, hours" },
{ key: "avgDurationSeconds", title: "avg duration, sec" },
{ key: "timeRange", sortBy: "timeRangeSeconds", title: "Query Time Interval" },
{ key: "count" }
]}
defaultOrderBy={"avgDurationSeconds"}
@ -167,8 +167,8 @@ const TopQueries: FC = () => {
title={"Queries with most summary time to execute"}
columns={[
{ key: "query" },
{ key: "sumDurationSeconds", title: "sum duration, seconds" },
{ key: "timeRangeHours", title: "time range, hours" },
{ key: "sumDurationSeconds", title: "sum duration, sec" },
{ key: "timeRange", sortBy: "timeRangeSeconds", title: "Query Time Interval" },
{ key: "count" }
]}
defaultOrderBy={"sumDurationSeconds"}

View file

@ -51,5 +51,14 @@
&-panels {
display: grid;
gap: $padding-medium;
&__table-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: $padding-small;
height: 100%;
padding: 0 $padding-small;
}
}
}

View file

@ -31,6 +31,7 @@
height: 40px;
vertical-align: top;
line-height: 1.5;
overflow-wrap: anywhere;
&__content {
display: flex;
@ -68,6 +69,10 @@
&_no-wrap {
white-space: nowrap;
}
&_no-padding {
padding: 0;
}
}
&__sort-icon {

View file

@ -86,7 +86,7 @@ export interface TopQuery {
query: string
timeRangeSeconds: number
sumDurationSeconds: number
timeRangeHours: number
timeRange: string
}
export interface TopQueryStats {

View file

@ -45,6 +45,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): display histograms as heatmaps in [Metrics explorer](https://docs.victoriametrics.com/#metrics-explorer). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4111).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add `WITH template` playground. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3811).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add ability to debug relabeling. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3807).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add an ability to copy and execute queries listed at [top queries](https://docs.victoriametrics.com/#top-queries) page. Also make more human readable the query duration column. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4292) and [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4299).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): increase default font size for better readability.
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): [cardinality explorer](https://docs.victoriametrics.com/#cardinality-explorer): return back a table with labels containing the highest number of unique label values. See [issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4213).
* FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): add `-s3StorageClass` command-line flag for setting the storage class for AWS S3 backups. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4164). Thanks to @justcompile for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4166).