From 5efe377a26799210a3f974655a07af6b715a6c98 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 15 Dec 2021 23:37:05 +0200 Subject: [PATCH] app/vmselect/promql: add `timestamp_with_name(m[d])` function This function works the same as `timestamp()`, but doesn't remove source time series names. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/949#issuecomment-995222388 --- app/vmselect/promql/exec_test.go | 24 +++++++++++++++++++ app/vmselect/promql/rollup.go | 13 ++++++---- app/vmselect/promql/rollup_test.go | 1 + docs/CHANGELOG.md | 1 + docs/MetricsQL.md | 6 ++++- go.mod | 2 +- go.sum | 4 ++-- .../VictoriaMetrics/metricsql/rollup.go | 11 +++++---- vendor/modules.txt | 2 +- 9 files changed, 49 insertions(+), 15 deletions(-) diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index cfd76878a..b69cfbd87 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -593,6 +593,29 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run("timestamp(alias(time()>=1600))", func(t *testing.T) { + t.Parallel() + q := `timestamp(alias(time()>=1600,"foo"))` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{nan, nan, nan, 1600, 1800, 2000}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) + t.Run("timestamp_with_name(alias(time()>=1600))", func(t *testing.T) { + t.Parallel() + q := `timestamp_with_name(alias(time()>=1600,"foo"))` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{nan, nan, nan, 1600, 1800, 2000}, + Timestamps: timestampsExpected, + } + r.MetricName.MetricGroup = []byte("foo") + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run("time()/100", func(t *testing.T) { t.Parallel() q := `time()/100` @@ -7382,6 +7405,7 @@ func TestExecError(t *testing.T) { f(`sort_by_label()`) f(`sort_by_label_desc()`) f(`timestamp()`) + f(`timestamp_with_name()`) f(`vector()`) f(`histogram_quantile()`) f(`histogram_quantiles()`) diff --git a/app/vmselect/promql/rollup.go b/app/vmselect/promql/rollup.go index 2ef33f6e4..4d2c653a1 100644 --- a/app/vmselect/promql/rollup.go +++ b/app/vmselect/promql/rollup.go @@ -82,11 +82,12 @@ var rollupFuncs = map[string]newRollupFunc{ // `timestamp` function must return timestamp for the last datapoint on the current window // in order to properly handle offset and timestamps unaligned to the current step. // See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/415 for details. - "timestamp": newRollupFuncOneArg(rollupTlast), - "tlast_over_time": newRollupFuncOneArg(rollupTlast), - "tmax_over_time": newRollupFuncOneArg(rollupTmax), - "tmin_over_time": newRollupFuncOneArg(rollupTmin), - "zscore_over_time": newRollupFuncOneArg(rollupZScoreOverTime), + "timestamp": newRollupFuncOneArg(rollupTlast), + "timestamp_with_name": newRollupFuncOneArg(rollupTlast), // + rollupFuncsKeepMetricGroup + "tlast_over_time": newRollupFuncOneArg(rollupTlast), + "tmax_over_time": newRollupFuncOneArg(rollupTmax), + "tmin_over_time": newRollupFuncOneArg(rollupTmin), + "zscore_over_time": newRollupFuncOneArg(rollupZScoreOverTime), } // rollupAggrFuncs are functions that can be passed to `aggr_over_time()` @@ -130,6 +131,7 @@ var rollupAggrFuncs = map[string]rollupFunc{ "sum2_over_time": rollupSum2, "tfirst_over_time": rollupTfirst, "timestamp": rollupTlast, + "timestamp_with_name": rollupTlast, "tlast_over_time": rollupTlast, "tmax_over_time": rollupTmax, "tmin_over_time": rollupTmin, @@ -186,6 +188,7 @@ var rollupFuncsKeepMetricGroup = map[string]bool{ "quantiles_over_time": true, "rollup": true, "rollup_candlestick": true, + "timestamp_with_name": true, } func getRollupAggrFuncNames(expr metricsql.Expr) ([]string, error) { diff --git a/app/vmselect/promql/rollup_test.go b/app/vmselect/promql/rollup_test.go index e90ebd0eb..e0348dfd7 100644 --- a/app/vmselect/promql/rollup_test.go +++ b/app/vmselect/promql/rollup_test.go @@ -524,6 +524,7 @@ func TestRollupNewRollupFuncSuccess(t *testing.T) { f("descent_over_time", 231) f("zscore_over_time", -0.4254336383156416) f("timestamp", 0.13) + f("timestamp_with_name", 0.13) f("mode_over_time", 34) f("rate_over_sum", 4520) } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1e6bb7aec..9fa90e0e9 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,6 +16,7 @@ sort: 15 * FEATURE: vminsert: add `-maxLabelValueLen` command-line flag for the ability to configure the maximum length of label value. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1908). * FEATURE: preserve the order of time series passed to [limit_offset](https://docs.victoriametrics.com/MetricsQL.html#limit_offset) function. This allows implementing series paging via `limit_offset(limit, offset, sort_by_label(...))`. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1920) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/951) issues. * FEATURE: automaticall convert `(value1|...|valueN)` into `{value1,...,valueN}` inside `__graphite__` pseudo-label. This allows using [Grafana multi-value template variables](https://grafana.com/docs/grafana/latest/variables/formatting-multi-value-variables/) inside `__graphite__` pseudo-label. For example, `{__graphite__=~"foo.($bar)"}` is expanded to `{__graphite__=~"foo.{x,y}"}` if both `x` and `y` are selected for `$bar` template variable. See [these docs](https://docs.victoriametrics.com/#selecting-graphite-metrics) for details. +* FEATURE: add [timestamp_with_name](https://docs.victoriametrics.com/MetricsQL.html#timestamp_with_name) function. It works the same as [timestamp](https://docs.victoriametrics.com/MetricsQL.html#timestamp), but leaves the original time series names, so it can be used in queries, which match multiple time series names: `timestamp_with_name({foo="bar"}[1h])`. See [this comment](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/949#issuecomment-995222388) for more context. * BUGFIX: fix `unaligned 64-bit atomic operation` panic on 32-bit architectures, which has been introduced in v1.70.0. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1944). * BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): restore the ability to use `$labels.alertname` in labels templating. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1921). diff --git a/docs/MetricsQL.md b/docs/MetricsQL.md index fc4cae858..d84808b8b 100644 --- a/docs/MetricsQL.md +++ b/docs/MetricsQL.md @@ -316,7 +316,11 @@ See also [implicit query conversions](#implicit-query-conversions). #### timestamp -`timestamp(series_selector[d])` returns the timestamp in seconds for the last raw sample on the given lookbehind window `d` per each time series returned from the given [series_selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). Metric names are stripped from the resulting rollups. This function is supported by PromQL. +`timestamp(series_selector[d])` returns the timestamp in seconds for the last raw sample on the given lookbehind window `d` per each time series returned from the given [series_selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). Metric names are stripped from the resulting rollups. This function is supported by PromQL. See also [timestamp_with_name](#timestamp_with_name). + +#### timestamp_with_name + +`timestamp_with_name(series_selector[d])` returns the timestamp in seconds for the last raw sample on the given lookbehind window `d` per each time series returned from the given [series_selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors). Metric names are preserved in the resulting rollups. See also [timestamp](#timestamp). #### tfirst_over_time diff --git a/go.mod b/go.mod index 4332258fe..148205faf 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( // like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b github.com/VictoriaMetrics/fasthttp v1.1.0 github.com/VictoriaMetrics/metrics v1.18.1 - github.com/VictoriaMetrics/metricsql v0.32.0 + github.com/VictoriaMetrics/metricsql v0.33.0 github.com/VividCortex/ewma v1.2.0 // indirect github.com/aws/aws-sdk-go v1.42.22 github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect diff --git a/go.sum b/go.sum index c6e1c36ca..fdb41d91c 100644 --- a/go.sum +++ b/go.sum @@ -110,8 +110,8 @@ github.com/VictoriaMetrics/fasthttp v1.1.0/go.mod h1:/7DMcogqd+aaD3G3Hg5kFgoFwlR github.com/VictoriaMetrics/metrics v1.12.2/go.mod h1:Z1tSfPfngDn12bTfZSCqArT3OPY3u88J12hSoOhuiRE= github.com/VictoriaMetrics/metrics v1.18.1 h1:OZ0+kTTto8oPfHnVAnTOoyl0XlRhRkoQrD2n2cOuRw0= github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA= -github.com/VictoriaMetrics/metricsql v0.32.0 h1:yTZFB1FvbOsD5ahl6mxKYprHpZ248nVk3s8Kl7UBg5c= -github.com/VictoriaMetrics/metricsql v0.32.0/go.mod h1:ylO7YITho/Iw6P71oEaGyHbO94bGoGtzWfLGqFhMIg8= +github.com/VictoriaMetrics/metricsql v0.33.0 h1:UBj7+Tf4dhD47tIxMYfAiy/4GXJN6xPYTweCZ+sRqw0= +github.com/VictoriaMetrics/metricsql v0.33.0/go.mod h1:ylO7YITho/Iw6P71oEaGyHbO94bGoGtzWfLGqFhMIg8= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= diff --git a/vendor/github.com/VictoriaMetrics/metricsql/rollup.go b/vendor/github.com/VictoriaMetrics/metricsql/rollup.go index 7bd5a2a68..4887cf2db 100644 --- a/vendor/github.com/VictoriaMetrics/metricsql/rollup.go +++ b/vendor/github.com/VictoriaMetrics/metricsql/rollup.go @@ -68,11 +68,12 @@ var rollupFuncs = map[string]bool{ // `timestamp` function must return timestamp for the last datapoint on the current window // in order to properly handle offset and timestamps unaligned to the current step. // See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/415 for details. - "timestamp": true, - "tlast_over_time": true, - "tmax_over_time": true, - "tmin_over_time": true, - "zscore_over_time": true, + "timestamp": true, + "timestamp_with_name": true, + "tlast_over_time": true, + "tmax_over_time": true, + "tmin_over_time": true, + "zscore_over_time": true, } // IsRollupFunc returns whether funcName is known rollup function. diff --git a/vendor/modules.txt b/vendor/modules.txt index ba4e6b2f3..68812d3f9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -22,7 +22,7 @@ github.com/VictoriaMetrics/fasthttp/stackless # github.com/VictoriaMetrics/metrics v1.18.1 ## explicit github.com/VictoriaMetrics/metrics -# github.com/VictoriaMetrics/metricsql v0.32.0 +# github.com/VictoriaMetrics/metricsql v0.33.0 ## explicit github.com/VictoriaMetrics/metricsql github.com/VictoriaMetrics/metricsql/binaryop