mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-11 14:53:49 +00:00
vmui: fix predefined panels
### Describe Your Changes - Fixes the handling of the `showLegend` flag. - Fixes the handling of `alias`. - Adds support for alias templates, allowing dynamic substitutions like `{{label_name}}`. Related issue: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7565
This commit is contained in:
parent
0f06d2f072
commit
dec9a2f023
10 changed files with 84 additions and 35 deletions
|
@ -37,7 +37,7 @@ type panelSettings struct {
|
||||||
Unit string `json:"unit,omitempty"`
|
Unit string `json:"unit,omitempty"`
|
||||||
Expr []string `json:"expr"`
|
Expr []string `json:"expr"`
|
||||||
Alias []string `json:"alias,omitempty"`
|
Alias []string `json:"alias,omitempty"`
|
||||||
ShowLegend bool `json:"showLegend,omitempty"`
|
ShowLegend *bool `json:"showLegend"`
|
||||||
Width int `json:"width,omitempty"`
|
Width int `json:"width,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,17 @@ func collectDashboardsSettings(path string) ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse file %s: %w", filePath, err)
|
return nil, fmt.Errorf("cannot parse file %s: %w", filePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := range ds.Rows {
|
||||||
|
for j := range ds.Rows[i].Panels {
|
||||||
|
// Set default value for ShowLegend = true if it is not specified
|
||||||
|
if ds.Rows[i].Panels[j].ShowLegend == nil {
|
||||||
|
defaultValue := true
|
||||||
|
ds.Rows[i].Panels[j].ShowLegend = &defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(ds.Rows) > 0 {
|
if len(ds.Rows) > 0 {
|
||||||
dss = append(dss, ds)
|
dss = append(dss, ds)
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,15 +128,27 @@ DashboardRow:
|
||||||
PanelSettings:
|
PanelSettings:
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
|:------------|:----------:|--------------------------------------------------------------------------------------:|
|
|:------------|:----------:|---------------------------------------------------------------------------------------------------------------:|
|
||||||
| expr* | `string[]` | Data source queries |
|
| expr* | `string[]` | Data source queries |
|
||||||
| alias | `string[]` | Expression alias. Matched by index in array |
|
| alias | `string[]` | An array of aliases for each expression in `expr`. See [Template Support in alias](#template-support-in-alias) |
|
||||||
| title | `string` | Panel title |
|
| title | `string` | Panel title |
|
||||||
| description | `string` | Additional information about the panel |
|
| description | `string` | Additional information about the panel |
|
||||||
| unit | `string` | Y-axis unit |
|
| unit | `string` | Y-axis unit |
|
||||||
| showLegend | `boolean` | If `false`, the legend hide. Default value - `true` |
|
| showLegend | `boolean` | If `false`, the legend hide. Default value - `true` |
|
||||||
| width | `number` | The number of columns the panel uses.<br/> From 1 (minimum width) to 12 (full width). |
|
| width | `number` | The number of columns the panel uses.<br/> From 1 (minimum width) to 12 (full width). |
|
||||||
|
|
||||||
|
### Template Support in `alias`
|
||||||
|
|
||||||
|
To create more readable metric names in the legend, you can use constructions like `{{label_name}}`, where `label_name`
|
||||||
|
is the label's name.
|
||||||
|
If the label exists in the metric, its value will be substituted in the template.
|
||||||
|
If the label is missing, the legend will use the default name.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
Metric: `metric{foo="bar",baz="qux"}`
|
||||||
|
Alias: `{{foo}} - {{baz}}`
|
||||||
|
Legend: `bar - qux`
|
||||||
|
|
||||||
### Example json
|
### Example json
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
|
@ -56,6 +56,8 @@ const LegendItem: FC<LegendItemProps> = ({ legend, onChange, isHeatmap, isAnomal
|
||||||
)}
|
)}
|
||||||
<div className="vm-legend-item-info">
|
<div className="vm-legend-item-info">
|
||||||
<span className="vm-legend-item-info__label">
|
<span className="vm-legend-item-info__label">
|
||||||
|
{legend.hasAlias ? legend.label : (
|
||||||
|
<>
|
||||||
{legend.freeFormFields["__name__"]}
|
{legend.freeFormFields["__name__"]}
|
||||||
{!!freeFormFields.length && <>{</>}
|
{!!freeFormFields.length && <>{</>}
|
||||||
{freeFormFields.map((f, i) => (
|
{freeFormFields.map((f, i) => (
|
||||||
|
@ -69,6 +71,8 @@ const LegendItem: FC<LegendItemProps> = ({ legend, onChange, isHeatmap, isAnomal
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
{!!freeFormFields.length && <>}</>}
|
{!!freeFormFields.length && <>}</>}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{!isHeatmap && showStats && (
|
{!isHeatmap && showStats && (
|
||||||
|
|
|
@ -64,7 +64,7 @@ const useLineTooltip = ({ u, metrics, series, unit, isAnomalyView }: LineTooltip
|
||||||
title: groups.size > 1 && !isAnomalyView ? `Query ${group}` : "",
|
title: groups.size > 1 && !isAnomalyView ? `Query ${group}` : "",
|
||||||
dates: [date ? dayjs(date * 1000).tz().format(DATE_FULL_TIMEZONE_FORMAT) : "-"],
|
dates: [date ? dayjs(date * 1000).tz().format(DATE_FULL_TIMEZONE_FORMAT) : "-"],
|
||||||
value: formatPrettyNumber(value, min, max),
|
value: formatPrettyNumber(value, min, max),
|
||||||
info: getMetricName(metricItem),
|
info: getMetricName(metricItem, seriesItem),
|
||||||
statsFormatted: seriesItem?.statsFormatted,
|
statsFormatted: seriesItem?.statsFormatted,
|
||||||
marker: `${seriesItem?.stroke}`,
|
marker: `${seriesItem?.stroke}`,
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ export interface SeriesItem extends Series {
|
||||||
median: number;
|
median: number;
|
||||||
forecast?: ForecastType | null;
|
forecast?: ForecastType | null;
|
||||||
forecastGroup?: string;
|
forecastGroup?: string;
|
||||||
|
hasAlias?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HideSeriesArgs {
|
export interface HideSeriesArgs {
|
||||||
|
@ -45,6 +46,7 @@ export interface LegendItemType {
|
||||||
freeFormFields: {[key: string]: string};
|
freeFormFields: {[key: string]: string};
|
||||||
statsFormatted: SeriesItemStatsFormatted;
|
statsFormatted: SeriesItemStatsFormatted;
|
||||||
median: number
|
median: number
|
||||||
|
hasAlias: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BarSeriesItem {
|
export interface BarSeriesItem {
|
||||||
|
|
|
@ -2,16 +2,23 @@ import { MetricBase } from "../api/types";
|
||||||
|
|
||||||
export const getNameForMetric = (result: MetricBase, alias?: string, showQueryNum = true): string => {
|
export const getNameForMetric = (result: MetricBase, alias?: string, showQueryNum = true): string => {
|
||||||
const { __name__, ...freeFormFields } = result.metric;
|
const { __name__, ...freeFormFields } = result.metric;
|
||||||
const name = alias || `${showQueryNum ? `[Query ${result.group}] ` : ""}${__name__ || ""}`;
|
const queryPrefix = showQueryNum ? `[Query ${result.group}] ` : "";
|
||||||
if (Object.keys(freeFormFields).length == 0) {
|
|
||||||
if (!name) {
|
if (alias) {
|
||||||
return "value";
|
return alias.replace(/\{\{(\w+)}}/g, (_, key) => result.metric[key] || "");
|
||||||
}
|
}
|
||||||
return name;
|
|
||||||
|
const name = `${queryPrefix}${__name__ || ""}`;
|
||||||
|
|
||||||
|
if (Object.keys(freeFormFields).length === 0) {
|
||||||
|
return name || "value";
|
||||||
}
|
}
|
||||||
return `${name}{${Object.entries(freeFormFields).map(e =>
|
|
||||||
`${e[0]}=${JSON.stringify(e[1])}`
|
const fieldsString = Object.entries(freeFormFields)
|
||||||
).join(", ")}}`;
|
.map(([key, value]) => `${key}=${JSON.stringify(value)}`)
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
return `${name}{${fieldsString}}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const promValueToNumber = (s: string): number => {
|
export const promValueToNumber = (s: string): number => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import uPlot from "uplot";
|
import uPlot from "uplot";
|
||||||
import { MetricResult } from "../../api/types";
|
import { MetricResult } from "../../api/types";
|
||||||
|
import { SeriesItem } from "../../types";
|
||||||
|
|
||||||
export const formatTicks = (u: uPlot, ticks: number[], unit = ""): string[] => {
|
export const formatTicks = (u: uPlot, ticks: number[], unit = ""): string[] => {
|
||||||
const min = ticks[0];
|
const min = ticks[0];
|
||||||
|
@ -53,7 +54,11 @@ export const getDashLine = (group: number): number[] => {
|
||||||
return group <= 1 ? [] : [group*4, group*1.2];
|
return group <= 1 ? [] : [group*4, group*1.2];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMetricName = (metricItem: MetricResult) => {
|
export const getMetricName = (metricItem: MetricResult, seriesItem: SeriesItem) => {
|
||||||
|
if (seriesItem?.hasAlias && seriesItem?.label) {
|
||||||
|
return seriesItem.label;
|
||||||
|
}
|
||||||
|
|
||||||
const metric = metricItem?.metric || {};
|
const metric = metricItem?.metric || {};
|
||||||
const labelNames = Object.keys(metric).filter(x => x != "__name__");
|
const labelNames = Object.keys(metric).filter(x => x != "__name__");
|
||||||
const labels = labelNames.map(key => `${key}=${JSON.stringify(metric[key])}`);
|
const labels = labelNames.map(key => `${key}=${JSON.stringify(metric[key])}`);
|
||||||
|
|
|
@ -42,10 +42,12 @@ export const getSeriesItemContext = (data: MetricResult[], hideSeries: string[],
|
||||||
|
|
||||||
return (d: MetricResult, i: number): SeriesItem => {
|
return (d: MetricResult, i: number): SeriesItem => {
|
||||||
const metricInfo = isAnomalyUI ? isForecast(data[i].metric) : null;
|
const metricInfo = isAnomalyUI ? isForecast(data[i].metric) : null;
|
||||||
const label = isAnomalyUI ? metricInfo?.group || "" : getNameForMetric(d, alias[d.group - 1]);
|
const aliasValue = alias[d.group - 1];
|
||||||
|
const label = isAnomalyUI ? metricInfo?.group || "" : getNameForMetric(d, aliasValue);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label,
|
label,
|
||||||
|
hasAlias: Boolean(aliasValue),
|
||||||
dash: getDashSeries(metricInfo),
|
dash: getDashSeries(metricInfo),
|
||||||
width: getWidthSeries(metricInfo),
|
width: getWidthSeries(metricInfo),
|
||||||
stroke: getStrokeSeries({ metricInfo, label, isAnomalyUI, colorState }),
|
stroke: getStrokeSeries({ metricInfo, label, isAnomalyUI, colorState }),
|
||||||
|
@ -88,6 +90,7 @@ export const getLegendItem = (s: SeriesItem, group: number): LegendItemType => (
|
||||||
freeFormFields: s.freeFormFields,
|
freeFormFields: s.freeFormFields,
|
||||||
statsFormatted: s.statsFormatted,
|
statsFormatted: s.statsFormatted,
|
||||||
median: s.median,
|
median: s.median,
|
||||||
|
hasAlias: s.hasAlias || false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getHideSeries = ({ hideSeries, legend, metaKey, series, isAnomalyView }: HideSeriesArgs): string[] => {
|
export const getHideSeries = ({ hideSeries, legend, metaKey, series, isAnomalyView }: HideSeriesArgs): string[] => {
|
||||||
|
|
|
@ -18,6 +18,9 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta
|
||||||
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add frontend-only pagination for table view.
|
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add frontend-only pagination for table view.
|
||||||
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): improve memory consumption during data processing. This enhancement reduces the overall memory footprint, leading to better performance and stability.
|
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): improve memory consumption during data processing. This enhancement reduces the overall memory footprint, leading to better performance and stability.
|
||||||
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): reduce memory usage across all tabs for improved performance and stability. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7185).
|
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): reduce memory usage across all tabs for improved performance and stability. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7185).
|
||||||
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add support for template alias in predefined panels. This allows creating more readable metric names in the legend using constructions like `{{label_name}}`, where `label_name` is the name of the label. [See this commit](https://github.com/VictoriaMetrics/VictoriaMetrics/commit/116101da78a4dee8bd7c4ba0e66458fd05a10469#diff-95141489b32468cf852d2705d96eaa48c50a8b1cdd0424a29e7ca289912a6dcbR140-R151)
|
||||||
|
|
||||||
|
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix for `showLegend` and `alias` flags in predefined panels. [See this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7565)
|
||||||
|
|
||||||
## [v1.0.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.0.0-victorialogs)
|
## [v1.0.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.0.0-victorialogs)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
|
||||||
|
|
||||||
* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert): revert the default value of `-remoteWrite.maxQueueSize` from `1_000_000` to `100_000`. It was bumped in [v1.104.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.104.0), which increases memory usage and is not needed for most setups. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7471).
|
* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert): revert the default value of `-remoteWrite.maxQueueSize` from `1_000_000` to `100_000`. It was bumped in [v1.104.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.104.0), which increases memory usage and is not needed for most setups. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7471).
|
||||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add `Raw Query` tab for displaying raw data. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7024).
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add `Raw Query` tab for displaying raw data. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7024).
|
||||||
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add support for template alias in predefined panels. This allows creating more readable metric names in the legend using constructions like `{{label_name}}`, where `label_name` is the name of the label. [See this commit](https://github.com/VictoriaMetrics/VictoriaMetrics/commit/116101da78a4dee8bd7c4ba0e66458fd05a10469#diff-95141489b32468cf852d2705d96eaa48c50a8b1cdd0424a29e7ca289912a6dcbR140-R151)
|
||||||
* FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): add `ignore_first_sample_interval` param to [aggregation config](https://docs.victoriametrics.com/stream-aggregation/#stream-aggregation-config). It allows users to control the time interval when aggregation skips sending aggregated samples to avoid unexpected spikes in values. By default, this interval is set to x2 of `staleness_interval`. The new setting is applicable only to `total`, `total_prometheus`, `increase`, `increase_prometheus` and `histogram_bucket` outputs. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7116) for details. Thanks to @iyuroch for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/7313).
|
* FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): add `ignore_first_sample_interval` param to [aggregation config](https://docs.victoriametrics.com/stream-aggregation/#stream-aggregation-config). It allows users to control the time interval when aggregation skips sending aggregated samples to avoid unexpected spikes in values. By default, this interval is set to x2 of `staleness_interval`. The new setting is applicable only to `total`, `total_prometheus`, `increase`, `increase_prometheus` and `histogram_bucket` outputs. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7116) for details. Thanks to @iyuroch for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/7313).
|
||||||
* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add `dump_request_on_errors` bool setting to [auth config](https://docs.victoriametrics.com/vmauth/#auth-config) for debugging HTTP requests that missed routing rules. This should improve debugability of vmauth settings.
|
* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add `dump_request_on_errors` bool setting to [auth config](https://docs.victoriametrics.com/vmauth/#auth-config) for debugging HTTP requests that missed routing rules. This should improve debugability of vmauth settings.
|
||||||
* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add `dryRun` flag to validate configuration. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7505) for details.
|
* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add `dryRun` flag to validate configuration. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7505) for details.
|
||||||
|
@ -32,6 +33,7 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
|
||||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent): fix the `resource_group` filter for Azure service discovery on virtual machine scale sets. Previously, this filter did not apply to virtual machine scale sets, causing all virtual machines to be discovered. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7630).
|
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent): fix the `resource_group` filter for Azure service discovery on virtual machine scale sets. Previously, this filter did not apply to virtual machine scale sets, causing all virtual machines to be discovered. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7630).
|
||||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/single-server-victoriametrics/), `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): properly return result for binary operation `^` aka pow at query requests for `NaN` values. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7359) for details.
|
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/single-server-victoriametrics/), `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): properly return result for binary operation `^` aka pow at query requests for `NaN` values. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7359) for details.
|
||||||
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix rendering of isolated data points on the graph that are not connected to other points.
|
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix rendering of isolated data points on the graph that are not connected to other points.
|
||||||
|
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix for `showLegend` and `alias` flags in predefined panels. [See this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7565)
|
||||||
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert): improve the correctness of alert [state restoration](https://docs.victoriametrics.com/vmalert/#alerts-state-on-restarts). Previously, it could result in false-positive alerts if alert was resolved shortly before vmalert restart.
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert): improve the correctness of alert [state restoration](https://docs.victoriametrics.com/vmalert/#alerts-state-on-restarts). Previously, it could result in false-positive alerts if alert was resolved shortly before vmalert restart.
|
||||||
* BUGFIX: [vmalert-tool](https://docs.victoriametrics.com/vmalert-tool/): exit immediately with error message if no test file is found under specified `-files`.
|
* BUGFIX: [vmalert-tool](https://docs.victoriametrics.com/vmalert-tool/): exit immediately with error message if no test file is found under specified `-files`.
|
||||||
* BUGFIX: `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): Properly handle [multitenant](https://docs.victoriametrics.com/cluster-victoriametrics/#multitenancy-via-labels) query request errors and correctly perform search for available tenants. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7549) for details. This is follow-up after [v1.106.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.106.1) release changes.
|
* BUGFIX: `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): Properly handle [multitenant](https://docs.victoriametrics.com/cluster-victoriametrics/#multitenancy-via-labels) query request errors and correctly perform search for available tenants. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7549) for details. This is follow-up after [v1.106.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.106.1) release changes.
|
||||||
|
|
Loading…
Reference in a new issue