From 1c0e0652169ebfdafa6b8b1fac67933d0debf216 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 30 Aug 2023 14:33:38 +0200 Subject: [PATCH] app/vmselect/promql: add support for `_` delimiters in numeric values For example, 1_234_567_890 is equivalent to 1234567890, while 1.234_567_890 is equivalent to 1.234567890 --- app/vmselect/promql/exec_test.go | 33 +++++++++++++++++++ docs/CHANGELOG.md | 1 + docs/MetricsQL.md | 1 + go.mod | 2 +- go.sum | 4 +-- .../VictoriaMetrics/metricsql/lexer.go | 8 +++-- vendor/modules.txt | 2 +- 7 files changed, 45 insertions(+), 6 deletions(-) diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index b39887bea..90d31e349 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -86,6 +86,28 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run("int_with_underscores", func(t *testing.T) { + t.Parallel() + q := `123_456_789` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{123456789, 123456789, 123456789, 123456789, 123456789, 123456789}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) + t.Run("float_with_underscores", func(t *testing.T) { + t.Parallel() + q := `1_2.3_456_789` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{12.3456789, 12.3456789, 12.3456789, 12.3456789, 12.3456789, 12.3456789}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run("duration-constant", func(t *testing.T) { t.Parallel() q := `1h23m5S` @@ -141,6 +163,17 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run("num-with-suffix-5", func(t *testing.T) { + t.Parallel() + q := `1_234M` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{1234e6, 1234e6, 1234e6, 1234e6, 1234e6, 1234e6}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run("simple-arithmetic", func(t *testing.T) { t.Parallel() q := `-1+2 *3 ^ 4+5%6` diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1d8dcd013..2a7f84154 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -24,6 +24,7 @@ The following `tip` changes can be tested by building VictoriaMetrics components ## tip +* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add support for numbers with underscore delimiters such as `1_234_567_890` and `1.234_567_890`. These numbers are easier to read than `1234567890` and `1.234567890`. * FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): add support for server-side copy of existing backups. See [these docs](https://docs.victoriametrics.com/vmbackup.html#server-side-copy-of-the-existing-backup) for details. * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add ability to set `member num` label for all the metrics scraped by a particular `vmagent` instance in [a cluster of vmagents](https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets) via `-promscrape.cluster.memberLabel` command-line flag. See [these docs](https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets) and [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4247). * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): do not log `unexpected EOF` when reading incoming metrics, since this error is expected and is handled during metrics' parsing. This reduces the amounts of noisy logs. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4817). diff --git a/docs/MetricsQL.md b/docs/MetricsQL.md index e5106fe6c..81df16782 100644 --- a/docs/MetricsQL.md +++ b/docs/MetricsQL.md @@ -67,6 +67,7 @@ The list of MetricsQL features on top of PromQL: depending on the current step used for building the graph (e.g. `step` query arg passed to [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query)). For instance, the following query is valid in VictoriaMetrics: `rate(node_network_receive_bytes_total)`. It is equivalent to `rate(node_network_receive_bytes_total[$__interval])` when used in Grafana. +* Numeric values can contain `_` delimiters for better readability. For example, `1_234_567_890` can be used in queries instead of `1234567890`. * [Series selectors](https://docs.victoriametrics.com/keyConcepts.html#filtering) accept multiple `or` filters. For example, `{env="prod",job="a" or env="dev",job="b"}` selects series with either `{env="prod",job="a"}` or `{env="dev",job="b"}` labels. See [these docs](https://docs.victoriametrics.com/keyConcepts.html#filtering-by-multiple-or-filters) for details. diff --git a/go.mod b/go.mod index 7b256e6c3..4b4181414 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( // like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b github.com/VictoriaMetrics/fasthttp v1.2.0 github.com/VictoriaMetrics/metrics v1.24.0 - github.com/VictoriaMetrics/metricsql v0.63.0 + github.com/VictoriaMetrics/metricsql v0.64.0 github.com/aws/aws-sdk-go-v2 v1.21.0 github.com/aws/aws-sdk-go-v2/config v1.18.37 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.81 diff --git a/go.sum b/go.sum index fbfd2b688..bdba8f831 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/VictoriaMetrics/fasthttp v1.2.0 h1:nd9Wng4DlNtaI27WlYh5mGXCJOmee/2c2b github.com/VictoriaMetrics/fasthttp v1.2.0/go.mod h1:zv5YSmasAoSyv8sBVexfArzFDIGGTN4TfCKAtAw7IfE= github.com/VictoriaMetrics/metrics v1.24.0 h1:ILavebReOjYctAGY5QU2F9X0MYvkcrG3aEn2RKa1Zkw= github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys= -github.com/VictoriaMetrics/metricsql v0.63.0 h1:RRu3lln7uhQwSRkzAknOUyB0uP9LwymFMHnzDqGbZ40= -github.com/VictoriaMetrics/metricsql v0.63.0/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I= +github.com/VictoriaMetrics/metricsql v0.64.0 h1:uty6AXQFY3OpQ+eopo1jDjCcTctuqkqYLnRbQVhukW8= +github.com/VictoriaMetrics/metricsql v0.64.0/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= diff --git a/vendor/github.com/VictoriaMetrics/metricsql/lexer.go b/vendor/github.com/VictoriaMetrics/metricsql/lexer.go index f0a2a3466..da6a47e68 100644 --- a/vendor/github.com/VictoriaMetrics/metricsql/lexer.go +++ b/vendor/github.com/VictoriaMetrics/metricsql/lexer.go @@ -233,7 +233,7 @@ func scanPositiveNumber(s string) (string, error) { } return s[:i], nil } - for i < len(s) && isDecimalChar(s[i]) { + for i < len(s) && isDecimalCharOrUnderscore(s[i]) { i++ } @@ -258,7 +258,7 @@ func scanPositiveNumber(s string) (string, error) { // Scan fractional part. It cannot be empty. i++ j := i - for j < len(s) && isDecimalChar(s[j]) { + for j < len(s) && isDecimalCharOrUnderscore(s[j]) { j++ } i = j @@ -673,6 +673,10 @@ func isDecimalChar(ch byte) bool { return ch >= '0' && ch <= '9' } +func isDecimalCharOrUnderscore(ch byte) bool { + return isDecimalChar(ch) || ch == '_' +} + func isHexChar(ch byte) bool { return isDecimalChar(ch) || ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F' } diff --git a/vendor/modules.txt b/vendor/modules.txt index c95f6db45..29b1bdb91 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -99,7 +99,7 @@ github.com/VictoriaMetrics/fasthttp/stackless # github.com/VictoriaMetrics/metrics v1.24.0 ## explicit; go 1.20 github.com/VictoriaMetrics/metrics -# github.com/VictoriaMetrics/metricsql v0.63.0 +# github.com/VictoriaMetrics/metricsql v0.64.0 ## explicit; go 1.13 github.com/VictoriaMetrics/metricsql github.com/VictoriaMetrics/metricsql/binaryop