mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-01 14:47:38 +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"`
|
||||
Expr []string `json:"expr"`
|
||||
Alias []string `json:"alias,omitempty"`
|
||||
ShowLegend bool `json:"showLegend,omitempty"`
|
||||
ShowLegend *bool `json:"showLegend"`
|
||||
Width int `json:"width,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,17 @@ func collectDashboardsSettings(path string) ([]byte, error) {
|
|||
if err != nil {
|
||||
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 {
|
||||
dss = append(dss, ds)
|
||||
}
|
||||
|
|
|
@ -127,15 +127,27 @@ DashboardRow:
|
|||
<br/>
|
||||
PanelSettings:
|
||||
|
||||
| Name | Type | Description |
|
||||
|:------------|:----------:|--------------------------------------------------------------------------------------:|
|
||||
| expr* | `string[]` | Data source queries |
|
||||
| alias | `string[]` | Expression alias. Matched by index in array |
|
||||
| title | `string` | Panel title |
|
||||
| description | `string` | Additional information about the panel |
|
||||
| unit | `string` | Y-axis unit |
|
||||
| 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). |
|
||||
| Name | Type | Description |
|
||||
|:------------|:----------:|---------------------------------------------------------------------------------------------------------------:|
|
||||
| expr* | `string[]` | Data source queries |
|
||||
| alias | `string[]` | An array of aliases for each expression in `expr`. See [Template Support in alias](#template-support-in-alias) |
|
||||
| title | `string` | Panel title |
|
||||
| description | `string` | Additional information about the panel |
|
||||
| unit | `string` | Y-axis unit |
|
||||
| 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). |
|
||||
|
||||
### 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
|
||||
|
||||
|
|
|
@ -56,19 +56,23 @@ const LegendItem: FC<LegendItemProps> = ({ legend, onChange, isHeatmap, isAnomal
|
|||
)}
|
||||
<div className="vm-legend-item-info">
|
||||
<span className="vm-legend-item-info__label">
|
||||
{legend.freeFormFields["__name__"]}
|
||||
{!!freeFormFields.length && <>{</>}
|
||||
{freeFormFields.map((f, i) => (
|
||||
<span
|
||||
className="vm-legend-item-info__free-fields"
|
||||
key={f.key}
|
||||
onClick={createHandlerCopy(f.freeField)}
|
||||
title="copy to clipboard"
|
||||
>
|
||||
{f.freeField}{i + 1 < freeFormFields.length && ","}
|
||||
</span>
|
||||
))}
|
||||
{!!freeFormFields.length && <>}</>}
|
||||
{legend.hasAlias ? legend.label : (
|
||||
<>
|
||||
{legend.freeFormFields["__name__"]}
|
||||
{!!freeFormFields.length && <>{</>}
|
||||
{freeFormFields.map((f, i) => (
|
||||
<span
|
||||
className="vm-legend-item-info__free-fields"
|
||||
key={f.key}
|
||||
onClick={createHandlerCopy(f.freeField)}
|
||||
title="copy to clipboard"
|
||||
>
|
||||
{f.freeField}{i + 1 < freeFormFields.length && ","}
|
||||
</span>
|
||||
))}
|
||||
{!!freeFormFields.length && <>}</>}
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
{!isHeatmap && showStats && (
|
||||
|
|
|
@ -64,7 +64,7 @@ const useLineTooltip = ({ u, metrics, series, unit, isAnomalyView }: LineTooltip
|
|||
title: groups.size > 1 && !isAnomalyView ? `Query ${group}` : "",
|
||||
dates: [date ? dayjs(date * 1000).tz().format(DATE_FULL_TIMEZONE_FORMAT) : "-"],
|
||||
value: formatPrettyNumber(value, min, max),
|
||||
info: getMetricName(metricItem),
|
||||
info: getMetricName(metricItem, seriesItem),
|
||||
statsFormatted: seriesItem?.statsFormatted,
|
||||
marker: `${seriesItem?.stroke}`,
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ export interface SeriesItem extends Series {
|
|||
median: number;
|
||||
forecast?: ForecastType | null;
|
||||
forecastGroup?: string;
|
||||
hasAlias?: boolean;
|
||||
}
|
||||
|
||||
export interface HideSeriesArgs {
|
||||
|
@ -45,6 +46,7 @@ export interface LegendItemType {
|
|||
freeFormFields: {[key: string]: string};
|
||||
statsFormatted: SeriesItemStatsFormatted;
|
||||
median: number
|
||||
hasAlias: boolean;
|
||||
}
|
||||
|
||||
export interface BarSeriesItem {
|
||||
|
|
|
@ -2,16 +2,23 @@ import { MetricBase } from "../api/types";
|
|||
|
||||
export const getNameForMetric = (result: MetricBase, alias?: string, showQueryNum = true): string => {
|
||||
const { __name__, ...freeFormFields } = result.metric;
|
||||
const name = alias || `${showQueryNum ? `[Query ${result.group}] ` : ""}${__name__ || ""}`;
|
||||
if (Object.keys(freeFormFields).length == 0) {
|
||||
if (!name) {
|
||||
return "value";
|
||||
}
|
||||
return name;
|
||||
const queryPrefix = showQueryNum ? `[Query ${result.group}] ` : "";
|
||||
|
||||
if (alias) {
|
||||
return alias.replace(/\{\{(\w+)}}/g, (_, key) => result.metric[key] || "");
|
||||
}
|
||||
return `${name}{${Object.entries(freeFormFields).map(e =>
|
||||
`${e[0]}=${JSON.stringify(e[1])}`
|
||||
).join(", ")}}`;
|
||||
|
||||
const name = `${queryPrefix}${__name__ || ""}`;
|
||||
|
||||
if (Object.keys(freeFormFields).length === 0) {
|
||||
return name || "value";
|
||||
}
|
||||
|
||||
const fieldsString = Object.entries(freeFormFields)
|
||||
.map(([key, value]) => `${key}=${JSON.stringify(value)}`)
|
||||
.join(", ");
|
||||
|
||||
return `${name}{${fieldsString}}`;
|
||||
};
|
||||
|
||||
export const promValueToNumber = (s: string): number => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import uPlot from "uplot";
|
||||
import { MetricResult } from "../../api/types";
|
||||
import { SeriesItem } from "../../types";
|
||||
|
||||
export const formatTicks = (u: uPlot, ticks: number[], unit = ""): string[] => {
|
||||
const min = ticks[0];
|
||||
|
@ -53,7 +54,11 @@ export const getDashLine = (group: number): number[] => {
|
|||
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 labelNames = Object.keys(metric).filter(x => x != "__name__");
|
||||
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 => {
|
||||
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 {
|
||||
label,
|
||||
hasAlias: Boolean(aliasValue),
|
||||
dash: getDashSeries(metricInfo),
|
||||
width: getWidthSeries(metricInfo),
|
||||
stroke: getStrokeSeries({ metricInfo, label, isAnomalyUI, colorState }),
|
||||
|
@ -88,6 +90,7 @@ export const getLegendItem = (s: SeriesItem, group: number): LegendItemType => (
|
|||
freeFormFields: s.freeFormFields,
|
||||
statsFormatted: s.statsFormatted,
|
||||
median: s.median,
|
||||
hasAlias: s.hasAlias || false,
|
||||
});
|
||||
|
||||
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): 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: [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)
|
||||
|
||||
|
|
|
@ -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: [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: [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.
|
||||
|
@ -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: [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 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-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.
|
||||
|
|
Loading…
Reference in a new issue