mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: add notification for non-matching queries (#4301)
vmui: add notification for non-matching queries (#4211) https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4211
This commit is contained in:
parent
5a7159ab2e
commit
f0fad01e8a
7 changed files with 64 additions and 3 deletions
|
@ -20,3 +20,8 @@ export interface TracingData {
|
|||
duration_msec: number;
|
||||
children: TracingData[];
|
||||
}
|
||||
|
||||
export interface QueryStats {
|
||||
seriesFetched?: string;
|
||||
resultLength?: number;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import { ErrorTypes } from "../../../types";
|
|||
import TextField from "../../Main/TextField/TextField";
|
||||
import Autocomplete from "../../Main/Autocomplete/Autocomplete";
|
||||
import "./style.scss";
|
||||
import { QueryStats } from "../../../api/types";
|
||||
import Tooltip from "../../Main/Tooltip/Tooltip";
|
||||
import { WarningIcon } from "../../Main/Icons";
|
||||
|
||||
export interface QueryEditorProps {
|
||||
onChange: (query: string) => void;
|
||||
|
@ -14,6 +17,7 @@ export interface QueryEditorProps {
|
|||
oneLiner?: boolean;
|
||||
autocomplete: boolean;
|
||||
error?: ErrorTypes | string;
|
||||
stats?: QueryStats;
|
||||
options: string[];
|
||||
label: string;
|
||||
disabled?: boolean
|
||||
|
@ -27,6 +31,7 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
onArrowDown,
|
||||
autocomplete,
|
||||
error,
|
||||
stats,
|
||||
options,
|
||||
label,
|
||||
disabled = false
|
||||
|
@ -34,6 +39,7 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
|
||||
const [openAutocomplete, setOpenAutocomplete] = useState(false);
|
||||
const autocompleteAnchorEl = useRef<HTMLDivElement>(null);
|
||||
const showSeriesFetchedWarning = stats?.seriesFetched === "0" && !stats.resultLength;
|
||||
|
||||
const handleSelect = (val: string) => {
|
||||
onChange(val);
|
||||
|
@ -90,6 +96,23 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
onOpenAutocomplete={setOpenAutocomplete}
|
||||
/>
|
||||
)}
|
||||
{showSeriesFetchedWarning && (
|
||||
<div className="vm-query-editor-warning">
|
||||
<Tooltip
|
||||
placement="bottom-right"
|
||||
title={(
|
||||
<span className="vm-query-editor-warning__tooltip">
|
||||
{`No match!
|
||||
This query hasn't selected any time series from database.
|
||||
Either the requested metrics are missing in the database,
|
||||
or there is a typo in series selector.`}
|
||||
</span>
|
||||
)}
|
||||
>
|
||||
<WarningIcon/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,27 @@
|
|||
@use "src/styles/variables" as *;
|
||||
|
||||
.vm-query-editor {
|
||||
position: relative;
|
||||
|
||||
&-autocomplete {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&-warning {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: $padding-global;
|
||||
transform: translateY(-50%);
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
color: $color-warning;
|
||||
|
||||
&__tooltip {
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback, useEffect, useMemo, useState } from "preact/compat";
|
||||
import { getQueryRangeUrl, getQueryUrl } from "../api/query-range";
|
||||
import { useAppState } from "../state/common/StateContext";
|
||||
import { InstantMetricResult, MetricBase, MetricResult } from "../api/types";
|
||||
import { InstantMetricResult, MetricBase, MetricResult, QueryStats } from "../api/types";
|
||||
import { isValidHttpUrl } from "../utils/url";
|
||||
import { ErrorTypes, SeriesLimits } from "../types";
|
||||
import debounce from "lodash.debounce";
|
||||
|
@ -28,9 +28,10 @@ interface FetchQueryReturn {
|
|||
liveData?: InstantMetricResult[],
|
||||
error?: ErrorTypes | string,
|
||||
queryErrors: (ErrorTypes | string)[],
|
||||
queryStats: QueryStats[],
|
||||
warning?: string,
|
||||
traces?: Trace[],
|
||||
isHistogram: boolean,
|
||||
isHistogram: boolean
|
||||
}
|
||||
|
||||
interface FetchDataParams {
|
||||
|
@ -62,6 +63,7 @@ export const useFetchQuery = ({
|
|||
const [traces, setTraces] = useState<Trace[]>();
|
||||
const [error, setError] = useState<ErrorTypes | string>();
|
||||
const [queryErrors, setQueryErrors] = useState<(ErrorTypes | string)[]>([]);
|
||||
const [queryStats, setQueryStats] = useState<QueryStats[]>([]);
|
||||
const [warning, setWarning] = useState<string>();
|
||||
const [fetchQueue, setFetchQueue] = useState<AbortController[]>([]);
|
||||
const [isHistogram, setIsHistogram] = useState(false);
|
||||
|
@ -90,6 +92,7 @@ export const useFetchQuery = ({
|
|||
const isHideQuery = hideQuery?.includes(counter - 1);
|
||||
if (isHideQuery) {
|
||||
setQueryErrors(prev => [...prev, ""]);
|
||||
setQueryStats(prev => [...prev, {}]);
|
||||
counter++;
|
||||
continue;
|
||||
}
|
||||
|
@ -98,6 +101,10 @@ export const useFetchQuery = ({
|
|||
const resp = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
setQueryStats(prev => [...prev, {
|
||||
...resp?.stats,
|
||||
resultLength: resp.data.result.length,
|
||||
}]);
|
||||
setQueryErrors(prev => [...prev, ""]);
|
||||
|
||||
if (resp.trace) {
|
||||
|
@ -139,6 +146,7 @@ export const useFetchQuery = ({
|
|||
const fetchUrl = useMemo(() => {
|
||||
setError("");
|
||||
setQueryErrors([]);
|
||||
setQueryStats([]);
|
||||
const expr = predefinedQuery ?? query;
|
||||
const displayChart = (display || displayType) === "chart";
|
||||
if (!period) return;
|
||||
|
@ -184,5 +192,5 @@ export const useFetchQuery = ({
|
|||
setFetchQueue(fetchQueue.filter(f => !f.signal.aborted));
|
||||
}, [fetchQueue]);
|
||||
|
||||
return { fetchUrl, isLoading, graphData, liveData, error, queryErrors, warning, traces, isHistogram };
|
||||
return { fetchUrl, isLoading, graphData, liveData, error, queryErrors, queryStats, warning, traces, isHistogram };
|
||||
};
|
||||
|
|
|
@ -14,9 +14,11 @@ import classNames from "classnames";
|
|||
import { MouseEvent as ReactMouseEvent } from "react";
|
||||
import { arrayEquals } from "../../../utils/array";
|
||||
import useDeviceDetect from "../../../hooks/useDeviceDetect";
|
||||
import { QueryStats } from "../../../api/types";
|
||||
|
||||
export interface QueryConfiguratorProps {
|
||||
errors: (ErrorTypes | string)[];
|
||||
stats: QueryStats[];
|
||||
queryOptions: string[]
|
||||
onHideQuery: (queries: number[]) => void
|
||||
onRunQuery: () => void
|
||||
|
@ -24,6 +26,7 @@ export interface QueryConfiguratorProps {
|
|||
|
||||
const QueryConfigurator: FC<QueryConfiguratorProps> = ({
|
||||
errors,
|
||||
stats,
|
||||
queryOptions,
|
||||
onHideQuery,
|
||||
onRunQuery
|
||||
|
@ -142,6 +145,7 @@ const QueryConfigurator: FC<QueryConfiguratorProps> = ({
|
|||
autocomplete={autocomplete}
|
||||
options={queryOptions}
|
||||
error={errors[i]}
|
||||
stats={stats[i]}
|
||||
onArrowUp={createHandlerArrow(-1, i)}
|
||||
onArrowDown={createHandlerArrow(1, i)}
|
||||
onEnter={handleRunQuery}
|
||||
|
|
|
@ -49,6 +49,7 @@ const CustomPanel: FC = () => {
|
|||
graphData,
|
||||
error,
|
||||
queryErrors,
|
||||
queryStats,
|
||||
warning,
|
||||
traces,
|
||||
isHistogram
|
||||
|
@ -115,6 +116,7 @@ const CustomPanel: FC = () => {
|
|||
>
|
||||
<QueryConfigurator
|
||||
errors={!hideError ? queryErrors : []}
|
||||
stats={queryStats}
|
||||
queryOptions={queryOptions}
|
||||
onHideQuery={handleHideQuery}
|
||||
onRunQuery={handleRunQuery}
|
||||
|
|
|
@ -48,6 +48,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
|||
* 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: [vmui](https://docs.victoriametrics.com/#vmui): add notification icon for queries that do not match any time series. A warning icon appears next to the query field when the executed query does not match any time series. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4211).
|
||||
* 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).
|
||||
* FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): store backup creation and completion time in `backup_complete.ignore` file of backup contents. This allows determining the exact timestamp when the backup was created and completed.
|
||||
* FEATURE: [vmbackupmanager](https://docs.victoriametrics.com/vmbackupmanager.html): add `created_at` field to the output of `/api/v1/backups` API and `vmbackupmanager backup list` command. See this [doc](https://docs.victoriametrics.com/vmbackupmanager.html#api-methods) for data format details.
|
||||
|
|
Loading…
Reference in a new issue