From 33c6cc2530b228961754680acf8ba4da817a3ac0 Mon Sep 17 00:00:00 2001 From: Artem Navoiev Date: Tue, 4 Apr 2023 13:00:22 +0200 Subject: [PATCH 01/27] fix closing divs in docs Signed-off-by: Artem Navoiev --- docs/guides/guide-delete-or-replace-metrics.md | 1 + docs/url-examples.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/guides/guide-delete-or-replace-metrics.md b/docs/guides/guide-delete-or-replace-metrics.md index 4b3526560..edce40e58 100644 --- a/docs/guides/guide-delete-or-replace-metrics.md +++ b/docs/guides/guide-delete-or-replace-metrics.md @@ -89,6 +89,7 @@ To trigger [forced merge](https://docs.victoriametrics.com/Single-server-Victori ```console curl -v -X POST http://vmstorage:8482/internal/force_merge ``` + After the merge is complete, the data will be permanently deleted from the disk. diff --git a/docs/url-examples.md b/docs/url-examples.md index 37f5a4103..186dab381 100644 --- a/docs/url-examples.md +++ b/docs/url-examples.md @@ -226,6 +226,7 @@ Single-node VictoriaMetrics: ```console curl -X POST http://localhost:8428/api/v1/import/native -T filename.bin ``` + Cluster version of VictoriaMetrics:
@@ -252,6 +253,8 @@ Single-node VictoriaMetrics: curl -d 'metric_name{foo="bar"} 123' -X POST http://localhost:8428/api/v1/import/prometheus ``` +
+ Cluster version of VictoriaMetrics:
From a8d149702487b9cd6f895f992bb4b2f9cb4ac10e Mon Sep 17 00:00:00 2001 From: Zakhar Bessarab Date: Tue, 4 Apr 2023 15:25:29 +0400 Subject: [PATCH 02/27] app/vmalert: update Grafana URLs to match latest format (#4061) See: #4019 Signed-off-by: Zakhar Bessarab --- app/vmalert/README.md | 2 +- app/vmalert/main.go | 2 +- docs/vmalert.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/vmalert/README.md b/app/vmalert/README.md index 047e9eebe..16b9450d0 100644 --- a/app/vmalert/README.md +++ b/app/vmalert/README.md @@ -916,7 +916,7 @@ The shortlist of configuration flags is the following: -evaluationInterval duration How often to evaluate the rules (default 1m0s) -external.alert.source string - External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]'. Link to VMUI: -external.alert.source='vmui/#/?g0.expr={{.Expr|queryEscape}}'. If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used. + External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left={"datasource":"VictoriaMetrics","queries":[{"expr":{{$expr|jsonEscape|queryEscape}},"refId":"A"}],"range":{"from":"now-1h","to":"now"}}'. Link to VMUI: -external.alert.source='vmui/#/?g0.expr={{.Expr|queryEscape}}'. If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used. -external.label array Optional label in the form 'Name=value' to add to all generated recording rules and alerts. Pass multiple -label flags in order to add multiple label sets. Supports an array of values separated by comma or specified via multiple flags. diff --git a/app/vmalert/main.go b/app/vmalert/main.go index 0e1ff26c1..7c3580b63 100644 --- a/app/vmalert/main.go +++ b/app/vmalert/main.go @@ -73,7 +73,7 @@ absolute path to all .tpl files in root.`) externalAlertSource = flag.String("external.alert.source", "", `External Alert Source allows to override the Source link for alerts sent to AlertManager `+ `for cases where you want to build a custom link to Grafana, Prometheus or any other service. `+ `Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . `+ - `For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]'. `+ + `For example, link to Grafana: -external.alert.source='explore?orgId=1&left={"datasource":"VictoriaMetrics","queries":[{"expr":{{$expr|jsonEscape|queryEscape}},"refId":"A"}],"range":{"from":"now-1h","to":"now"}}'. `+ `Link to VMUI: -external.alert.source='vmui/#/?g0.expr={{.Expr|queryEscape}}'. `+ `If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.`) externalLabels = flagutil.NewArrayString("external.label", "Optional label in the form 'Name=value' to add to all generated recording rules and alerts. "+ diff --git a/docs/vmalert.md b/docs/vmalert.md index afbe71196..86e3f2d9c 100644 --- a/docs/vmalert.md +++ b/docs/vmalert.md @@ -920,7 +920,7 @@ The shortlist of configuration flags is the following: -evaluationInterval duration How often to evaluate the rules (default 1m0s) -external.alert.source string - External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]'. Link to VMUI: -external.alert.source='vmui/#/?g0.expr={{.Expr|queryEscape}}'. If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used. + External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left={"datasource":"VictoriaMetrics","queries":[{"expr":{{$expr|jsonEscape|queryEscape}},"refId":"A"}],"range":{"from":"now-1h","to":"now"}}'. Link to VMUI: -external.alert.source='vmui/#/?g0.expr={{.Expr|queryEscape}}'. If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used. -external.label array Optional label in the form 'Name=value' to add to all generated recording rules and alerts. Pass multiple -label flags in order to add multiple label sets. Supports an array of values separated by comma or specified via multiple flags. From 8a6acce7d38c87f4ef101dcea89a063cb3282d7e Mon Sep 17 00:00:00 2001 From: Zakhar Bessarab Date: Tue, 4 Apr 2023 15:26:08 +0400 Subject: [PATCH 03/27] deployment/docker: update Grafana URLs to match latest format (#4060) See: #4019 Signed-off-by: Zakhar Bessarab --- deployment/docker/docker-compose-cluster.yml | 2 +- deployment/docker/docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/docker/docker-compose-cluster.yml b/deployment/docker/docker-compose-cluster.yml index 3c5aef5f4..210e70ec5 100644 --- a/deployment/docker/docker-compose-cluster.yml +++ b/deployment/docker/docker-compose-cluster.yml @@ -101,7 +101,7 @@ services: # display source of alerts in grafana - '-external.url=http://127.0.0.1:3000' #grafana outside container # when copypaste the line below be aware of '$$' for escaping in '$expr' - - '--external.alert.source=explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' + - '--external.alert.source=explore?orgId=1&left={"datasource":"VictoriaMetrics","queries":[{"expr":{{$$expr|jsonEscape|queryEscape}},"refId":"A"}],"range":{"from":"now-1h","to":"now"}}' restart: always alertmanager: diff --git a/deployment/docker/docker-compose.yml b/deployment/docker/docker-compose.yml index c96c609f7..8b41723de 100644 --- a/deployment/docker/docker-compose.yml +++ b/deployment/docker/docker-compose.yml @@ -76,7 +76,7 @@ services: # display source of alerts in grafana - "--external.url=http://127.0.0.1:3000" #grafana outside container # when copypaste the line be aware of '$$' for escaping in '$expr' - - '--external.alert.source=explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' + - '--external.alert.source=explore?orgId=1&left={"datasource":"VictoriaMetrics","queries":[{"expr":{{$$expr|jsonEscape|queryEscape}},"refId":"A"}],"range":{"from":"now-1h","to":"now"}}' networks: - vm_net restart: always From 59102db4cf6f69b8e158c214de707cce276ee69f Mon Sep 17 00:00:00 2001 From: Artem Navoiev Date: Wed, 5 Apr 2023 15:45:38 +0200 Subject: [PATCH 04/27] update changelog Signed-off-by: Artem Navoiev --- docs/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index eb1563a3b..05a53f0d1 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -21,7 +21,6 @@ created by v1.90.0 or newer versions. The solution is to upgrade to v1.90.0 or n * SECURITY: upgrade base docker image (alpine) from 3.17.2 to 3.17.3. See [alpine 3.17.3 release notes](https://alpinelinux.org/posts/Alpine-3.17.3-released.html). -* FEATURE: open source [Graphite Render API](https://docs.victoriametrics.com/#graphite-render-api-usage). This API allows using VictoriaMetrics as a drop-in replacement for Graphite at both data ingestion and querying sides and reducing infrastructure costs by up to 10x comparing to Graphite. See [this case study](https://docs.victoriametrics.com/CaseStudies.html#grammarly) as an example. * FEATURE: release Windows binaries for [single-node VictoriaMetrics](https://docs.victoriametrics.com/), [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html), [vmbackup](https://docs.victoriametrics.com/vmbackup.html) and [vmrestore](https://docs.victoriametrics.com/vmrestore.html). See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3236), [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3821) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/70) issues. * FEATURE: log metrics with truncated labels if the length of label value in the ingested metric exceeds `-maxLabelValueLen`. This should simplify debugging for this case. * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): show target URL when debugging [target relabeling](https://docs.victoriametrics.com/vmagent.html#relabel-debug). This should simplify target relabel debugging a bit. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3882). From c7bcf750c2d031b1259cd8115d7464b67f40cb9e Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 13:28:41 -0700 Subject: [PATCH 05/27] docs/Troubleshooting.md: add General troubleshooting checklist This checklist helps searching for the infromation related to some issue / question about VictoriaMetrics --- docs/Troubleshooting.md | 79 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index e7d9192ac..1a6cb0305 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -6,6 +6,7 @@ sort: 23 This document contains troubleshooting guides for most common issues when working with VictoriaMetrics: +- [General troubleshooting checklist](#general-toubleshooting-checklist) - [Unexpected query results](#unexpected-query-results) - [Slow data ingestion](#slow-data-ingestion) - [Slow queries](#slow-queries) @@ -13,6 +14,84 @@ This document contains troubleshooting guides for most common issues when workin - [Cluster instability](#cluster-instability) - [Monitoring](#monitoring) +## General troubleshooting checklist + +If you hit some issue or have some question about VictoriaMetrics components, +then please follow the following steps in order to quickly find the solution: + +1. Check the version of VictoriaMetrics component, which needs to be troubleshot and compare + it to [the latest available version](https://docs.victoriametrics.com/CHANGELOG.html). + If the used version is lower than the latest available version, then there are high chances + that the issue is already resolved in newer versions. Carefully read [the changelog](https://docs.victoriametrics.com/CHANGELOG.html) + between your version and the latest version and check whether the issue is already fixed there. + + If the issue is already fixed in newer versions, then upgrade to the newer version and verify whether the issue is fixed: + + - [How to upgrade single-node VictoriaMetrics](https://docs.victoriametrics.com/#how-to-upgrade-victoriametrics) + - [How to upgrade VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#updating--reconfiguring-cluster-nodes) + + Upgrade procedure for other VictoriaMetrics components is as simple as gracefully stopping the component + by sending `SIGINT` signal to it and starting the new version of the component. + + There may be breaking changes between different versions of VictoriaMetrics components in rare cases. + These cases are documented in [the changelog](https://docs.victoriametrics.com/CHANGELOG.html). + So please read the changelog before the upgrade. + +1. Check for logs in VictoriaMetrics components. They may contain useful information about the issue. + If the log message doesn't have enough useful information for troubleshooting the issue, + then search the log message in Google. There are high chances that the issue is already reported + somewhere (docs, StackOverflow, Github issues, etc.) indexed by Google and the solution is already documented there. + +1. If VictoriaMetrics logs have no relevant information, then try searching for the issue in Google + via multiple keywords and phrases specific to the issue. There are high chances that the issue + and the solution is already documented somewhere. + +1. Try searching for the issue at [VictoriaMetrics Github](https://github.com/VictoriaMetrics/VictoriaMetrics/issues) + The sinal/noise quality of search results here is much lower than in Google, but sometimes it may help + finding the relevant information about the issue when Google fails to find the needed information. + If you located the relevant Github issue, but it misses some information on how to diagnose or troubleshoot + the issue, then please provide this information in comments to the issue. This increases chances + that the issue will be resolved soon. + +1. Try searching for information about the issue in [VictoriaMetrics source code](https://github.com/search?q=repo%3AVictoriaMetrics%2FVictoriaMetrics&type=code). + Github code search may be not very good in some cases, so it is recommended [checking out VictoriaMetrics source code](https://github.com/VictoriaMetrics/VictoriaMetrics/) + and perform local search in the checked out code. + Note that the source code for VictoriaMetrics cluster is located in [the cluster](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/cluster) branch. + +1. Try searching for information about the issue in the history of [VictoriaMetrics Slack chat](https://victoriametrics.slack.com). + There are non-zero chances that somebody already stuck with the same issue and documented the solution at Slack. + +1. If steps above didn't help finding the solution to the issue, then please [file a new issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/new/choose) + by providing the maximum details on how to reproduce the issue. + + After that you can post the link to the issue to [VictoriaMetrics Slack chat](https://victoriametrics.slack.com), + so VictoriaMetrics community could help finding the solution to the issue. It is better filing the issue at VictoriaMetrics Github + before posting your question to VictoriaMetrics Slack chat, since Github issues are indexed by Google, + while Slack messages aren't indexed by Google. This simplifies searching for the solution to the issue for future VictoriaMetrics users. + +1. Pro tip 1: if you see that [VictoriaMetrics docs](https://docs.victoriametrics.com/) contain incomplete or incorrect information, + then please create a pull request with the relevant changes. This will VictoriaMetrics community. + + All the docs published at `https://docs.victoriametrics.com` are located in the [docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs) + folder inside VictoriaMetrics repository. + +1. Pro tip 2: please provide links to existing docs / Github issues / StackOverflow questions + instead of copy-n-pasting the information from these sources when asking or answering questions + from VictoriaMetrics community. If the linked resources have no enough information, + then it is better posting the missing information in the web resource before providing links + to this information in Slack chat. This will simplify searching for this information in the future + for VictoriaMetrics users via Google and ChatGPT :) + +1. Pro tip 3: if you are answering somebody's question about VictoriaMetrics components + at Github issues / Slack chat / StackOverflow, then the best answer is a direct link to the information + regaring the question. + The better answer is a concise message with multiple links to the relevant information. + The worst answer is a message with misleading or completely wrong information. + +1. Pro tip 4: if you can fix the issue on yourself, then please do it and provide the corresponding pull request! + We are glad to get pull requests from VictoriaMetrics community. + + ## Unexpected query results If you see unexpected or unreliable query results from VictoriaMetrics, then try the following steps: From 5074cc672a67cad6f0939e6ce0a607e3f5ab6b4e Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 13:37:20 -0700 Subject: [PATCH 06/27] all: update Go builder from Go1.20.2 to Go1.20.3 See https://github.com/golang/go/issues?q=milestone%3AGo1.20.3+label%3ACherryPickApproved --- .github/workflows/check-licenses.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/main.yml | 6 +++--- .github/workflows/nightly-build.yml | 2 +- app/vmui/Dockerfile-web | 2 +- deployment/docker/Makefile | 2 +- docs/CHANGELOG.md | 1 + snap/local/Makefile | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check-licenses.yml b/.github/workflows/check-licenses.yml index 0d321fc5c..a9fe98297 100644 --- a/.github/workflows/check-licenses.yml +++ b/.github/workflows/check-licenses.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Go uses: actions/setup-go@main with: - go-version: 1.20.2 + go-version: 1.20.3 id: go - name: Code checkout uses: actions/checkout@master diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7e4ba6b33..41a1a5db9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -57,7 +57,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.20.2 + go-version: 1.20.3 check-latest: true cache: true if: ${{ matrix.language == 'go' }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 779b1b729..cc8e9f75a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: 1.20.2 + go-version: 1.20.3 check-latest: true cache: true @@ -56,7 +56,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: 1.20.2 + go-version: 1.20.3 check-latest: true cache: true @@ -81,7 +81,7 @@ jobs: id: go uses: actions/setup-go@v4 with: - go-version: 1.20.2 + go-version: 1.20.3 check-latest: true cache: true diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index 33a3c0e01..cbc6029ec 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Go uses: actions/setup-go@main with: - go-version: 1.20.2 + go-version: 1.20.3 id: go - name: Setup docker scan diff --git a/app/vmui/Dockerfile-web b/app/vmui/Dockerfile-web index bf19ceeab..5ca408acc 100644 --- a/app/vmui/Dockerfile-web +++ b/app/vmui/Dockerfile-web @@ -1,4 +1,4 @@ -FROM golang:1.20.2 as build-web-stage +FROM golang:1.20.3 as build-web-stage COPY build /build WORKDIR /build diff --git a/deployment/docker/Makefile b/deployment/docker/Makefile index 3d224b7b9..f082cbbeb 100644 --- a/deployment/docker/Makefile +++ b/deployment/docker/Makefile @@ -4,7 +4,7 @@ DOCKER_NAMESPACE := victoriametrics ROOT_IMAGE ?= alpine:3.17.3 CERTS_IMAGE := alpine:3.17.3 -GO_BUILDER_IMAGE := golang:1.20.2-alpine +GO_BUILDER_IMAGE := golang:1.20.3-alpine BUILDER_IMAGE := local/builder:2.0.0-$(shell echo $(GO_BUILDER_IMAGE) | tr :/ __)-1 BASE_IMAGE := local/base:1.1.4-$(shell echo $(ROOT_IMAGE) | tr :/ __)-$(shell echo $(CERTS_IMAGE) | tr :/ __) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 05a53f0d1..0a3141a5d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -20,6 +20,7 @@ so the previous versions of VictoriaMetrics will exit with the `unexpected numbe created by v1.90.0 or newer versions. The solution is to upgrade to v1.90.0 or newer releases** * SECURITY: upgrade base docker image (alpine) from 3.17.2 to 3.17.3. See [alpine 3.17.3 release notes](https://alpinelinux.org/posts/Alpine-3.17.3-released.html). +* SECURITY: upgrade Go builder from Go1.20.2 to Go1.20.3. See [the list of issues addressed in Go1.20.3](https://github.com/golang/go/issues?q=milestone%3AGo1.20.3+label%3ACherryPickApproved). * FEATURE: release Windows binaries for [single-node VictoriaMetrics](https://docs.victoriametrics.com/), [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html), [vmbackup](https://docs.victoriametrics.com/vmbackup.html) and [vmrestore](https://docs.victoriametrics.com/vmrestore.html). See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3236), [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3821) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/70) issues. * FEATURE: log metrics with truncated labels if the length of label value in the ingested metric exceeds `-maxLabelValueLen`. This should simplify debugging for this case. diff --git a/snap/local/Makefile b/snap/local/Makefile index c16434801..46726707e 100644 --- a/snap/local/Makefile +++ b/snap/local/Makefile @@ -1,4 +1,4 @@ -GO_VERSION ?=1.20.2 +GO_VERSION ?=1.20.3 SNAP_BUILDER_IMAGE := local/snap-builder:2.0.0-$(shell echo $(GO_VERSION) | tr :/ __) From a265da4f53361bc272bc752009636c8584037ed5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 13:40:24 -0700 Subject: [PATCH 07/27] docs/Troubleshooting.md: fix a typo in the link after c7bcf750c2d031b1259cd8115d7464b67f40cb9e --- docs/Troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 1a6cb0305..cbe443259 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -6,7 +6,7 @@ sort: 23 This document contains troubleshooting guides for most common issues when working with VictoriaMetrics: -- [General troubleshooting checklist](#general-toubleshooting-checklist) +- [General troubleshooting checklist](#general-troubleshooting-checklist) - [Unexpected query results](#unexpected-query-results) - [Slow data ingestion](#slow-data-ingestion) - [Slow queries](#slow-queries) From 052160dcdca7df3c4aa5ef0679aa681fd1d644d7 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 13:46:19 -0700 Subject: [PATCH 08/27] docs/Troubleshooting.md: fix formatting after c7bcf750c2d031b1259cd8115d7464b67f40cb9e --- docs/Troubleshooting.md | 90 ++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index cbe443259..064318d67 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -20,76 +20,76 @@ If you hit some issue or have some question about VictoriaMetrics components, then please follow the following steps in order to quickly find the solution: 1. Check the version of VictoriaMetrics component, which needs to be troubleshot and compare - it to [the latest available version](https://docs.victoriametrics.com/CHANGELOG.html). - If the used version is lower than the latest available version, then there are high chances - that the issue is already resolved in newer versions. Carefully read [the changelog](https://docs.victoriametrics.com/CHANGELOG.html) - between your version and the latest version and check whether the issue is already fixed there. + it to [the latest available version](https://docs.victoriametrics.com/CHANGELOG.html). + If the used version is lower than the latest available version, then there are high chances + that the issue is already resolved in newer versions. Carefully read [the changelog](https://docs.victoriametrics.com/CHANGELOG.html) + between your version and the latest version and check whether the issue is already fixed there. - If the issue is already fixed in newer versions, then upgrade to the newer version and verify whether the issue is fixed: + If the issue is already fixed in newer versions, then upgrade to the newer version and verify whether the issue is fixed: - - [How to upgrade single-node VictoriaMetrics](https://docs.victoriametrics.com/#how-to-upgrade-victoriametrics) - - [How to upgrade VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#updating--reconfiguring-cluster-nodes) + - [How to upgrade single-node VictoriaMetrics](https://docs.victoriametrics.com/#how-to-upgrade-victoriametrics) + - [How to upgrade VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#updating--reconfiguring-cluster-nodes) - Upgrade procedure for other VictoriaMetrics components is as simple as gracefully stopping the component - by sending `SIGINT` signal to it and starting the new version of the component. + Upgrade procedure for other VictoriaMetrics components is as simple as gracefully stopping the component + by sending `SIGINT` signal to it and starting the new version of the component. - There may be breaking changes between different versions of VictoriaMetrics components in rare cases. - These cases are documented in [the changelog](https://docs.victoriametrics.com/CHANGELOG.html). - So please read the changelog before the upgrade. + There may be breaking changes between different versions of VictoriaMetrics components in rare cases. + These cases are documented in [the changelog](https://docs.victoriametrics.com/CHANGELOG.html). + So please read the changelog before the upgrade. 1. Check for logs in VictoriaMetrics components. They may contain useful information about the issue. - If the log message doesn't have enough useful information for troubleshooting the issue, - then search the log message in Google. There are high chances that the issue is already reported - somewhere (docs, StackOverflow, Github issues, etc.) indexed by Google and the solution is already documented there. + If the log message doesn't have enough useful information for troubleshooting the issue, + then search the log message in Google. There are high chances that the issue is already reported + somewhere (docs, StackOverflow, Github issues, etc.) indexed by Google and the solution is already documented there. 1. If VictoriaMetrics logs have no relevant information, then try searching for the issue in Google - via multiple keywords and phrases specific to the issue. There are high chances that the issue - and the solution is already documented somewhere. + via multiple keywords and phrases specific to the issue. There are high chances that the issue + and the solution is already documented somewhere. 1. Try searching for the issue at [VictoriaMetrics Github](https://github.com/VictoriaMetrics/VictoriaMetrics/issues) - The sinal/noise quality of search results here is much lower than in Google, but sometimes it may help - finding the relevant information about the issue when Google fails to find the needed information. - If you located the relevant Github issue, but it misses some information on how to diagnose or troubleshoot - the issue, then please provide this information in comments to the issue. This increases chances - that the issue will be resolved soon. + The sinal/noise quality of search results here is much lower than in Google, but sometimes it may help + finding the relevant information about the issue when Google fails to find the needed information. + If you located the relevant Github issue, but it misses some information on how to diagnose or troubleshoot + the issue, then please provide this information in comments to the issue. This increases chances + that the issue will be resolved soon. 1. Try searching for information about the issue in [VictoriaMetrics source code](https://github.com/search?q=repo%3AVictoriaMetrics%2FVictoriaMetrics&type=code). - Github code search may be not very good in some cases, so it is recommended [checking out VictoriaMetrics source code](https://github.com/VictoriaMetrics/VictoriaMetrics/) - and perform local search in the checked out code. - Note that the source code for VictoriaMetrics cluster is located in [the cluster](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/cluster) branch. + Github code search may be not very good in some cases, so it is recommended [checking out VictoriaMetrics source code](https://github.com/VictoriaMetrics/VictoriaMetrics/) + and perform local search in the checked out code. + Note that the source code for VictoriaMetrics cluster is located in [the cluster](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/cluster) branch. 1. Try searching for information about the issue in the history of [VictoriaMetrics Slack chat](https://victoriametrics.slack.com). - There are non-zero chances that somebody already stuck with the same issue and documented the solution at Slack. + There are non-zero chances that somebody already stuck with the same issue and documented the solution at Slack. 1. If steps above didn't help finding the solution to the issue, then please [file a new issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/new/choose) - by providing the maximum details on how to reproduce the issue. + by providing the maximum details on how to reproduce the issue. - After that you can post the link to the issue to [VictoriaMetrics Slack chat](https://victoriametrics.slack.com), - so VictoriaMetrics community could help finding the solution to the issue. It is better filing the issue at VictoriaMetrics Github - before posting your question to VictoriaMetrics Slack chat, since Github issues are indexed by Google, - while Slack messages aren't indexed by Google. This simplifies searching for the solution to the issue for future VictoriaMetrics users. + After that you can post the link to the issue to [VictoriaMetrics Slack chat](https://victoriametrics.slack.com), + so VictoriaMetrics community could help finding the solution to the issue. It is better filing the issue at VictoriaMetrics Github + before posting your question to VictoriaMetrics Slack chat, since Github issues are indexed by Google, + while Slack messages aren't indexed by Google. This simplifies searching for the solution to the issue for future VictoriaMetrics users. 1. Pro tip 1: if you see that [VictoriaMetrics docs](https://docs.victoriametrics.com/) contain incomplete or incorrect information, - then please create a pull request with the relevant changes. This will VictoriaMetrics community. + then please create a pull request with the relevant changes. This will VictoriaMetrics community. - All the docs published at `https://docs.victoriametrics.com` are located in the [docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs) - folder inside VictoriaMetrics repository. + All the docs published at `https://docs.victoriametrics.com` are located in the [docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs) + folder inside VictoriaMetrics repository. 1. Pro tip 2: please provide links to existing docs / Github issues / StackOverflow questions - instead of copy-n-pasting the information from these sources when asking or answering questions - from VictoriaMetrics community. If the linked resources have no enough information, - then it is better posting the missing information in the web resource before providing links - to this information in Slack chat. This will simplify searching for this information in the future - for VictoriaMetrics users via Google and ChatGPT :) + instead of copy-n-pasting the information from these sources when asking or answering questions + from VictoriaMetrics community. If the linked resources have no enough information, + then it is better posting the missing information in the web resource before providing links + to this information in Slack chat. This will simplify searching for this information in the future + for VictoriaMetrics users via Google and ChatGPT :) 1. Pro tip 3: if you are answering somebody's question about VictoriaMetrics components - at Github issues / Slack chat / StackOverflow, then the best answer is a direct link to the information - regaring the question. - The better answer is a concise message with multiple links to the relevant information. - The worst answer is a message with misleading or completely wrong information. + at Github issues / Slack chat / StackOverflow, then the best answer is a direct link to the information + regaring the question. + The better answer is a concise message with multiple links to the relevant information. + The worst answer is a message with misleading or completely wrong information. 1. Pro tip 4: if you can fix the issue on yourself, then please do it and provide the corresponding pull request! - We are glad to get pull requests from VictoriaMetrics community. + We are glad to get pull requests from VictoriaMetrics community. ## Unexpected query results @@ -97,7 +97,7 @@ then please follow the following steps in order to quickly find the solution: If you see unexpected or unreliable query results from VictoriaMetrics, then try the following steps: 1. Check whether simplified queries return unexpected results. For example, if the query looks like - `sum(rate(http_requests_total[5m])) by (job)`, then check whether the following queries return + `sum(rate(http_requests_total[5m])) by (job)`, then check whether the following queries return expected results: - Remove the outer `sum` and execute `rate(http_requests_total[5m])`, From 13668fc935df9da577c2b7bab8db927a2bfdeae5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 14:13:08 -0700 Subject: [PATCH 09/27] docs/Troubleshooting.md: another typo fixes after c7bcf750c2d031b1259cd8115d7464b67f40cb9eg --- docs/Troubleshooting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 064318d67..9ff142f2e 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -40,14 +40,14 @@ then please follow the following steps in order to quickly find the solution: 1. Check for logs in VictoriaMetrics components. They may contain useful information about the issue. If the log message doesn't have enough useful information for troubleshooting the issue, then search the log message in Google. There are high chances that the issue is already reported - somewhere (docs, StackOverflow, Github issues, etc.) indexed by Google and the solution is already documented there. + somewhere (docs, StackOverflow, Github issues, etc.) and indexed by Google and the solution is already documented there. 1. If VictoriaMetrics logs have no relevant information, then try searching for the issue in Google via multiple keywords and phrases specific to the issue. There are high chances that the issue and the solution is already documented somewhere. -1. Try searching for the issue at [VictoriaMetrics Github](https://github.com/VictoriaMetrics/VictoriaMetrics/issues) - The sinal/noise quality of search results here is much lower than in Google, but sometimes it may help +1. Try searching for the issue at [VictoriaMetrics Github](https://github.com/VictoriaMetrics/VictoriaMetrics/issues). + The signal/noise quality of search results here is much lower than in Google, but sometimes it may help finding the relevant information about the issue when Google fails to find the needed information. If you located the relevant Github issue, but it misses some information on how to diagnose or troubleshoot the issue, then please provide this information in comments to the issue. This increases chances From 8249451dbbc8e7531d67ad7f1bd3eb8c78053ccc Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 14:28:09 -0700 Subject: [PATCH 10/27] docs/Troubleshooting.md: add missing `help` word after c7bcf750c2d031b1259cd8115d7464b67f40cb9eg --- docs/Troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 9ff142f2e..fe848c20e 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -70,7 +70,7 @@ then please follow the following steps in order to quickly find the solution: while Slack messages aren't indexed by Google. This simplifies searching for the solution to the issue for future VictoriaMetrics users. 1. Pro tip 1: if you see that [VictoriaMetrics docs](https://docs.victoriametrics.com/) contain incomplete or incorrect information, - then please create a pull request with the relevant changes. This will VictoriaMetrics community. + then please create a pull request with the relevant changes. This will help VictoriaMetrics community. All the docs published at `https://docs.victoriametrics.com` are located in the [docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs) folder inside VictoriaMetrics repository. From d87a7005289c31fca5e9321eaafced84f61445a7 Mon Sep 17 00:00:00 2001 From: Timur Bakeyev Date: Thu, 6 Apr 2023 04:56:28 +0200 Subject: [PATCH 11/27] Fix reference to the imagepullsecrets description (#4080) Looks like the original document has moved to the https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod. Alternatively, it could be that https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ describes the meaning of the parameter in more detail. --- docs/operator/api.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/operator/api.md b/docs/operator/api.md index 50b306d72..4a1b2da3c 100644 --- a/docs/operator/api.md +++ b/docs/operator/api.md @@ -171,7 +171,7 @@ VMAlertmanagerSpec is a specification of the desired behavior of the VMAlertmana | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the alertmanager pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | | image | Image - docker image settings for VMAlertmanager if no specified operator uses default config version | [Image](#image) | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMAlertmanager object, which shall be mounted into the VMAlertmanager Pods. The Secrets are mounted into /etc/vm/secrets/<secret-name> | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMAlertmanager object, which shall be mounted into the VMAlertmanager Pods. The ConfigMaps are mounted into /etc/vm/configs/<configmap-name>. | []string | false | | templates | Templates is a list of ConfigMap key references for ConfigMaps in the same namespace as the VMAlertmanager object, which shall be mounted into the VMAlertmanager Pods. The Templates are mounted into /etc/vm/templates/<configmap-name>/<configmap-key>. | [][ConfigMapKeyReference](#configmapkeyreference) | false | @@ -723,7 +723,7 @@ VMAgentSpec defines the desired state of VMAgent | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the vmagent pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | | image | Image - docker image settings for VMAgent if no specified operator uses default config version | [Image](#image) | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the vmagent object, which shall be mounted into the vmagent Pods. will be mounted at path /etc/vm/secrets | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the vmagent object, which shall be mounted into the vmagent Pods. will be mounted at path /etc/vm/configs | []string | false | | logLevel | LogLevel for VMAgent to be configured with. INFO, WARN, ERROR, FATAL, PANIC | string | false | @@ -1091,7 +1091,7 @@ VMAlertSpec defines the desired state of VMAlert | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the VMAlert pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | | image | Image - docker image settings for VMAlert if no specified operator uses default config version | [Image](#image) | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMAlert object, which shall be mounted into the VMAlert Pods. The Secrets are mounted into /etc/vm/secrets/<secret-name>. | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMAlert object, which shall be mounted into the VMAlert Pods. The ConfigMaps are mounted into /etc/vm/configs/<configmap-name>. | []string | false | | logFormat | LogFormat for VMAlert to be configured with. default or json | string | false | @@ -1188,7 +1188,7 @@ VMSingleSpec defines the desired state of VMSingle | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the VMSingle pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | | image | Image - docker image settings for VMSingle if no specified operator uses default config version | [Image](#image) | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMSingle object, which shall be mounted into the VMSingle Pods. | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMSingle object, which shall be mounted into the VMSingle Pods. | []string | false | | logLevel | LogLevel for victoria metrics single to be configured with. | string | false | @@ -1701,7 +1701,7 @@ VMClusterSpec defines the desired state of VMCluster | podSecurityPolicyName | PodSecurityPolicyName - defines name for podSecurityPolicy in case of empty value, prefixedName will be used. | string | false | | serviceAccountName | ServiceAccountName is the name of the ServiceAccount to use to run the VMSelect, VMStorage and VMInsert Pods. | string | false | | clusterVersion | ClusterVersion defines default images tag for all components. it can be overwritten with component specific image.tag value. | string | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | | vmselect | | *[VMSelect](#vmselect) | false | | vminsert | | *[VMInsert](#vminsert) | false | | vmstorage | | *[VMStorage](#vmstorage) | false | @@ -2073,7 +2073,7 @@ VMAuthSpec defines the desired state of VMAuth | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the VMAuth pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | | image | Image - docker image settings for VMAuth if no specified operator uses default config version | [Image](#image) | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMAuth object, which shall be mounted into the VMAuth Pods. | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMAuth object, which shall be mounted into the VMAuth Pods. | []string | false | | logLevel | LogLevel for victoria metrics single to be configured with. | string | false | From 29a692f27800c3c4a306a9a56a26ccab7d491a5c Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Apr 2023 20:52:36 -0700 Subject: [PATCH 12/27] vendor: update github.com/valyala/gozstd from v1.18.0 to v1.19.0 --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/valyala/gozstd/Makefile | 2 +- .../valyala/gozstd/libzstd_linux_amd64.a | Bin 1027680 -> 1065466 bytes .../valyala/gozstd/libzstd_linux_arm.a | Bin 914726 -> 955868 bytes .../valyala/gozstd/libzstd_linux_arm64.a | Bin 845370 -> 862500 bytes .../valyala/gozstd/libzstd_linux_musl_amd64.a | Bin 986408 -> 1014634 bytes .../valyala/gozstd/libzstd_linux_musl_arm64.a | Bin 812626 -> 830532 bytes vendor/github.com/valyala/gozstd/zstd.h | 504 ++++++++++-------- vendor/modules.txt | 2 +- 10 files changed, 280 insertions(+), 234 deletions(-) diff --git a/go.mod b/go.mod index d3978d052..7f1bdb37c 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/valyala/fastjson v1.6.4 github.com/valyala/fastrand v1.1.0 github.com/valyala/fasttemplate v1.2.2 - github.com/valyala/gozstd v1.18.0 + github.com/valyala/gozstd v1.19.0 github.com/valyala/histogram v1.2.0 github.com/valyala/quicktemplate v1.7.0 golang.org/x/net v0.8.0 diff --git a/go.sum b/go.sum index b88a42e69..b97d92f88 100644 --- a/go.sum +++ b/go.sum @@ -425,8 +425,8 @@ github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/gozstd v1.18.0 h1:f4BskcUZBnDrEJ2F+lVbNCMGOFBoGHEw71RBkCNR4IM= -github.com/valyala/gozstd v1.18.0/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ= +github.com/valyala/gozstd v1.19.0 h1:BS0M7sH3dcuyw2SQBrTLprAdGuNxfiH0c4IAM8kX07c= +github.com/valyala/gozstd v1.19.0/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= diff --git a/vendor/github.com/valyala/gozstd/Makefile b/vendor/github.com/valyala/gozstd/Makefile index 2dcc40c7d..b7f1372d3 100644 --- a/vendor/github.com/valyala/gozstd/Makefile +++ b/vendor/github.com/valyala/gozstd/Makefile @@ -3,7 +3,7 @@ GOARCH ?= $(shell go env GOARCH) GOOS_GOARCH := $(GOOS)_$(GOARCH) GOOS_GOARCH_NATIVE := $(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH) LIBZSTD_NAME := libzstd_$(GOOS_GOARCH).a -ZSTD_VERSION ?= v1.5.4 +ZSTD_VERSION ?= v1.5.5 MUSL_BUILDER_IMAGE=golang:1.20.1-alpine BUILDER_IMAGE := local/builder_musl:2.0.0-$(shell echo $(MUSL_BUILDER_IMAGE) | tr : _)-1 diff --git a/vendor/github.com/valyala/gozstd/libzstd_linux_amd64.a b/vendor/github.com/valyala/gozstd/libzstd_linux_amd64.a index 7379e5bd1c8127ad0ff0e1d68280711336523b23..40446a8bedc5f783fbae63ac28e62f4a6443aae6 100644 GIT binary patch delta 374018 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

- {metricName}: - {valueFormat} - {unit} + value: {valueFormat}{unit}

- {!!fields.length && ( -
- {fields.map((f, i) => ( -
{f}
- ))} -
- )} +
+ {bucket} +
), targetPortal); }; diff --git a/app/vmui/packages/vmui/src/components/Chart/HeatmapChart/HeatmapChart.tsx b/app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx similarity index 89% rename from app/vmui/packages/vmui/src/components/Chart/HeatmapChart/HeatmapChart.tsx rename to app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx index 8f7cbc179..cdbe20fc5 100644 --- a/app/vmui/packages/vmui/src/components/Chart/HeatmapChart/HeatmapChart.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx @@ -4,21 +4,21 @@ import uPlot, { Options as uPlotOptions, Range } from "uplot"; -import { defaultOptions, sizeAxis } from "../../../utils/uplot/helpers"; -import { dragChart } from "../../../utils/uplot/events"; -import { getAxes } from "../../../utils/uplot/axes"; -import { MetricResult } from "../../../api/types"; -import { dateFromSeconds, formatDateForNativeInput, limitsDurations } from "../../../utils/time"; +import { defaultOptions, sizeAxis } from "../../../../utils/uplot/helpers"; +import { dragChart } from "../../../../utils/uplot/events"; +import { getAxes } from "../../../../utils/uplot/axes"; +import { MetricResult } from "../../../../api/types"; +import { dateFromSeconds, formatDateForNativeInput, limitsDurations } from "../../../../utils/time"; import throttle from "lodash.throttle"; -import useResize from "../../../hooks/useResize"; -import { TimeParams } from "../../../types"; -import { YaxisState } from "../../../state/graph/reducer"; +import useResize from "../../../../hooks/useResize"; +import { TimeParams } from "../../../../types"; +import { YaxisState } from "../../../../state/graph/reducer"; import "uplot/dist/uPlot.min.css"; import classNames from "classnames"; import dayjs from "dayjs"; -import { useAppState } from "../../../state/common/StateContext"; -import { heatmapPaths } from "../../../utils/uplot/heatmap"; -import { DATE_FULL_TIMEZONE_FORMAT } from "../../../constants/date"; +import { useAppState } from "../../../../state/common/StateContext"; +import { heatmapPaths } from "../../../../utils/uplot/heatmap"; +import { DATE_FULL_TIMEZONE_FORMAT } from "../../../../constants/date"; import ChartTooltipHeatmap, { ChartTooltipHeatmapProps, TooltipHeatmapProps @@ -33,7 +33,7 @@ export interface HeatmapChartProps { setPeriod: ({ from, to }: {from: Date, to: Date}) => void; container: HTMLDivElement | null; height?: number; - onChangeLegend: (val: number) => void; + onChangeLegend: (val: TooltipHeatmapProps) => void; } enum typeChartUpdate {xRange = "xRange", yRange = "yRange"} @@ -62,7 +62,7 @@ const HeatmapChart: FC = ({ const [tooltipOffset, setTooltipOffset] = useState({ left: 0, top: 0 }); const [stickyTooltips, setStickyToolTips] = useState([]); const tooltipId = useMemo(() => { - return `${tooltipProps?.fields.join(",")}_${tooltipProps?.startDate}`; + return `${tooltipProps?.bucket}_${tooltipProps?.startDate}`; }, [tooltipProps]); const setScale = ({ min, max }: { min: number, max: number }): void => { @@ -135,7 +135,7 @@ const HeatmapChart: FC = ({ const handleClick = () => { if (!tooltipProps) return; - const id = `${tooltipProps?.fields.join(",")}_${tooltipProps?.startDate}`; + const id = `${tooltipProps?.bucket}_${tooltipProps?.startDate}`; const props = { id, unit, @@ -171,12 +171,6 @@ const HeatmapChart: FC = ({ return; } - const metric = result?.metric; - const metricName = metric["__name__"] || "value"; - - const labelNames = Object.keys(metric).filter(x => x != "__name__"); - const fields = labelNames.map(key => `${key}=${JSON.stringify(metric[key])}`); - const [endTime = 0, value = ""] = result.values.find(v => v[0] === second) || []; const valueFormat = `${+value}%`; const startTime = xArr[xIdx]; @@ -187,8 +181,7 @@ const HeatmapChart: FC = ({ cursor: { left, top }, startDate, endDate, - metricName, - fields, + bucket: result?.metric?.vmrange || "", value: +value, valueFormat: valueFormat, }); @@ -228,7 +221,7 @@ const HeatmapChart: FC = ({ font: axes[0].font, size: sizeAxis, splits: metrics.map((m, i) => i), - values: metrics.map(m => Object.entries(m.metric).map(e => `${e[0]}=${JSON.stringify(e[1])}`)[0]), + values: metrics.map(m => m.metric.vmrange), } ], scales: { @@ -339,7 +332,7 @@ const HeatmapChart: FC = ({ }, [tooltipProps, stickyTooltips]); useEffect(() => { - onChangeLegend(tooltipProps?.value || 0); + if (tooltipProps) onChangeLegend(tooltipProps); }, [tooltipProps]); return ( diff --git a/app/vmui/packages/vmui/src/components/Chart/Heatmap/LegendHeatmap/LegendHeatmap.tsx b/app/vmui/packages/vmui/src/components/Chart/Heatmap/LegendHeatmap/LegendHeatmap.tsx new file mode 100644 index 000000000..97824cb3f --- /dev/null +++ b/app/vmui/packages/vmui/src/components/Chart/Heatmap/LegendHeatmap/LegendHeatmap.tsx @@ -0,0 +1,68 @@ +import React, { FC, useEffect, useState } from "preact/compat"; +import { gradMetal16 } from "../../../../utils/uplot/heatmap"; +import "./style.scss"; +import { TooltipHeatmapProps } from "../ChartTooltipHeatmap/ChartTooltipHeatmap"; +import { SeriesItem } from "../../../../utils/uplot/series"; +import LegendItem from "../../Line/Legend/LegendItem/LegendItem"; +import { LegendItemType } from "../../../../utils/uplot/types"; + +interface LegendHeatmapProps { + min: number + max: number + legendValue: TooltipHeatmapProps | null, + series: SeriesItem[] +} + +const LegendHeatmap: FC = ( + { + min, + max, + legendValue, + series, + } +) => { + + const [percent, setPercent] = useState(0); + const [valueFormat, setValueFormat] = useState(""); + const [minFormat, setMinFormat] = useState(""); + const [maxFormat, setMaxFormat] = useState(""); + + useEffect(() => { + const value = legendValue?.value || 0; + setPercent(value ? (value - min) / (max - min) * 100 : 0); + setValueFormat(value ? `${value}%` : ""); + setMinFormat(`${min}%`); + setMaxFormat(`${max}%`); + }, [legendValue, min, max]); + + return ( +
+
+
+ {!!legendValue?.value && ( +
+ {valueFormat} +
+ )} +
+
{minFormat}
+
{maxFormat}
+
+ {series[1] && ( + + )} +
+ ); +}; + +export default LegendHeatmap; diff --git a/app/vmui/packages/vmui/src/components/Chart/LegendHeatmap/style.scss b/app/vmui/packages/vmui/src/components/Chart/Heatmap/LegendHeatmap/style.scss similarity index 86% rename from app/vmui/packages/vmui/src/components/Chart/LegendHeatmap/style.scss rename to app/vmui/packages/vmui/src/components/Chart/Heatmap/LegendHeatmap/style.scss index acba34f2b..359dda224 100644 --- a/app/vmui/packages/vmui/src/components/Chart/LegendHeatmap/style.scss +++ b/app/vmui/packages/vmui/src/components/Chart/Heatmap/LegendHeatmap/style.scss @@ -7,6 +7,14 @@ justify-content: space-between; gap: 4px; + &__wrapper { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: $padding-global; + flex-wrap: wrap; + } + &__value { color: $color-text; font-size: $font-size-small; @@ -52,4 +60,8 @@ } } } + + &__labels { + word-break: break-all; + } } diff --git a/app/vmui/packages/vmui/src/components/Chart/LegendHeatmap/LegendHeatmap.tsx b/app/vmui/packages/vmui/src/components/Chart/LegendHeatmap/LegendHeatmap.tsx deleted file mode 100644 index 4747331c6..000000000 --- a/app/vmui/packages/vmui/src/components/Chart/LegendHeatmap/LegendHeatmap.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { FC, useEffect, useState } from "preact/compat"; -import { gradMetal16 } from "../../../utils/uplot/heatmap"; -import "./style.scss"; - -interface LegendHeatmapProps { - min: number - max: number - value?: number -} - -const LegendHeatmap: FC = ({ min, max, value }) => { - - const [percent, setPercent] = useState(0); - const [valueFormat, setValueFormat] = useState(""); - const [minFormat, setMinFormat] = useState(""); - const [maxFormat, setMaxFormat] = useState(""); - - useEffect(() => { - setPercent(value ? (value - min) / (max - min) * 100 : 0); - setValueFormat(value ? `${value}%` : ""); - setMinFormat(`${min}%`); - setMaxFormat(`${max}%`); - }, [value, min, max]); - - return ( -
-
- {!!value && ( -
- {valueFormat} -
- )} -
-
{minFormat}
-
{maxFormat}
-
- ); -}; - -export default LegendHeatmap; diff --git a/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/ChartTooltip.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx similarity index 93% rename from app/vmui/packages/vmui/src/components/Chart/ChartTooltip/ChartTooltip.tsx rename to app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx index d69a99da7..23c2a434a 100644 --- a/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/ChartTooltip.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx @@ -1,17 +1,17 @@ import React, { FC, useEffect, useMemo, useRef, useState } from "preact/compat"; import uPlot from "uplot"; -import { MetricResult } from "../../../api/types"; -import { formatPrettyNumber } from "../../../utils/uplot/helpers"; +import { MetricResult } from "../../../../api/types"; +import { formatPrettyNumber } from "../../../../utils/uplot/helpers"; import dayjs from "dayjs"; -import { DATE_FULL_TIMEZONE_FORMAT } from "../../../constants/date"; +import { DATE_FULL_TIMEZONE_FORMAT } from "../../../../constants/date"; import ReactDOM from "react-dom"; import get from "lodash.get"; -import Button from "../../Main/Button/Button"; -import { CloseIcon, DragIcon } from "../../Main/Icons"; +import Button from "../../../Main/Button/Button"; +import { CloseIcon, DragIcon } from "../../../Main/Icons"; import classNames from "classnames"; import { MouseEvent as ReactMouseEvent } from "react"; import "./style.scss"; -import { SeriesItem } from "../../../utils/uplot/series"; +import { SeriesItem } from "../../../../utils/uplot/series"; export interface ChartTooltipProps { id: string, diff --git a/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/style.scss b/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/style.scss similarity index 98% rename from app/vmui/packages/vmui/src/components/Chart/ChartTooltip/style.scss rename to app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/style.scss index 891bd3125..e924130d5 100644 --- a/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/style.scss +++ b/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/style.scss @@ -78,5 +78,6 @@ $chart-tooltip-y: -1 * ($padding-small + $chart-tooltip-half-icon); display: grid; grid-gap: 4px; word-break: break-all; + white-space: pre-wrap; } } diff --git a/app/vmui/packages/vmui/src/components/Chart/Legend/Legend.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/Legend.tsx similarity index 92% rename from app/vmui/packages/vmui/src/components/Chart/Legend/Legend.tsx rename to app/vmui/packages/vmui/src/components/Chart/Line/Legend/Legend.tsx index 6cdc47632..9cdffff43 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Legend/Legend.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/Legend.tsx @@ -1,7 +1,7 @@ import React, { FC, useMemo } from "preact/compat"; -import { LegendItemType } from "../../../utils/uplot/types"; +import { LegendItemType } from "../../../../utils/uplot/types"; import LegendItem from "./LegendItem/LegendItem"; -import Accordion from "../../Main/Accordion/Accordion"; +import Accordion from "../../../Main/Accordion/Accordion"; import "./style.scss"; interface LegendProps { diff --git a/app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/LegendItem.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx similarity index 68% rename from app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/LegendItem.tsx rename to app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx index 813f5933c..ebc080825 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/LegendItem.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx @@ -1,19 +1,23 @@ import React, { FC, useState, useMemo } from "preact/compat"; import { MouseEvent } from "react"; -import { LegendItemType } from "../../../../utils/uplot/types"; +import { LegendItemType } from "../../../../../utils/uplot/types"; import "./style.scss"; import classNames from "classnames"; -import Tooltip from "../../../Main/Tooltip/Tooltip"; +import Tooltip from "../../../../Main/Tooltip/Tooltip"; import { getFreeFields } from "./helpers"; interface LegendItemProps { legend: LegendItemType; - onChange: (item: LegendItemType, metaKey: boolean) => void; + onChange?: (item: LegendItemType, metaKey: boolean) => void; + isHeatmap?: boolean; } -const LegendItem: FC = ({ legend, onChange }) => { +const LegendItem: FC = ({ legend, onChange, isHeatmap }) => { const [copiedValue, setCopiedValue] = useState(""); - const freeFormFields = useMemo(() => getFreeFields(legend), [legend]); + const freeFormFields = useMemo(() => { + const result = getFreeFields(legend); + return isHeatmap ? result.filter(f => f.key !== "vmrange") : result; + }, [legend, isHeatmap]); const calculations = legend.calculations; const showCalculations = Object.values(calculations).some(v => v); @@ -24,7 +28,7 @@ const LegendItem: FC = ({ legend, onChange }) => { }; const createHandlerClick = (legend: LegendItemType) => (e: MouseEvent) => { - onChange(legend, e.ctrlKey || e.metaKey); + onChange && onChange(legend, e.ctrlKey || e.metaKey); }; const createHandlerCopy = (freeField: string, id: string) => (e: MouseEvent) => { @@ -37,18 +41,21 @@ const LegendItem: FC = ({ legend, onChange }) => { className={classNames({ "vm-legend-item": true, "vm-legend-row": true, - "vm-legend-item_hide": !legend.checked, + "vm-legend-item_hide": !legend.checked && !isHeatmap, + "vm-legend-item_static": isHeatmap, })} onClick={createHandlerClick(legend)} > -
+ {!isHeatmap && ( +
+ )}
{legend.freeFormFields["__name__"]} - { + {!!freeFormFields.length && <>{} {freeFormFields.map((f, i) => ( = ({ legend, onChange }) => { ))} - } + {!!freeFormFields.length && <>}}
- {showCalculations && ( + {!isHeatmap && showCalculations && (
median:{calculations.median}, min:{calculations.min}, max:{calculations.max}, last:{calculations.last}
diff --git a/app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/helpers.ts b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/helpers.ts similarity index 84% rename from app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/helpers.ts rename to app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/helpers.ts index 53e6bed59..6fed3c686 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/helpers.ts +++ b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/helpers.ts @@ -1,4 +1,4 @@ -import { LegendItemType } from "../../../../utils/uplot/types"; +import { LegendItemType } from "../../../../../utils/uplot/types"; export const getFreeFields = (legend: LegendItemType) => { const keys = Object.keys(legend.freeFormFields).filter(f => f !== "__name__"); diff --git a/app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/style.scss b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/style.scss similarity index 84% rename from app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/style.scss rename to app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/style.scss index 4e32bc26f..7c5e2ed1b 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Legend/LegendItem/style.scss +++ b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/style.scss @@ -21,6 +21,17 @@ opacity: 0.5; } + &_static { + grid-template-columns: 1fr; + margin: 0; + padding: 0; + cursor: default; + + &:hover { + background-color: $color-background-block; + } + } + &__marker { width: 14px; height: 14px; diff --git a/app/vmui/packages/vmui/src/components/Chart/Legend/style.scss b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/style.scss similarity index 100% rename from app/vmui/packages/vmui/src/components/Chart/Legend/style.scss rename to app/vmui/packages/vmui/src/components/Chart/Line/Legend/style.scss diff --git a/app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx similarity index 94% rename from app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx rename to app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx index f3e41ac55..7fab79c11 100644 --- a/app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx @@ -7,22 +7,22 @@ import uPlot, { Scales, Scale, } from "uplot"; -import { defaultOptions } from "../../../utils/uplot/helpers"; -import { dragChart } from "../../../utils/uplot/events"; -import { getAxes, getMinMaxBuffer } from "../../../utils/uplot/axes"; -import { MetricResult } from "../../../api/types"; -import { dateFromSeconds, formatDateForNativeInput, limitsDurations } from "../../../utils/time"; +import { defaultOptions } from "../../../../utils/uplot/helpers"; +import { dragChart } from "../../../../utils/uplot/events"; +import { getAxes, getMinMaxBuffer } from "../../../../utils/uplot/axes"; +import { MetricResult } from "../../../../api/types"; +import { dateFromSeconds, formatDateForNativeInput, limitsDurations } from "../../../../utils/time"; import throttle from "lodash.throttle"; -import useResize from "../../../hooks/useResize"; -import { TimeParams } from "../../../types"; -import { YaxisState } from "../../../state/graph/reducer"; +import useResize from "../../../../hooks/useResize"; +import { TimeParams } from "../../../../types"; +import { YaxisState } from "../../../../state/graph/reducer"; import "uplot/dist/uPlot.min.css"; import "./style.scss"; import classNames from "classnames"; import ChartTooltip, { ChartTooltipProps } from "../ChartTooltip/ChartTooltip"; import dayjs from "dayjs"; -import { useAppState } from "../../../state/common/StateContext"; -import { SeriesItem } from "../../../utils/uplot/series"; +import { useAppState } from "../../../../state/common/StateContext"; +import { SeriesItem } from "../../../../utils/uplot/series"; export interface LineChartProps { metrics: MetricResult[]; diff --git a/app/vmui/packages/vmui/src/components/Chart/LineChart/style.scss b/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/style.scss similarity index 100% rename from app/vmui/packages/vmui/src/components/Chart/LineChart/style.scss rename to app/vmui/packages/vmui/src/components/Chart/Line/LineChart/style.scss diff --git a/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx b/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx index d5d6165f1..cdd95003d 100644 --- a/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx +++ b/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx @@ -1,10 +1,10 @@ import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat"; import { MetricResult } from "../../../api/types"; -import LineChart from "../../Chart/LineChart/LineChart"; +import LineChart from "../../Chart/Line/LineChart/LineChart"; import { AlignedData as uPlotData, Series as uPlotSeries } from "uplot"; -import Legend from "../../Chart/Legend/Legend"; -import LegendHeatmap from "../../Chart/LegendHeatmap/LegendHeatmap"; -import { getHideSeries, getLegendItem, getSeriesItemContext } from "../../../utils/uplot/series"; +import Legend from "../../Chart/Line/Legend/Legend"; +import LegendHeatmap from "../../Chart/Heatmap/LegendHeatmap/LegendHeatmap"; +import { getHideSeries, getLegendItem, getSeriesItemContext, SeriesItem } from "../../../utils/uplot/series"; import { getLimitsYAxis, getMinMaxBuffer, getTimeSeries } from "../../../utils/uplot/axes"; import { LegendItemType } from "../../../utils/uplot/types"; import { TimeParams } from "../../../types"; @@ -12,11 +12,12 @@ import { AxisRange, YaxisState } from "../../../state/graph/reducer"; import { getAvgFromArray, getMaxFromArray, getMinFromArray } from "../../../utils/math"; import classNames from "classnames"; import { useTimeState } from "../../../state/time/TimeStateContext"; -import HeatmapChart from "../../Chart/HeatmapChart/HeatmapChart"; +import HeatmapChart from "../../Chart/Heatmap/HeatmapChart/HeatmapChart"; import "./style.scss"; import { promValueToNumber } from "../../../utils/metric"; import { normalizeData } from "../../../utils/uplot/heatmap"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import { TooltipHeatmapProps } from "../../Chart/Heatmap/ChartTooltipHeatmap/ChartTooltipHeatmap"; export interface GraphViewProps { data?: MetricResult[]; @@ -60,7 +61,7 @@ const GraphView: FC = ({ const [series, setSeries] = useState([]); const [legend, setLegend] = useState([]); const [hideSeries, setHideSeries] = useState([]); - const [legendValue, setLegendValue] = useState(0); + const [legendValue, setLegendValue] = useState(null); const setLimitsYaxis = (values: {[key: string]: number[]}) => { const limits = getLimitsYAxis(values, !isHistogram); @@ -71,7 +72,7 @@ const GraphView: FC = ({ setHideSeries(getHideSeries({ hideSeries, legend, metaKey, series })); }; - const handleChangeLegend = (val: number) => { + const handleChangeLegend = (val: TooltipHeatmapProps) => { setLegendValue(val); }; @@ -209,9 +210,10 @@ const GraphView: FC = ({ )} {isHistogram && showLegend && ( )}
diff --git a/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts b/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts index 5c9dcf2c5..9fdb97a55 100644 --- a/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts +++ b/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts @@ -79,7 +79,7 @@ export const useFetchQuery = ({ setFetchQueue([...fetchQueue, controller]); try { const isDisplayChart = displayType === "chart"; - const seriesLimit = showAllSeries ? Infinity : (+stateSeriesLimits[displayType] || Infinity); + let seriesLimit = showAllSeries ? Infinity : (+stateSeriesLimits[displayType] || Infinity); const tempData: MetricBase[] = []; const tempTraces: Trace[] = []; let counter = 1; @@ -104,6 +104,8 @@ export const useFetchQuery = ({ tempTraces.push(trace); } + const isHistogramResult = isDisplayChart && isHistogramData(resp.data.result); + if (isHistogramResult) seriesLimit = Infinity; const freeTempSize = seriesLimit - tempData.length; resp.data.result.slice(0, freeTempSize).forEach((d: MetricBase) => { d.group = counter; diff --git a/app/vmui/packages/vmui/src/utils/metric.ts b/app/vmui/packages/vmui/src/utils/metric.ts index f24e47e7d..90ec03ab9 100644 --- a/app/vmui/packages/vmui/src/utils/metric.ts +++ b/app/vmui/packages/vmui/src/utils/metric.ts @@ -31,14 +31,13 @@ export const promValueToNumber = (s: string): number => { export const isHistogramData = (result: MetricBase[]) => { if (result.length < 2) return false; - const histogramNames = ["le", "vmrange"]; + const histogramLabels = ["le", "vmrange"]; - return result.every(r => { - const keys = Object.keys(r.metric); - const labels = Object.keys(r.metric).filter(n => !histogramNames.includes(n)); - const byName = keys.length > labels.length; - const byLabels = labels.every(l => r.metric[l] === result[0].metric[l]); - - return byName && byLabels; + const firstLabels = Object.keys(result[0].metric).filter(n => !histogramLabels.includes(n)); + const isHistogram = result.every(r => { + const labels = Object.keys(r.metric).filter(n => !histogramLabels.includes(n)); + return firstLabels.length === labels.length && labels.every(l => r.metric[l] === result[0].metric[l]); }); + + return isHistogram && result.every(r => histogramLabels.some(l => l in r.metric)); }; diff --git a/app/vmui/packages/vmui/src/utils/uplot/heatmap.ts b/app/vmui/packages/vmui/src/utils/uplot/heatmap.ts index bae189d3a..fbe8f1e77 100644 --- a/app/vmui/packages/vmui/src/utils/uplot/heatmap.ts +++ b/app/vmui/packages/vmui/src/utils/uplot/heatmap.ts @@ -1,6 +1,7 @@ import uPlot from "uplot"; import { generateGradient } from "../color"; import { MetricResult } from "../../api/types"; +import { promValueToNumber } from "../metric"; // 16-color gradient from "rgb(246, 226, 219)" to "rgb(127, 39, 4)" export const gradMetal16 = generateGradient([246, 226, 219], [127, 39, 4], 16); @@ -115,11 +116,11 @@ export const convertPrometheusToVictoriaMetrics = (buckets: MetricResult[]): Met const sortedBuckets = buckets.sort((a,b) => parseFloat(a.metric.le) - parseFloat(b.metric.le)); const group = buckets[0]?.group || 1; - let prevBucket: MetricResult = { metric: { le: "0" }, values: [], group }; + let prevBucket: MetricResult = { metric: { le: "" }, values: [], group }; const result: MetricResult[] = []; for (const bucket of sortedBuckets) { - const vmrange = `${prevBucket.metric.le}..${bucket.metric.le}`; + const vmrange = [prevBucket.metric.le, bucket.metric.le].filter(n => n).join("..."); const values: [number, string][] = []; for (const [timestamp, value] of bucket.values) { @@ -135,14 +136,25 @@ export const convertPrometheusToVictoriaMetrics = (buckets: MetricResult[]): Met return result; }; +const getUpperBound = (bucket: MetricResult) => { + const values = (bucket.metric.vmrange || bucket.metric.le).split("..."); + return promValueToNumber(values[values.length - 1]); +}; + +const sortBucketsByValues = (a: MetricResult, b: MetricResult) => getUpperBound(a) - getUpperBound(b); + export const normalizeData = (buckets: MetricResult[], isHistogram?: boolean): MetricResult[] => { if (!isHistogram) return buckets; - const vmBuckets = convertPrometheusToVictoriaMetrics(buckets); + const sortedBuckets = buckets.sort(sortBucketsByValues); + const vmBuckets = convertPrometheusToVictoriaMetrics(sortedBuckets); const allValues = vmBuckets.map(b => b.values).flat(); return vmBuckets.map(bucket => { const values = bucket.values.map((v) => { - const totalHits = allValues.filter(av => av[0] === v[0]).reduce((bucketSum, v) => bucketSum + +v[1], 0); + const totalHits = allValues + .filter(av => av[0] === v[0]) + .reduce((bucketSum, v) => bucketSum + +v[1], 0); + return [v[0], `${Math.round((+v[1] / totalHits) * 100)}`]; }); From 4b2cc1b32c39b69aa5935a8884c4619156f880ef Mon Sep 17 00:00:00 2001 From: Zakhar Bessarab Date: Thu, 6 Apr 2023 09:16:39 +0400 Subject: [PATCH 16/27] docs: fix example operator spec for vmbackupmanager restore usage (#4074) Signed-off-by: Zakhar Bessarab --- docs/vmbackupmanager.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/vmbackupmanager.md b/docs/vmbackupmanager.md index e4e7ea78c..34c43c98d 100644 --- a/docs/vmbackupmanager.md +++ b/docs/vmbackupmanager.md @@ -279,7 +279,8 @@ If restore mark doesn't exist at `storageDataPath`(restore wasn't requested) `vm ```yaml vmbackup: restore: - onStart: "true" + onStart: + enabled: "true" ``` See operator `VMStorage` schema [here](https://docs.victoriametrics.com/operator/api.html#vmstorage) and `VMSingle` [here](https://docs.victoriametrics.com/operator/api.html#vmsinglespec). 2. Enter container running `vmbackupmanager` @@ -309,7 +310,8 @@ Clusters here are referred to as `source` and `destination`. ```yaml vmbackup: restore: - onStart: "true" + onStart: + enabled: "true" ``` Note: it is safe to leave this section in the cluster configuration, since it will be ignored if restore mark doesn't exist. > Important! Use different `-dst` for *destination* cluster to avoid overwriting backup data of the *source* cluster. From a1601929ec12ff27e5d2a654ee930762a8071ca8 Mon Sep 17 00:00:00 2001 From: Yury Molodov Date: Thu, 6 Apr 2023 07:19:36 +0200 Subject: [PATCH 17/27] fix: correct the description of shortcut keys (#4057) --- .../Chart/GraphTips/contants/tips.tsx | 7 +- .../Main/ShortcutKeys/ShortcutKeys.tsx | 114 +++++------------- .../Main/ShortcutKeys/constants/keyList.tsx | 62 ++++++++++ .../components/Main/ShortcutKeys/style.scss | 19 ++- 4 files changed, 111 insertions(+), 91 deletions(-) create mode 100644 app/vmui/packages/vmui/src/components/Main/ShortcutKeys/constants/keyList.tsx diff --git a/app/vmui/packages/vmui/src/components/Chart/GraphTips/contants/tips.tsx b/app/vmui/packages/vmui/src/components/Chart/GraphTips/contants/tips.tsx index bf096b91c..6957d3f8c 100644 --- a/app/vmui/packages/vmui/src/components/Chart/GraphTips/contants/tips.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/GraphTips/contants/tips.tsx @@ -51,15 +51,16 @@ const legendTips = [ }, { - title: "Copy key-value pairs", + title: "Copy label key-value pairs", description: <> - click on a key-value pair to save it to the clipboard. + click on a label key-value pair to save it to the clipboard. }, { title: "Collapse/Expand the legend group", description: <> - click on the group name (e.g. Query 1: {name!=""}) to collapse or expand the legend. + click on the group name (e.g. Query 1: {__name__!=""}) + to collapse or expand the legend. }, ]; diff --git a/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx b/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx index 1f2f589f2..3da26c034 100644 --- a/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx +++ b/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx @@ -1,77 +1,18 @@ -import React, { FC, useState } from "preact/compat"; -import { isMacOs } from "../../../utils/detect-device"; +import React, { FC, useEffect, useState } from "preact/compat"; import { getAppModeEnable } from "../../../utils/app-mode"; import Button from "../Button/Button"; import { KeyboardIcon } from "../Icons"; import Modal from "../Modal/Modal"; import "./style.scss"; import Tooltip from "../Tooltip/Tooltip"; - -const ctrlMeta = isMacOs() ? "Cmd" : "Ctrl"; - -const keyList = [ - { - title: "Query", - list: [ - { - keys: ["Enter"], - description: "Run" - }, - { - keys: ["Shift", "Enter"], - description: "Multi-line queries" - }, - { - keys: [ctrlMeta, "Arrow Up"], - description: "Previous command from the Query history" - }, - { - keys: [ctrlMeta, "Arrow Down"], - description: "Next command from the Query history" - }, - { - keys: [ctrlMeta, "Click by 'Eye'"], - description: "Toggle multiple queries" - } - ] - }, - { - title: "Graph", - list: [ - { - keys: [ctrlMeta, "Scroll Up"], - alt: ["+"], - description: "Zoom in" - }, - { - keys: [ctrlMeta, "Scroll Down"], - alt: ["-"], - description: "Zoom out" - }, - { - keys: [ctrlMeta, "Click and Drag"], - description: "Move the graph left/right" - }, - ] - }, - { - title: "Legend", - list: [ - { - keys: ["Mouse Click"], - description: "Select series" - }, - { - keys: [ctrlMeta, "Mouse Click"], - description: "Toggle multiple series" - } - ] - } -]; +import keyList from "./constants/keyList"; +import { isMacOs } from "../../../utils/detect-device"; const title = "Shortcut keys"; +const isMac = isMacOs(); +const keyOpenHelp = isMac ? "Cmd + /" : "F1"; -const ShortcutKeys: FC<{showTitle?: boolean}> = ({ showTitle }) => { +const ShortcutKeys: FC<{ showTitle?: boolean }> = ({ showTitle }) => { const [openList, setOpenList] = useState(false); const appModeEnable = getAppModeEnable(); @@ -83,10 +24,26 @@ const ShortcutKeys: FC<{showTitle?: boolean}> = ({ showTitle }) => { setOpenList(false); }; + const handleKeyDown = (e: KeyboardEvent) => { + const openOnMac = isMac && e.key === "/" && e.metaKey; + const openOnOther = !isMac && e.key === "F1" && !e.metaKey; + if (openOnMac || openOnOther) { + handleOpen(); + } + }; + + useEffect(() => { + window.addEventListener("keydown", handleKeyDown); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, []); + return <>