mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-20 15:29:24 +01:00
vmui: add functionality to preserve selected columns (#7037)
### Describe Your Changes 1) Changed table settings from a popup to a modal window to simplify future functionality additions. 2) Added functionality to save selected columns when data is modified or the page is reloaded. See #7016. <details> <summary>Example screenshots</summary> <img alt="demo-1" width="600" src="https://github.com/user-attachments/assets/a5d9a910-363c-4931-8b12-18ea8b3d97d8"/> </details> ### Checklist The following checks are **mandatory**: - [x] My change adheres [VictoriaMetrics contributing guidelines](https://docs.victoriametrics.com/contributing/). --------- Co-authored-by: Roman Khavronenko <roman@victoriametrics.com>
This commit is contained in:
parent
2d26d3e3de
commit
c896bf340d
@ -149,7 +149,7 @@
|
|||||||
max-width: 15px;
|
max-width: 15px;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: $padding-small;
|
left: $padding-small;
|
||||||
height: 40px;
|
height: 36px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: $color-text-secondary;
|
color: $color-text-secondary;
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import React, { FC, useEffect, useRef, useMemo } from "preact/compat";
|
import React, { FC, useEffect, useRef, useMemo } from "preact/compat";
|
||||||
import Button from "../../Main/Button/Button";
|
import Button from "../../Main/Button/Button";
|
||||||
import { SearchIcon, SettingsIcon } from "../../Main/Icons";
|
import { SearchIcon, SettingsIcon } from "../../Main/Icons";
|
||||||
import Popper from "../../Main/Popper/Popper";
|
|
||||||
import "./style.scss";
|
import "./style.scss";
|
||||||
import Checkbox from "../../Main/Checkbox/Checkbox";
|
import Checkbox from "../../Main/Checkbox/Checkbox";
|
||||||
import Tooltip from "../../Main/Tooltip/Tooltip";
|
import Tooltip from "../../Main/Tooltip/Tooltip";
|
||||||
import Switch from "../../Main/Switch/Switch";
|
import Switch from "../../Main/Switch/Switch";
|
||||||
import { arrayEquals } from "../../../utils/array";
|
import { arrayEquals } from "../../../utils/array";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import useDeviceDetect from "../../../hooks/useDeviceDetect";
|
|
||||||
import useBoolean from "../../../hooks/useBoolean";
|
import useBoolean from "../../../hooks/useBoolean";
|
||||||
import TextField from "../../Main/TextField/TextField";
|
import TextField from "../../Main/TextField/TextField";
|
||||||
import { KeyboardEvent, useState } from "react";
|
import { KeyboardEvent, useState } from "react";
|
||||||
|
import Modal from "../../Main/Modal/Modal";
|
||||||
|
import { getFromStorage, removeFromStorage, saveToStorage } from "../../../utils/storage";
|
||||||
|
|
||||||
const title = "Table settings";
|
const title = "Table settings";
|
||||||
|
|
||||||
interface TableSettingsProps {
|
interface TableSettingsProps {
|
||||||
columns: string[];
|
columns: string[];
|
||||||
defaultColumns?: string[];
|
selectedColumns?: string[];
|
||||||
tableCompact: boolean;
|
tableCompact: boolean;
|
||||||
toggleTableCompact: () => void;
|
toggleTableCompact: () => void;
|
||||||
onChangeColumns: (arr: string[]) => void
|
onChangeColumns: (arr: string[]) => void
|
||||||
@ -25,13 +25,11 @@ interface TableSettingsProps {
|
|||||||
|
|
||||||
const TableSettings: FC<TableSettingsProps> = ({
|
const TableSettings: FC<TableSettingsProps> = ({
|
||||||
columns,
|
columns,
|
||||||
defaultColumns = [],
|
selectedColumns = [],
|
||||||
tableCompact,
|
tableCompact,
|
||||||
onChangeColumns,
|
onChangeColumns,
|
||||||
toggleTableCompact
|
toggleTableCompact
|
||||||
}) => {
|
}) => {
|
||||||
const { isMobile } = useDeviceDetect();
|
|
||||||
|
|
||||||
const buttonRef = useRef<HTMLDivElement>(null);
|
const buttonRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -41,31 +39,34 @@ const TableSettings: FC<TableSettingsProps> = ({
|
|||||||
} = useBoolean(false);
|
} = useBoolean(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
value: showSearch,
|
value: saveColumns,
|
||||||
toggle: toggleShowSearch,
|
toggle: toggleSaveColumns,
|
||||||
} = useBoolean(false);
|
} = useBoolean(Boolean(getFromStorage("TABLE_COLUMNS")));
|
||||||
|
|
||||||
const [searchColumn, setSearchColumn] = useState("");
|
const [searchColumn, setSearchColumn] = useState("");
|
||||||
const [indexFocusItem, setIndexFocusItem] = useState(-1);
|
const [indexFocusItem, setIndexFocusItem] = useState(-1);
|
||||||
|
|
||||||
|
const customColumns = useMemo(() => {
|
||||||
|
return selectedColumns.filter(col => !columns.includes(col));
|
||||||
|
}, [columns, selectedColumns]);
|
||||||
|
|
||||||
const filteredColumns = useMemo(() => {
|
const filteredColumns = useMemo(() => {
|
||||||
if (!searchColumn) return columns;
|
const allColumns = customColumns.concat(columns);
|
||||||
return columns.filter(col => col.includes(searchColumn));
|
if (!searchColumn) return allColumns;
|
||||||
}, [columns, searchColumn]);
|
return allColumns.filter(col => col.includes(searchColumn));
|
||||||
|
}, [columns, customColumns, searchColumn]);
|
||||||
|
|
||||||
const isAllChecked = useMemo(() => {
|
const isAllChecked = useMemo(() => {
|
||||||
return filteredColumns.every(col => defaultColumns.includes(col));
|
return filteredColumns.every(col => selectedColumns.includes(col));
|
||||||
}, [defaultColumns, filteredColumns]);
|
}, [selectedColumns, filteredColumns]);
|
||||||
|
|
||||||
const disabledButton = useMemo(() => !columns.length, [columns]);
|
|
||||||
|
|
||||||
const handleChange = (key: string) => {
|
const handleChange = (key: string) => {
|
||||||
onChangeColumns(defaultColumns.includes(key) ? defaultColumns.filter(col => col !== key) : [...defaultColumns, key]);
|
onChangeColumns(selectedColumns.includes(key) ? selectedColumns.filter(col => col !== key) : [...selectedColumns, key]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleAllColumns = () => {
|
const toggleAllColumns = () => {
|
||||||
if (isAllChecked) {
|
if (isAllChecked) {
|
||||||
onChangeColumns(defaultColumns.filter(col => !filteredColumns.includes(col)));
|
onChangeColumns(selectedColumns.filter(col => !filteredColumns.includes(col)));
|
||||||
} else {
|
} else {
|
||||||
onChangeColumns(filteredColumns);
|
onChangeColumns(filteredColumns);
|
||||||
}
|
}
|
||||||
@ -94,10 +95,24 @@ const TableSettings: FC<TableSettingsProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (arrayEquals(columns, defaultColumns)) return;
|
if (arrayEquals(columns, selectedColumns) || saveColumns) return;
|
||||||
onChangeColumns(columns);
|
onChangeColumns(columns);
|
||||||
}, [columns]);
|
}, [columns]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!saveColumns) {
|
||||||
|
removeFromStorage(["TABLE_COLUMNS"]);
|
||||||
|
} else if (selectedColumns.length) {
|
||||||
|
saveToStorage("TABLE_COLUMNS", selectedColumns.join(","));
|
||||||
|
}
|
||||||
|
}, [saveColumns, selectedColumns]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const saveColumns = getFromStorage("TABLE_COLUMNS") as string;
|
||||||
|
if (!saveColumns) return;
|
||||||
|
onChangeColumns(saveColumns.split(","));
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="vm-table-settings">
|
<div className="vm-table-settings">
|
||||||
<Tooltip title={title}>
|
<Tooltip title={title}>
|
||||||
@ -106,48 +121,24 @@ const TableSettings: FC<TableSettingsProps> = ({
|
|||||||
variant="text"
|
variant="text"
|
||||||
startIcon={<SettingsIcon/>}
|
startIcon={<SettingsIcon/>}
|
||||||
onClick={toggleOpenSettings}
|
onClick={toggleOpenSettings}
|
||||||
disabled={disabledButton}
|
|
||||||
ariaLabel={title}
|
ariaLabel={title}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Popper
|
{openSettings && (
|
||||||
open={openSettings}
|
<Modal
|
||||||
onClose={handleClose}
|
|
||||||
placement="bottom-right"
|
|
||||||
buttonRef={buttonRef}
|
|
||||||
title={title}
|
title={title}
|
||||||
|
className="vm-table-settings-modal"
|
||||||
|
onClose={handleClose}
|
||||||
>
|
>
|
||||||
<div
|
<div className="vm-table-settings-modal-section">
|
||||||
className={classNames({
|
<div className="vm-table-settings-modal-section__title">
|
||||||
"vm-table-settings-popper": true,
|
Customize columns
|
||||||
"vm-table-settings-popper_mobile": isMobile
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div className="vm-table-settings-popper-list vm-table-settings-popper-list_first">
|
|
||||||
<Switch
|
|
||||||
label={"Compact view"}
|
|
||||||
value={tableCompact}
|
|
||||||
onChange={toggleTableCompact}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="vm-table-settings-popper-list">
|
<div className="vm-table-settings-modal-columns">
|
||||||
<div>
|
<div className="vm-table-settings-modal-columns__search">
|
||||||
<div className="vm-table-settings-popper-list-header">
|
|
||||||
<h3 className="vm-table-settings-popper-list-header__title">Display columns</h3>
|
|
||||||
<Tooltip title="search column">
|
|
||||||
<Button
|
|
||||||
color="primary"
|
|
||||||
variant="text"
|
|
||||||
onClick={toggleShowSearch}
|
|
||||||
startIcon={<SearchIcon/>}
|
|
||||||
ariaLabel="reset columns"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
{showSearch && (
|
|
||||||
<TextField
|
<TextField
|
||||||
placeholder={"search column"}
|
placeholder={"Search columns"}
|
||||||
startIcon={<SearchIcon/>}
|
startIcon={<SearchIcon/>}
|
||||||
value={searchColumn}
|
value={searchColumn}
|
||||||
onChange={setSearchColumn}
|
onChange={setSearchColumn}
|
||||||
@ -155,13 +146,10 @@ const TableSettings: FC<TableSettingsProps> = ({
|
|||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
type="search"
|
type="search"
|
||||||
/>
|
/>
|
||||||
)}
|
</div>
|
||||||
{!filteredColumns.length && (
|
<div className="vm-table-settings-modal-columns-list">
|
||||||
<p className="vm-table-settings-popper-list__no-found">No columns found</p>
|
|
||||||
)}
|
|
||||||
<div className="vm-table-settings-popper-list-header">
|
|
||||||
{!!filteredColumns.length && (
|
{!!filteredColumns.length && (
|
||||||
<div className="vm-table-settings-popper-list__item vm-table-settings-popper-list__item_check_all">
|
<div className="vm-table-settings-modal-columns-list__item vm-table-settings-modal-columns-list__item_all">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={isAllChecked}
|
checked={isAllChecked}
|
||||||
onChange={toggleAllColumns}
|
onChange={toggleAllColumns}
|
||||||
@ -170,18 +158,24 @@ const TableSettings: FC<TableSettingsProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{!filteredColumns.length && (
|
||||||
|
<div className="vm-table-settings-modal-columns-no-found">
|
||||||
|
<p className="vm-table-settings-modal-columns-no-found__info">
|
||||||
|
No columns found.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="vm-table-settings-popper-list-columns">
|
)}
|
||||||
{filteredColumns.map((col, i) => (
|
{filteredColumns.map((col, i) => (
|
||||||
<div
|
<div
|
||||||
className={classNames({
|
className={classNames({
|
||||||
"vm-table-settings-popper-list__item": true,
|
"vm-table-settings-modal-columns-list__item": true,
|
||||||
"vm-table-settings-popper-list__item_focus": i === indexFocusItem,
|
"vm-table-settings-modal-columns-list__item_focus": i === indexFocusItem,
|
||||||
|
"vm-table-settings-modal-columns-list__item_custom": customColumns.includes(col),
|
||||||
})}
|
})}
|
||||||
key={col}
|
key={col}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={defaultColumns.includes(col)}
|
checked={selectedColumns.includes(col)}
|
||||||
onChange={createHandlerChange(col)}
|
onChange={createHandlerChange(col)}
|
||||||
label={col}
|
label={col}
|
||||||
disabled={tableCompact}
|
disabled={tableCompact}
|
||||||
@ -189,10 +183,34 @@ const TableSettings: FC<TableSettingsProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="vm-table-settings-modal-preserve">
|
||||||
|
<Checkbox
|
||||||
|
checked={saveColumns}
|
||||||
|
onChange={toggleSaveColumns}
|
||||||
|
label={"Preserve column settings"}
|
||||||
|
disabled={tableCompact}
|
||||||
|
color={"primary"}
|
||||||
|
/>
|
||||||
|
<p className="vm-table-settings-modal-preserve__info">
|
||||||
|
This label indicates that when the checkbox is activated,
|
||||||
|
the current column configurations will not be reset.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Popper>
|
<div className="vm-table-settings-modal-section">
|
||||||
|
<div className="vm-table-settings-modal-section__title">
|
||||||
|
Table view
|
||||||
|
</div>
|
||||||
|
<div className="vm-table-settings-modal-columns-list__item">
|
||||||
|
<Switch
|
||||||
|
label={"Compact view"}
|
||||||
|
value={tableCompact}
|
||||||
|
onChange={toggleTableCompact}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,66 +1,98 @@
|
|||||||
@use "src/styles/variables" as *;
|
@use "src/styles/variables" as *;
|
||||||
|
|
||||||
.vm-table-settings-popper {
|
.vm-table-settings {
|
||||||
display: grid;
|
&-modal {
|
||||||
min-width: 250px;
|
.vm-modal-content-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&_mobile &-list {
|
&-section {
|
||||||
gap: $padding-global;
|
padding-block: $padding-global;
|
||||||
|
border-top: $border-divider;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
border-top: none;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
&-list {
|
|
||||||
display: grid;
|
|
||||||
gap: 12px;
|
|
||||||
padding: $padding-global;
|
|
||||||
border-bottom: $border-divider;
|
|
||||||
max-width: 250px;
|
|
||||||
|
|
||||||
&_first {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-header {
|
|
||||||
display: grid;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
grid-template-columns: 1fr auto;
|
|
||||||
gap: $padding-small;
|
|
||||||
min-height: 25px;
|
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
padding-inline: $padding-global;
|
||||||
|
font-size: $font-size;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
margin-bottom: $padding-global;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-columns {
|
&-columns {
|
||||||
max-height: 350px;
|
&__search {
|
||||||
overflow: auto;
|
padding-inline: $padding-global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-height: 250px;
|
||||||
|
min-height: 250px;
|
||||||
|
overflow: auto;
|
||||||
|
margin-bottom: $padding-global;
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
padding: calc($padding-global/2) $padding-global;
|
width: 100%;
|
||||||
font-size: $font-size;
|
font-size: $font-size;
|
||||||
|
border-radius: $border-radius-small;
|
||||||
|
|
||||||
|
&>div {
|
||||||
|
padding: $padding-small $padding-global;
|
||||||
|
}
|
||||||
|
|
||||||
|
&_all {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&_focus {
|
&_focus {
|
||||||
background-color: $color-hover-black;
|
background-color: $color-hover-black;
|
||||||
}
|
}
|
||||||
|
|
||||||
&_check_all {
|
&_custom {
|
||||||
padding: calc($padding-global/2) $padding-global;
|
.vm-checkbox__label:after {
|
||||||
margin: 0 (-$padding-global);
|
width: 100%;
|
||||||
|
content: "(custom column, will be removed if unchecked)";
|
||||||
|
padding: 0 $padding-small;
|
||||||
|
text-align: right;
|
||||||
|
font-style: italic;
|
||||||
|
color: $color-text-secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__no-found {
|
&-no-found {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 250px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: $padding-global;
|
||||||
|
|
||||||
|
&__info {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: $color-text-secondary;
|
color: $color-text-secondary;
|
||||||
margin-bottom: $padding-small;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-preserve {
|
||||||
|
padding: $padding-global;
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
padding-top: $padding-small;
|
||||||
|
font-size: $font-size-small;
|
||||||
|
color: $color-text-secondary;
|
||||||
|
line-height: 130%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ const TableTab: FC<Props> = ({ liveData, controlsRef }) => {
|
|||||||
const controls = (
|
const controls = (
|
||||||
<TableSettings
|
<TableSettings
|
||||||
columns={columns}
|
columns={columns}
|
||||||
defaultColumns={displayColumns}
|
selectedColumns={displayColumns}
|
||||||
onChangeColumns={setDisplayColumns}
|
onChangeColumns={setDisplayColumns}
|
||||||
tableCompact={tableCompact}
|
tableCompact={tableCompact}
|
||||||
toggleTableCompact={toggleTableCompact}
|
toggleTableCompact={toggleTableCompact}
|
||||||
|
@ -96,7 +96,7 @@ const ExploreLogsBody: FC<ExploreLogBodyProps> = ({ data }) => {
|
|||||||
<div className="vm-explore-logs-body-header__settings">
|
<div className="vm-explore-logs-body-header__settings">
|
||||||
<TableSettings
|
<TableSettings
|
||||||
columns={columns}
|
columns={columns}
|
||||||
defaultColumns={displayColumns}
|
selectedColumns={displayColumns}
|
||||||
onChangeColumns={setDisplayColumns}
|
onChangeColumns={setDisplayColumns}
|
||||||
tableCompact={tableCompact}
|
tableCompact={tableCompact}
|
||||||
toggleTableCompact={toggleTableCompact}
|
toggleTableCompact={toggleTableCompact}
|
||||||
|
@ -147,7 +147,7 @@ const QueryAnalyzerView: FC<Props> = ({ data, period }) => {
|
|||||||
{displayType === "table" && (
|
{displayType === "table" && (
|
||||||
<TableSettings
|
<TableSettings
|
||||||
columns={columns}
|
columns={columns}
|
||||||
defaultColumns={displayColumns}
|
selectedColumns={displayColumns}
|
||||||
onChangeColumns={setDisplayColumns}
|
onChangeColumns={setDisplayColumns}
|
||||||
tableCompact={tableCompact}
|
tableCompact={tableCompact}
|
||||||
toggleTableCompact={toggleTableCompact}
|
toggleTableCompact={toggleTableCompact}
|
||||||
|
@ -3,6 +3,7 @@ export type StorageKeys = "AUTOCOMPLETE"
|
|||||||
| "QUERY_TRACING"
|
| "QUERY_TRACING"
|
||||||
| "SERIES_LIMITS"
|
| "SERIES_LIMITS"
|
||||||
| "TABLE_COMPACT"
|
| "TABLE_COMPACT"
|
||||||
|
| "TABLE_COLUMNS"
|
||||||
| "TIMEZONE"
|
| "TIMEZONE"
|
||||||
| "DISABLED_DEFAULT_TIMEZONE"
|
| "DISABLED_DEFAULT_TIMEZONE"
|
||||||
| "THEME"
|
| "THEME"
|
||||||
|
@ -15,6 +15,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta
|
|||||||
|
|
||||||
## tip
|
## tip
|
||||||
|
|
||||||
|
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): keep selected columns in table view on page reloads. Before, selected columns were reset on each update. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7016).
|
||||||
|
|
||||||
## [v0.30.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.30.1-victorialogs)
|
## [v0.30.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.30.1-victorialogs)
|
||||||
|
|
||||||
Released at 2024-09-27
|
Released at 2024-09-27
|
||||||
|
@ -26,6 +26,7 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
|
|||||||
* FEATURE: [vmgateway](https://docs.victoriametrics.com/vmgateway/): support parsing `vm_access` claims in string format. This is useful for cases when identity provider does not support mapping claims to JSON format.
|
* FEATURE: [vmgateway](https://docs.victoriametrics.com/vmgateway/): support parsing `vm_access` claims in string format. This is useful for cases when identity provider does not support mapping claims to JSON format.
|
||||||
* FEATURE: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): add new metrics for data ingestion: `vm_rows_received_by_storage_total`, `vm_rows_ignored_total{reason="nan_value"}`, `vm_rows_ignored_total{reason="invalid_raw_metric_name"}`, `vm_rows_ignored_total{reason="hourly_limit_exceeded"}`, `vm_rows_ignored_total{reason="daily_limit_exceeded"}`. See this [PR](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/6663) for details.
|
* FEATURE: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): add new metrics for data ingestion: `vm_rows_received_by_storage_total`, `vm_rows_ignored_total{reason="nan_value"}`, `vm_rows_ignored_total{reason="invalid_raw_metric_name"}`, `vm_rows_ignored_total{reason="hourly_limit_exceeded"}`, `vm_rows_ignored_total{reason="daily_limit_exceeded"}`. See this [PR](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/6663) for details.
|
||||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): change request method for `/query_range` and `/query` calls from `GET` to `POST`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6288).
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): change request method for `/query_range` and `/query` calls from `GET` to `POST`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6288).
|
||||||
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): keep selected columns in table view on page reloads. Before, selected columns were reset on each update. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7016).
|
||||||
* FEATURE: [dashboards](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards) for VM single-node, cluster, vmalert, vmagent, VictoriaLogs: add `Go scheduling latency` panel to show the 99th quantile of Go goroutines scheduling. This panel should help identifying insufficient CPU resources for the service. It is especially useful if CPU gets throttled, which now should be visible on this panel.
|
* FEATURE: [dashboards](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards) for VM single-node, cluster, vmalert, vmagent, VictoriaLogs: add `Go scheduling latency` panel to show the 99th quantile of Go goroutines scheduling. This panel should help identifying insufficient CPU resources for the service. It is especially useful if CPU gets throttled, which now should be visible on this panel.
|
||||||
* FEATURE: [alerts](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/alerts-health.yml): add alerting rule to track the Go scheduling latency for goroutines. It should notify users if VM component doesn't have enough CPU to run or gets throttled.
|
* FEATURE: [alerts](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/alerts-health.yml): add alerting rule to track the Go scheduling latency for goroutines. It should notify users if VM component doesn't have enough CPU to run or gets throttled.
|
||||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent/) and [Single-node VictoriaMetrics](https://docs.victoriametrics.com/): hide jobs that contain only healthy targets when `show_only_unhealthy` filter is enabled. Before, jobs without unhealthy targets were still displayed on the page. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3536).
|
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent/) and [Single-node VictoriaMetrics](https://docs.victoriametrics.com/): hide jobs that contain only healthy targets when `show_only_unhealthy` filter is enabled. Before, jobs without unhealthy targets were still displayed on the page. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3536).
|
||||||
|
Loading…
Reference in New Issue
Block a user