mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-05-22 03:06:36 +03:00
Compare commits
10 Commits
vmui-null-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
734efe8f7e | ||
|
|
37a662b7e7 | ||
|
|
e303965b6c | ||
|
|
69869d7d08 | ||
|
|
3160979048 | ||
|
|
a45ec9a6a0 | ||
|
|
af595acc73 | ||
|
|
b1dea965aa | ||
|
|
df9750a968 | ||
|
|
bc9320aaf3 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -63,11 +63,11 @@ jobs:
|
||||
arch: amd64
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Go
|
||||
id: go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
cache-dependency-path: |
|
||||
go.sum
|
||||
|
||||
2
.github/workflows/changelog-linter.yml
vendored
2
.github/workflows/changelog-linter.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
tip-lint:
|
||||
runs-on: 'ubuntu-latest'
|
||||
steps:
|
||||
- uses: 'actions/checkout@v6'
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# needed for proper diff
|
||||
fetch-depth: 0
|
||||
|
||||
2
.github/workflows/check-commit-signed.yml
vendored
2
.github/workflows/check-commit-signed.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0 # we need full history for commit verification
|
||||
|
||||
|
||||
6
.github/workflows/check-licenses.yml
vendored
6
.github/workflows/check-licenses.yml
vendored
@@ -15,11 +15,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Go
|
||||
id: go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
cache: false
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
- run: go version
|
||||
|
||||
- name: Cache Go artifacts
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
|
||||
12
.github/workflows/codeql-analysis-go.yml
vendored
12
.github/workflows/codeql-analysis-go.yml
vendored
@@ -29,18 +29,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Go
|
||||
id: go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
cache: false
|
||||
go-version-file: 'go.mod'
|
||||
- run: go version
|
||||
|
||||
- name: Cache Go artifacts
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
@@ -50,14 +50,14 @@ jobs:
|
||||
restore-keys: go-artifacts-${{ runner.os }}-codeql-analyze-${{ steps.go.outputs.go-version }}-
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4.35.2
|
||||
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||
with:
|
||||
languages: go
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v4.35.2
|
||||
uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4.35.2
|
||||
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||
with:
|
||||
category: 'language:go'
|
||||
|
||||
6
.github/workflows/docs.yaml
vendored
6
.github/workflows/docs.yaml
vendored
@@ -16,19 +16,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
path: __vm
|
||||
|
||||
- name: Checkout private code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
repository: VictoriaMetrics/vmdocs
|
||||
token: ${{ secrets.VM_BOT_GH_TOKEN }}
|
||||
path: __vm-docs
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v7
|
||||
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0
|
||||
id: import-gpg
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.VM_BOT_GPG_PRIVATE_KEY }}
|
||||
|
||||
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@@ -32,11 +32,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Go
|
||||
id: go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
cache-dependency-path: |
|
||||
go.sum
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
- run: go version
|
||||
|
||||
- name: Cache golangci-lint
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/golangci-lint
|
||||
@@ -72,11 +72,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Go
|
||||
id: go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
cache-dependency-path: |
|
||||
go.sum
|
||||
@@ -94,11 +94,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Go
|
||||
id: go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
cache-dependency-path: |
|
||||
go.sum
|
||||
|
||||
6
.github/workflows/vmui.yml
vendored
6
.github/workflows/vmui.yml
vendored
@@ -32,11 +32,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Code checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Cache node_modules
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: app/vmui/packages/vmui/node_modules
|
||||
key: vmui-deps-${{ runner.os }}-${{ hashFiles('app/vmui/packages/vmui/package-lock.json', 'app/vmui/Dockerfile-build') }}
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
VMUI_SKIP_INSTALL: true
|
||||
|
||||
- name: Annotate Code Linting Results
|
||||
uses: ataylorme/eslint-annotate-action@v3
|
||||
uses: ataylorme/eslint-annotate-action@d57a1193d4c59cbfbf3f86c271f42612f9dbd9e9 # 3.0.0
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
report-json: app/vmui/packages/vmui/vmui-lint-report.json
|
||||
|
||||
9
Makefile
9
Makefile
@@ -535,6 +535,15 @@ remove-golangci-lint:
|
||||
govulncheck: install-govulncheck
|
||||
govulncheck ./...
|
||||
|
||||
govulncheck-docker:
|
||||
docker run -w $(PWD) -v $(PWD):$(PWD) \
|
||||
-v govulncheck-gomod-cache:/root/go/pkg/mod \
|
||||
-v govulncheck-gobuild-cache:/root/.cache/go-build \
|
||||
-v govulncheck-go-bin:/root/go/bin \
|
||||
--env="GOCACHE=/root/.cache/go-build" \
|
||||
--env="GOMODCACHE=/root/go/pkg/mod" \
|
||||
"$(GO_BUILDER_IMAGE)" /bin/sh -c "which govulncheck || go install golang.org/x/vuln/cmd/govulncheck@latest && govulncheck ./..."
|
||||
|
||||
install-govulncheck:
|
||||
which govulncheck || go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ export interface MetricBase {
|
||||
metric: {
|
||||
[key: string]: string;
|
||||
};
|
||||
nullTimestamps?: number[];
|
||||
}
|
||||
|
||||
export interface MetricResult extends MetricBase {
|
||||
|
||||
@@ -16,7 +16,6 @@ export interface ChartTooltipProps {
|
||||
point: { top: number, left: number };
|
||||
unit?: string;
|
||||
statsFormatted?: SeriesItemStatsFormatted;
|
||||
description?: ReactNode;
|
||||
isSticky?: boolean;
|
||||
info?: ReactNode;
|
||||
marker?: string;
|
||||
@@ -35,7 +34,6 @@ const ChartTooltip: FC<ChartTooltipProps> = ({
|
||||
unit = "",
|
||||
info,
|
||||
statsFormatted,
|
||||
description,
|
||||
isSticky,
|
||||
marker,
|
||||
duplicateCount = 0,
|
||||
@@ -175,7 +173,6 @@ const ChartTooltip: FC<ChartTooltipProps> = ({
|
||||
))}
|
||||
</table>
|
||||
)}
|
||||
{description && <p className="vm-chart-tooltip__description">{description}</p>}
|
||||
{info && <p className="vm-chart-tooltip__info">{info}</p>}
|
||||
</div>
|
||||
), u.root);
|
||||
|
||||
@@ -143,10 +143,4 @@ $chart-tooltip-y: -1 * ($padding-global + $chart-tooltip-half-icon);
|
||||
word-break: break-all;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
&__description {
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ChartTooltipProps } from "../../components/Chart/ChartTooltip/ChartTool
|
||||
import { SeriesItem } from "../../types";
|
||||
import dayjs from "dayjs";
|
||||
import { DATE_FULL_TIMEZONE_FORMAT } from "../../constants/date";
|
||||
import { formatPrettyNumber, getMetricName } from "../../utils/uplot";
|
||||
import { getMetricName } from "../../utils/uplot";
|
||||
import { MetricResult } from "../../api/types";
|
||||
import useEventListener from "../useEventListener";
|
||||
|
||||
@@ -15,65 +15,19 @@ interface LineTooltipHook {
|
||||
unit?: string;
|
||||
}
|
||||
|
||||
// Pixel proximity for detecting hover over null-timestamp X markers drawn at chart bottom.
|
||||
const NULL_HOVER_PROX = 8;
|
||||
// Half the visual marker height in CSS px (BASE_POINT_SIZE * 1.4 / 2 from scatter.ts).
|
||||
// scatter.ts lifts the marker center by this amount above yMin so the icon sits inside
|
||||
// the plot area; the hover y-anchor must match that offset.
|
||||
const NULL_MARKER_HALF_CSS = 2.8;
|
||||
|
||||
interface NullHover {
|
||||
seriesIdx: number;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
const findNullHover = (u: uPlot): NullHover | null => {
|
||||
const cursorLeft = u.cursor.left ?? -1;
|
||||
const cursorTop = u.cursor.top ?? -1;
|
||||
if (cursorLeft < 0 || cursorTop < 0) return null;
|
||||
|
||||
const scaleY = u.scales["1"];
|
||||
if (!scaleY || scaleY.min == null) return null;
|
||||
const yPos = u.valToPos(scaleY.min, "1") - NULL_MARKER_HALF_CSS;
|
||||
if (Math.abs(cursorTop - yPos) > NULL_HOVER_PROX) return null;
|
||||
|
||||
let best: { seriesIdx: number; timestamp: number; dist: number } | null = null;
|
||||
for (let s = 1; s < u.series.length; s++) {
|
||||
const seriesItem = u.series[s] as SeriesItem;
|
||||
if (!seriesItem.show) continue;
|
||||
const nullTs = seriesItem.nullTimestamps;
|
||||
if (!nullTs || !nullTs.length) continue;
|
||||
|
||||
for (let i = 0; i < nullTs.length; i++) {
|
||||
const t = nullTs[i];
|
||||
const xPos = u.valToPos(t, "x");
|
||||
const dist = Math.abs(cursorLeft - xPos);
|
||||
if (dist < NULL_HOVER_PROX && (best === null || dist < best.dist)) {
|
||||
best = { seriesIdx: s, timestamp: t, dist };
|
||||
}
|
||||
}
|
||||
}
|
||||
return best ? { seriesIdx: best.seriesIdx, timestamp: best.timestamp } : null;
|
||||
};
|
||||
|
||||
const NULL_DESCRIPTION = "\"null\" can be a staleness marker or an actual NaN/null value produced by exporter.";
|
||||
|
||||
const useLineTooltip = ({ u, metrics, series, unit }: LineTooltipHook) => {
|
||||
const [showTooltip, setShowTooltip] = useState(false);
|
||||
const [tooltipIdx, setTooltipIdx] = useState({ seriesIdx: -1, dataIdx: -1 });
|
||||
const [nullTooltip, setNullTooltip] = useState<NullHover | null>(null);
|
||||
const [stickyTooltips, setStickyToolTips] = useState<ChartTooltipProps[]>([]);
|
||||
|
||||
const resetTooltips = () => {
|
||||
setStickyToolTips([]);
|
||||
setTooltipIdx({ seriesIdx: -1, dataIdx: -1 });
|
||||
setNullTooltip(null);
|
||||
};
|
||||
|
||||
const setCursor = (u: uPlot) => {
|
||||
const dataIdx = u.cursor.idx ?? -1;
|
||||
setTooltipIdx(prev => ({ ...prev, dataIdx }));
|
||||
setNullTooltip(findNullHover(u));
|
||||
};
|
||||
|
||||
const seriesFocus = (u: uPlot, sidx: (number | null)) => {
|
||||
@@ -81,36 +35,7 @@ const useLineTooltip = ({ u, metrics, series, unit }: LineTooltipHook) => {
|
||||
setTooltipIdx(prev => ({ ...prev, seriesIdx }));
|
||||
};
|
||||
|
||||
const getNullTooltipProps = (hit: NullHover): ChartTooltipProps => {
|
||||
const { seriesIdx, timestamp } = hit;
|
||||
const metricItem = metrics[seriesIdx - 1];
|
||||
const seriesItem = series[seriesIdx] as SeriesItem;
|
||||
|
||||
const groups = new Set(metrics.map(m => m.group));
|
||||
const group = metricItem?.group || 0;
|
||||
|
||||
const yMin = u?.scales?.[1]?.min ?? 0;
|
||||
const point = {
|
||||
top: u ? u.valToPos(yMin, seriesItem?.scale || "1") - NULL_MARKER_HALF_CSS : 0,
|
||||
left: u ? u.valToPos(timestamp, "x") : 0,
|
||||
};
|
||||
|
||||
return {
|
||||
u,
|
||||
id: `null_${seriesIdx}_${timestamp}`,
|
||||
title: groups.size > 1 ? `Query ${group}` : "",
|
||||
dates: [dayjs(timestamp * 1000).tz().format(DATE_FULL_TIMEZONE_FORMAT)],
|
||||
value: "null",
|
||||
info: getMetricName(metricItem, seriesItem),
|
||||
description: NULL_DESCRIPTION,
|
||||
marker: `${seriesItem?.stroke}`,
|
||||
point,
|
||||
};
|
||||
};
|
||||
|
||||
const getTooltipProps = useCallback((): ChartTooltipProps => {
|
||||
if (nullTooltip) return getNullTooltipProps(nullTooltip);
|
||||
|
||||
const { seriesIdx, dataIdx } = tooltipIdx;
|
||||
const metricItem = metrics[seriesIdx - 1];
|
||||
const seriesItem = series[seriesIdx] as SeriesItem;
|
||||
@@ -119,8 +44,6 @@ const useLineTooltip = ({ u, metrics, series, unit }: LineTooltipHook) => {
|
||||
const group = metricItem?.group || 0;
|
||||
|
||||
const value = u?.data?.[seriesIdx]?.[dataIdx] || 0;
|
||||
const min = u?.scales?.[1]?.min || 0;
|
||||
const max = u?.scales?.[1]?.max || 1;
|
||||
const date = u?.data?.[0]?.[dataIdx] || 0;
|
||||
|
||||
let duplicateCount = 1;
|
||||
@@ -155,13 +78,13 @@ const useLineTooltip = ({ u, metrics, series, unit }: LineTooltipHook) => {
|
||||
id: `${seriesIdx}_${dataIdx}`,
|
||||
title: groups.size > 1 ? `Query ${group}` : "",
|
||||
dates: [date ? dayjs(date * 1000).tz().format(DATE_FULL_TIMEZONE_FORMAT) : "-"],
|
||||
value: formatPrettyNumber(value, min, max),
|
||||
value: value.toLocaleString("en-US", { maximumFractionDigits: 20 }),
|
||||
info: getMetricName(metricItem, seriesItem),
|
||||
statsFormatted: seriesItem?.statsFormatted,
|
||||
marker: `${seriesItem?.stroke}`,
|
||||
duplicateCount,
|
||||
};
|
||||
}, [u, tooltipIdx, metrics, series, unit, nullTooltip]);
|
||||
}, [u, tooltipIdx, metrics, series, unit]);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (!showTooltip) return;
|
||||
@@ -176,9 +99,8 @@ const useLineTooltip = ({ u, metrics, series, unit }: LineTooltipHook) => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const normalHit = tooltipIdx.dataIdx !== -1 && tooltipIdx.seriesIdx !== -1;
|
||||
setShowTooltip(normalHit || nullTooltip !== null);
|
||||
}, [tooltipIdx, nullTooltip]);
|
||||
setShowTooltip(tooltipIdx.dataIdx !== -1 && tooltipIdx.seriesIdx !== -1);
|
||||
}, [tooltipIdx]);
|
||||
|
||||
useEventListener("click", handleClick);
|
||||
|
||||
|
||||
@@ -149,21 +149,15 @@ export const useFetchExport = ({ hideQuery, showAllSeries }: FetchQueryParams):
|
||||
const pointsToTake = shouldDownsample ? maxPointsPerSeries : totalPoints;
|
||||
const step = shouldDownsample ? totalPoints / maxPointsPerSeries : 1;
|
||||
|
||||
const values: [number, number][] = new Array(pointsToTake);
|
||||
const nullTimestamps: number[] = [];
|
||||
for (let i = 0; i < pointsToTake; i++) {
|
||||
const values: [number, number][] = Array.from({ length: pointsToTake }, (_, i) => {
|
||||
const idx = shouldDownsample ? Math.floor(i * step) : i;
|
||||
const ts = rawTimestamps[idx] / 1000;
|
||||
const raw = rawValues[idx];
|
||||
if (raw === null) nullTimestamps.push(ts);
|
||||
values[i] = [ts, raw as number];
|
||||
}
|
||||
return [rawTimestamps[idx] / 1000, rawValues[idx]];
|
||||
});
|
||||
|
||||
tempData.push({
|
||||
group: counter,
|
||||
metric: jsonLine.metric,
|
||||
values,
|
||||
nullTimestamps,
|
||||
} as MetricBase);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ export interface SeriesItem extends Series {
|
||||
statsFormatted: SeriesItemStatsFormatted;
|
||||
median: number;
|
||||
hasAlias?: boolean;
|
||||
nullTimestamps?: number[];
|
||||
}
|
||||
|
||||
export interface HideSeriesArgs {
|
||||
|
||||
@@ -103,28 +103,6 @@ export const drawPoints = (u: uPlot, seriesIdx: number) => {
|
||||
u.ctx.lineWidth = 1.4 * uPlot.pxRatio;
|
||||
u.ctx.strokeStyle = u.ctx.fillStyle;
|
||||
u.ctx.stroke(squaresPath);
|
||||
|
||||
const nullTs = (series as unknown as { nullTimestamps?: number[] }).nullTimestamps;
|
||||
if (nullTs && nullTs.length) {
|
||||
const xSize = BASE_POINT_SIZE * 1.4 * uPlot.pxRatio;
|
||||
const xHalf = xSize / 2;
|
||||
// Lift the marker by half its size so the entire icon sits inside the plot area
|
||||
// (yMin maps to the plot's bottom edge, so centering on it would clip the lower half).
|
||||
const cy = valToPosY(yMin, scaleY, yDim, yOff) - xHalf;
|
||||
const xPath = new Path2D();
|
||||
for (let i = 0; i < nullTs.length; i++) {
|
||||
const t = nullTs[i];
|
||||
if (t < xMin || t > xMax) continue;
|
||||
const cx = valToPosX(t, scaleX, xDim, xOff);
|
||||
xPath.moveTo(cx - xHalf, cy - xHalf);
|
||||
xPath.lineTo(cx + xHalf, cy + xHalf);
|
||||
xPath.moveTo(cx + xHalf, cy - xHalf);
|
||||
xPath.lineTo(cx - xHalf, cy + xHalf);
|
||||
}
|
||||
u.ctx.lineWidth = 1.6 * uPlot.pxRatio;
|
||||
u.ctx.strokeStyle = u.ctx.fillStyle;
|
||||
u.ctx.stroke(xPath);
|
||||
}
|
||||
};
|
||||
|
||||
uPlot.orient(u, seriesIdx, orientCallback);
|
||||
|
||||
@@ -38,7 +38,6 @@ export const getSeriesItemContext = (data: MetricResult[], hideSeries: string[],
|
||||
show: !includesHideSeries(label, hideSeries),
|
||||
scale: "1",
|
||||
paths: isRawQuery ? drawPoints : undefined,
|
||||
nullTimestamps: d.nullTimestamps,
|
||||
...getSeriesStatistics(d),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -191,7 +191,7 @@ func testLegacyDeleteSeries(tc *at.TestCase, opts testLegacyDeleteSeriesOpts) {
|
||||
|
||||
// - start legacy vmsingle
|
||||
// - insert data1
|
||||
// - confirm that metric names and samples are searcheable
|
||||
// - confirm that metric names and samples are searchable
|
||||
// - stop legacy vmsingle
|
||||
const step = 24 * 3600 * 1000 // 24h
|
||||
start1 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC).UnixMilli()
|
||||
@@ -204,12 +204,12 @@ func testLegacyDeleteSeries(tc *at.TestCase, opts testLegacyDeleteSeriesOpts) {
|
||||
opts.stopLegacySUT()
|
||||
|
||||
// - start new vmsingle
|
||||
// - confirm that data1 metric names and samples are searcheable
|
||||
// - confirm that data1 metric names and samples are searchable
|
||||
// - delete data1
|
||||
// - confirm that data1 metric names and samples are not searcheable anymore
|
||||
// - confirm that data1 metric names and samples are not searchable anymore
|
||||
// - insert data2 (same metric names, different dates)
|
||||
// - confirm that metric names become searcheable again
|
||||
// - confirm that data1 samples are not searchable and data2 samples are searcheable
|
||||
// - confirm that metric names become searchable again
|
||||
// - confirm that data1 samples are not searchable and data2 samples are searchable
|
||||
|
||||
newSUT := opts.startNewSUT()
|
||||
assertSearchResults(newSUT, `{__name__=~".*"}`, start1, end1, "1d", want1)
|
||||
@@ -230,7 +230,7 @@ func testLegacyDeleteSeries(tc *at.TestCase, opts testLegacyDeleteSeriesOpts) {
|
||||
|
||||
// - restart new vmsingle
|
||||
// - confirm that metric names still searchable, data1 samples are not
|
||||
// searchable, and data2 samples are searcheable
|
||||
// searchable, and data2 samples are searchable
|
||||
|
||||
opts.stopNewSUT()
|
||||
newSUT = opts.startNewSUT()
|
||||
|
||||
@@ -652,12 +652,11 @@ vmanomaly version: [v1.29.4](https://docs.victoriametrics.com/anomaly-detection/
|
||||
- run 2-100x faster for [online models](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-models) depending on a configuration vs [1.6.1](#v161) timings
|
||||
- show stage-aware progress bar, e.g. "getting data", "fitting model", "inferring on chunk".
|
||||
- IMPROVEMENT: "Advanced Options" design is improved, section is collapsed by default to save vertical space, yet can be encoded as always open in UI state URL.
|
||||
- IMPROVEMENT: dropdowns in UI are now searcheable and constrained in size for better UX, especially when many options are available (e.g. models list, tenants list, etc.).
|
||||
- IMPROVEMENT: dropdowns in UI are now searchable and constrained in size for better UX, especially when many options are available (e.g. models list, tenants list, etc.).
|
||||
- BUGFIX: in generated config ("Show Config" menu)
|
||||
- special YAML values (like `-.inf`, `.inf`, `.nan`) are now properly quoted and formatted to avoid JSON converting issues when copied to Kubernetes CRs, which previously lead to rejection of the manifest before vmanomaly can consume it.
|
||||
- special YAML values (like `-.inf`, `.inf`, `.nan`) are now properly quoted and formatted to avoid JSON converting issues when copied to Kubernetes CRs, which previously led to rejection of the manifest before vmanomaly can consume it.
|
||||
- with Data Source selected as "Logs/Traces" `reader.class` is now correctly set to `vlogs` (previously `vm`) in generated config, when "model only" toggle is turned off.
|
||||
- BUGFIX: now "Hide Common Labels" toggle in "Table View" works correctly and does not show common labels in the legend columns when turned on.
|
||||
- BUGFIX: improved dropdowns for better accessibility to be searcheable and constrained in size.
|
||||
- BUGFIX: "Prettify query" now works correctly for "Metrics" datasources.
|
||||
|
||||
### v1.6.1
|
||||
|
||||
@@ -566,7 +566,7 @@ The following optional command-line flags related to mTLS are supported:
|
||||
- `-cluster.tlsCAFile` can be set at `vminsert`, `vmselect` and `vmstorage` for verifying peer certificates issued with custom [certificate authority](https://en.wikipedia.org/wiki/Certificate_authority). By default, system-wide certificate authority is used for peer certificate verification.
|
||||
- `-cluster.tlsCipherSuites` can be set to the list of supported TLS cipher suites at `vmstorage`. See [the list of supported TLS cipher suites](https://pkg.go.dev/crypto/tls#pkg-constants).
|
||||
|
||||
When `vmselect` runs with `-clusternativeListenAddr` command-line option, then it can be configured with `-clusternative.tls*` options similar to `-cluster.tls*` for accepting `mTLS` connections from top-level `vmselect` nodes in [multi-level cluster setup](#multi-level-cluster-setup).
|
||||
When `vmselect` or `vminsert` runs with `-clusternativeListenAddr` command-line option, then it can be configured with `-clusternative.tls*` options similar to `-cluster.tls*` for accepting `mTLS` connections from top-level `vmselect` or `vminsert` nodes in [multi-level cluster setup](#multi-level-cluster-setup).
|
||||
|
||||
See [these docs](https://gist.github.com/f41gh7/76ed8e5fb1ebb9737fe746bae9175ee6) on how to set up mTLS in VictoriaMetrics cluster.
|
||||
|
||||
@@ -700,6 +700,7 @@ Also in the cluster version the `/prometheus/api/v1` endpoint ingests `jsonl`,
|
||||
|
||||
- `vmstorage` nodes provide the following HTTP endpoints on `8482` port:
|
||||
- `/internal/force_merge` - initiate [forced compactions](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#forced-merge) on the given `vmstorage` node.
|
||||
- `/internal/force_flush` - [flush in-memory buffers](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#forced-flush) for recently ingested samples into searchable parts on the given `vmstorage` node.
|
||||
- `/snapshot/create` - create [instant snapshot](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282),
|
||||
which can be used for backups in background. Snapshots are created in `<storageDataPath>/snapshots` folder, where `<storageDataPath>` is the corresponding
|
||||
command-line flag value.
|
||||
|
||||
@@ -147,7 +147,7 @@ After=network.target
|
||||
Type=simple
|
||||
User=victoriametrics
|
||||
Group=victoriametrics
|
||||
ExecStart=/usr/local/bin/victoria-metrics-prod -storageDataPath=/var/lib/victoria-metrics -retentionPeriod=90d -selfScrapeInterval=10s
|
||||
ExecStart=/usr/local/bin/victoria-metrics-prod -storageDataPath=/var/lib/victoria-metrics -selfScrapeInterval=10s
|
||||
SyslogIdentifier=victoriametrics
|
||||
Restart=always
|
||||
|
||||
@@ -231,7 +231,7 @@ Type=simple
|
||||
User=victoriametrics
|
||||
Group=victoriametrics
|
||||
Restart=always
|
||||
ExecStart=/usr/local/bin/vmstorage-prod -retentionPeriod=90d -storageDataPath=/var/lib/vmstorage
|
||||
ExecStart=/usr/local/bin/vmstorage-prod -storageDataPath=/var/lib/vmstorage
|
||||
|
||||
PrivateTmp=yes
|
||||
NoNewPrivileges=yes
|
||||
@@ -434,6 +434,14 @@ the main monitoring installation.
|
||||
|
||||
See more details in the article [VictoriaMetrics Monitoring](https://victoriametrics.com/blog/victoriametrics-monitoring/).
|
||||
|
||||
### Retention
|
||||
|
||||
VictoriaMetrics Single-node and `vmstorage` in VictoriaMetrics Cluster retain data for 1 month by default.
|
||||
Data older than the retention period will be automatically deleted. To change the retention period, use the `-retentionPeriod` flag (e.g. `-retentionPeriod=90d`).
|
||||
See the [retention](https://docs.victoriametrics.com/victoriametrics/#retention) documentation for more details.
|
||||
|
||||
If free disk space falls below `-storage.minFreeDiskSpaceBytes`, VictoriaMetrics Single-node or `vmstorage` switches to read-only mode and stops accepting new data. To prevent this, ensure proper [capacity planning](#capacity-planning) and set up monitoring and alerting for disk usage.
|
||||
|
||||
### Capacity planning
|
||||
|
||||
See capacity planning sections in [docs](https://docs.victoriametrics.com) for
|
||||
|
||||
@@ -701,18 +701,37 @@ It's better to use the `-retentionPeriod` command-line flag for efficient prunin
|
||||
|
||||
## Forced merge
|
||||
|
||||
VictoriaMetrics performs [data compactions in background](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282)
|
||||
in order to keep good performance characteristics when accepting new data. These compactions (merges) are performed independently on per-month partitions.
|
||||
This means that compactions are stopped for per-month partitions if no new data is ingested into these partitions.
|
||||
Sometimes it is necessary to trigger compactions for old partitions. For instance, in order to free up disk space occupied by [deleted time series](#how-to-delete-time-series).
|
||||
In this case forced compaction may be initiated on the specified per-month partition by sending request to `/internal/force_merge?partition_prefix=YYYY_MM`,
|
||||
where `YYYY_MM` is per-month partition name. For example, `http://victoriametrics:8428/internal/force_merge?partition_prefix=2020_08` would initiate forced
|
||||
merge for August 2020 partition. The call to `/internal/force_merge` returns immediately, while the corresponding forced merge continues running in background.
|
||||
VictoriaMetrics performs [data compaction in background](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282)
|
||||
to keep high performance during ingestion. These compactions (merges) are performed independently on per-month partitions.
|
||||
Partitions that don't receive new data will eventually stop being merged, as they reach an optimal state.
|
||||
Sometimes it is necessary to trigger merges for old partitions. For example, to free up disk space occupied by [deleted time series](https://docs.victoriametrics.com/victoriametrics/#how-to-delete-time-series).
|
||||
The user can **force** compaction on the specified per-month partition by sending a request to `/internal/force_merge?partition_prefix=YYYY_MM`,
|
||||
where `YYYY_MM` is the per-month partition name. For example, `http://victoriametrics:8428/internal/force_merge?partition_prefix=2020_08` would initiate a forced
|
||||
merge for the August 2020 partition. The call to `/internal/force_merge` returns immediately, while the corresponding forced merge continues running in the background.
|
||||
|
||||
Forced merges may require additional CPU, disk IO and storage space resources. It is unnecessary to run forced merge under normal conditions,
|
||||
Forced merges may require additional CPU, disk I/O, and storage space. It is unnecessary to run a forced merge under normal conditions,
|
||||
since VictoriaMetrics automatically performs [optimal merges in background](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282)
|
||||
when new data is ingested into it.
|
||||
|
||||
The `/internal/force_merge` endpoint can be protected from unauthorized access via the `--forceMergeAuthKey` command-line flag.
|
||||
See [General security recommendations](https://docs.victoriametrics.com/victoriametrics/#general-security-recommendations) for more details.
|
||||
|
||||
## Forced flush
|
||||
|
||||
VictoriaMetrics puts the recently [ingested samples](https://docs.victoriametrics.com/victoriametrics/keyconcepts/#write-data) into in-memory buffers,
|
||||
which aren't available for [querying](https://docs.victoriametrics.com/victoriametrics/keyconcepts/#query-data) for up to a few seconds.
|
||||
If you need to query the samples immediately after they are ingested, then call the `/internal/force_flush` HTTP endpoint before running your query.
|
||||
This endpoint converts in-memory buffers containing recently ingested samples into searchable data blocks.
|
||||
|
||||
It isn't recommended to force flush on a regular basis, as this increases CPU usage and slows data ingestion.
|
||||
The `/internal/force_flush` endpoint exists for debug and test purposes (for instance, for automated tests) and should be avoided in production.
|
||||
|
||||
> VictoriaMetrics may intentionally hide samples with timestamps close to the current time during querying.
|
||||
> This behavior is controlled via `-search.latencyOffset` command-line flag. See more details in [Query latency](https://docs.victoriametrics.com/victoriametrics/keyconcepts/#query-latency) documentation.
|
||||
|
||||
The `/internal/force_flush` endpoint can be protected from unauthorized access via `-forceFlushAuthKey` command-line flag.
|
||||
See [General security recommendations](https://docs.victoriametrics.com/victoriametrics/#general-security-recommendations) for more details.
|
||||
|
||||
## How to export time series
|
||||
|
||||
VictoriaMetrics provides the following handlers for exporting data:
|
||||
@@ -1736,16 +1755,16 @@ VictoriaMetrics provides the following security-related command-line flags:
|
||||
* `-mtls` and `-mtlsCAFile` for enabling [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication) for requests to `-httpListenAddr`. See [these docs](#mtls-protection).
|
||||
* `-httpAuth.username` and `-httpAuth.password` for protecting all the HTTP endpoints
|
||||
with [HTTP Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
|
||||
* `-deleteAuthKey` for protecting `/api/v1/admin/tsdb/delete_series` endpoint. See [how to delete time series](#how-to-delete-time-series).
|
||||
* `-snapshotAuthKey` for protecting `/snapshot*` endpoints. See [how to work with snapshots](#how-to-work-with-snapshots).
|
||||
* `-forceFlushAuthKey` for protecting `/internal/force_flush` endpoint. See [these docs](#troubleshooting).
|
||||
* `-forceMergeAuthKey` for protecting `/internal/force_merge` endpoint. See [force merge docs](#forced-merge).
|
||||
* `-search.resetCacheAuthKey` for protecting `/internal/resetRollupResultCache` endpoint. See [backfilling](#backfilling) for more details.
|
||||
* `-reloadAuthKey` for protecting `/-/reload` endpoint, which is used for force reloading of [`-promscrape.config`](#how-to-scrape-prometheus-exporters-such-as-node-exporter).
|
||||
* `-configAuthKey` for protecting `/config` endpoint, since it may contain sensitive information such as passwords.
|
||||
* `-flagsAuthKey` for protecting `/flags` endpoint.
|
||||
* `-pprofAuthKey` for protecting `/debug/pprof/*` endpoints, which can be used for [profiling](#profiling).
|
||||
* `-metricNamesStatsResetAuthKey` for protecting `/api/v1/admin/status/metric_names_stats/reset` endpoint, used for [Metric Names Tracker](#track-ingested-metrics-usage).
|
||||
* `-deleteAuthKey` for protecting the `/api/v1/admin/tsdb/delete_series` endpoint. See [how to delete time series](#how-to-delete-time-series).
|
||||
* `-snapshotAuthKey` for protecting the `/snapshot*` endpoints. See [how to work with snapshots](#how-to-work-with-snapshots).
|
||||
* `-forceFlushAuthKey` for protecting the `/internal/force_flush` endpoint. See [force flush docs](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#forced-flush).
|
||||
* `-forceMergeAuthKey` for protecting the `/internal/force_merge` endpoint. See [force merge docs](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#forced-merge).
|
||||
* `-search.resetCacheAuthKey` for protecting the `/internal/resetRollupResultCache` endpoint. See [backfilling](#backfilling) for more details.
|
||||
* `-reloadAuthKey` for protecting the `/-/reload` endpoint, which is used for force reloading of [`-promscrape.config`](#how-to-scrape-prometheus-exporters-such-as-node-exporter).
|
||||
* `-configAuthKey` for protecting the `/config` endpoint, since it may contain sensitive information such as passwords.
|
||||
* `-flagsAuthKey` for protecting the `/flags` endpoint.
|
||||
* `-pprofAuthKey` for protecting the `/debug/pprof/*` endpoints, which can be used for [profiling](#profiling).
|
||||
* `-metricNamesStatsResetAuthKey` for protecting the `/api/v1/admin/status/metric_names_stats/reset` endpoint, used for [Metric Names Tracker](#track-ingested-metrics-usage).
|
||||
* `-denyQueryTracing` for disallowing [query tracing](#query-tracing).
|
||||
* `-http.header.hsts`, `-http.header.csp`, and `-http.header.frameOptions` for serving `Strict-Transport-Security`, `Content-Security-Policy`
|
||||
and `X-Frame-Options` HTTP response headers.
|
||||
|
||||
@@ -28,10 +28,10 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel
|
||||
|
||||
* FEATURE: all VictoriaMetrics components: improve logging for the `-memory.allowedBytes` flag to warn about excessively low value (less than 1MB). See issue [#10935](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10935).
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) and [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): add `basicAuth.usernameFile` command-line flags for reading basic auth username from a file, similar to the existing `basicAuth.passwordFile`. The file is re-read every second. See [#9436](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9436). Thanks to @kimjune01 for the contribution.
|
||||
* FEATURE: `vminsert` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): add `clusternative.tls` `vminsert` configuration flags for [multi-level cluster setups](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/#multi-level-cluster-setup). See [#10958](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10958).
|
||||
* FEATURE: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/), `vminsert` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/) and [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): add `-opentelemetry.labelNameUnderscoreSanitization` command-line flag to control whether to enable prepending of `key` to labels starting with `_` when `-opentelemetry.usePrometheusNaming` is enabled. See [OpenTelemetry](https://docs.victoriametrics.com/victoriametrics/integrations/opentelemetry/) docs and [#9663](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9663). Thanks to @andriibeee for the contribution.
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): improve the [Top Queries](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#top-queries) table UI. Duration columns now display human-readable values (e.g. `1.23s`) instead of raw seconds, memory column shows human-readable sizes (e.g. `1.23 MB`), instant queries are labeled as `instant` instead of empty string, and column headers now show tooltips with descriptions. See [#10790](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10790).
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): drain in-memory remote write queue on shutdown within the 5-second grace period before falling back to persisting blocks to disk. See [#9996](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9996)
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): display `null` values on `Raw Query` chart. `null` values can be actual `NaN` or `null` values exposed by the exporter, or [stale markers](https://docs.victoriametrics.com/victoriametrics/vmagent/#prometheus-staleness-markers). Before, vmui Raw Query was silently dropping non-numeric values. Displaying such values on the chart could improve the debugging experience.
|
||||
|
||||
* BUGFIX: [stream aggregation](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/): stop emitting stale values for `quantiles(...)` outputs when a time series has no samples during the current aggregation interval. See [#10918](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10918). Thanks to @alexei38 for the contribution.
|
||||
* BUGFIX: [stream aggregation](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/): extend delay on aggregation windows flush by the biggest lag among pushed samples. Before, the delay was calculated as 95th percentile across samples, which could underrepresent outliers and reject them from aggregation as "too old". See [#10402](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10402).
|
||||
@@ -44,6 +44,7 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel
|
||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): prevent unintentional rerouting of samples to other sharding targets when one of the `-remoteWrite.url` targets with `-remoteWrite.disableOnDiskQueue` becomes blocked. Previously this could break the sharding guarantee by sending samples to wrong targets instead of dropping or retrying them. See [#10507](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10507).
|
||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): return error on startup if `-remoteWrite.disableOnDiskQueue` is not configured uniformly across all `-remoteWrite.url` targets when `-remoteWrite.shardByURL` is enabled. Either all targets must have it enabled or all must have it disabled. See [#10507](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10507).
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): hide values passed to `vmalert.proxyURL` in startup logs, `/metrics`, and `/flags`, since they can contain sensitive HTTP headers such as `Authorization` and API keys.
|
||||
* BUGFIX: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): preserve exact series values in graph tooltips instead of rounding them by significant digits. See [#10952](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10952).
|
||||
|
||||
## [v1.143.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.143.0)
|
||||
|
||||
|
||||
@@ -353,6 +353,18 @@ Example Docker image:
|
||||
|
||||
`victoriametrics/victoria-metrics:v1.143.0-enterprise-fips` – uses the FIPS-compatible binary and based on `scratch` image.
|
||||
|
||||
## What Happens to Licensed Components When a License Expires
|
||||
|
||||
When a license expires, all licensed components continue to function normally until a restart occurs.
|
||||
|
||||
License checks happen only at startup. If a license expires while the component is running, nothing changes; the component continues to run until the next restart.
|
||||
|
||||
This means you don't need to restart components to install a new license. The component automatically picks up the new license the next time it restarts. The exception is when the `-license` flag is used, because the license is supplied at startup and changing it requires restarting VictoriaMetrics with the updated flag value.
|
||||
|
||||
If your license has expired and you decide to not renew it, you can switch to the VictoriaMetrics Open Source version without data loss, as both versions share the same data model. In doing so, however, you will lose access to the [VictoriaMetrics Enterprise features](https://docs.victoriametrics.com/victoriametrics/enterprise/#victoriametrics-enterprise-features).
|
||||
|
||||
See [updating the license key](https://docs.victoriametrics.com/victoriametrics/enterprise/#updating-the-license-key) for more details.
|
||||
|
||||
## Monitoring license expiration
|
||||
|
||||
All the Enterprise components expose the following metrics at the `/metrics` page:
|
||||
|
||||
@@ -313,7 +313,7 @@ The following variables are available in templating:
|
||||
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| $value or .Value | The current alert's value. Avoid using value in labels, it may cause unexpected issues. | `Number of connections is {{ $value }}` |
|
||||
| $activeAt or .ActiveAt | The moment of [time](https://pkg.go.dev/time) when alert became active (`pending` or `firing`). | `http://vm-grafana.com/<dashboard-id>?viewPanel=<panel-id>&from={{($activeAt.Add (parseDurationTime \"-1h\")).UnixMilli}}&to={{($activeAt.Add (parseDurationTime \"1h\")).UnixMilli}}` |
|
||||
| $labels or .Labels | The list of labels of the current alert. Use as `.Labels.<label_name>`. | `Too high number of connections for {{ .Labels.instance }}` |
|
||||
| $labels or .Labels | The list of labels of the current alert. Use as `.Labels.<label_name>`. When the label name contains `.`, such as `cpu.mode`, use `{{ index .Labels "cpu.mode" }}` to access label value instead. | `Too high number of connections for {{ .Labels.instance }}` |
|
||||
| $type or .Type | The rule type: "graphite", "prometheus" or "vlogs" | `Link: /explore?left={"datasource":"{{ if eq .Type "vlogs" }}VictoriaLogs{{ else }}VictoriaMetrics{{ end }}","queries":[{"expr":"{{ .Expr }}"}]}` |
|
||||
| $alertID or .AlertID | The current alert's ID generated by vmalert. | `Link: /vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}` |
|
||||
| $groupID or .GroupID | The current alert's group ID generated by vmalert. | `Link: /vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}` |
|
||||
|
||||
Reference in New Issue
Block a user