VictoriaMetrics/app/vmselect/prometheus/expand-with-exprs.qtpl.go
Yury Molodov 68e31a6000
vmui: Integrate WITH template playground (#3831)
* feat: add WithTemplate page

* app/vmselect/prometheus: enable json mode for expand with expr API

* app/vmselect/prometheus: enable CORS and add content type

* feat: add api for expand with templates

* fix: remove console from useExpandWithExprs

* app/vmselect/prometheus: fix escaping

* vmui:  integrate WITH template

* app/vmctl: check content type instead of form param

* fix: add content-type for fetch with-exprs

* fix: add a header to the server's response that allows the "Content-Type" header

* app/vmctl: added comment and cleanup

* app/vmctl: use format query param

---------

Co-authored-by: dmitryk-dk <kozlovdmitriyy@gmail.com>
2023-04-25 11:40:01 +03:00

443 lines
15 KiB
Go

// Code generated by qtc from "expand-with-exprs.qtpl". DO NOT EDIT.
// See https://github.com/valyala/quicktemplate for details.
//line app/vmselect/prometheus/expand-with-exprs.qtpl:1
package prometheus
//line app/vmselect/prometheus/expand-with-exprs.qtpl:1
import (
"fmt"
"github.com/VictoriaMetrics/metricsql"
)
// ExpandWithExprsResponse returns a webpage, which expands with templates in q MetricsQL.
//line app/vmselect/prometheus/expand-with-exprs.qtpl:9
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:9
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:9
func StreamExpandWithExprsResponse(qw422016 *qt422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:9
qw422016.N().S(`<html><head><title>Expand WITH expressions</title><style>p { font-weight: bold }textarea { margin: 1em }</style></head><body><div><form method="get"><div><p><a href="https://docs.victoriametrics.com/MetricsQL.html">MetricsQL</a> query with optional WITH expressions:</p><textarea name="query" style="height: 15em; width: 90%">`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:26
qw422016.E().S(q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:26
qw422016.N().S(`</textarea><br/><input type="submit" value="Expand" /><p><a href="https://docs.victoriametrics.com/MetricsQL.html">MetricsQL</a> query after expanding WITH expressions and applying other optimizations:</p><textarea style="height: 5em; width: 90%" readonly="readonly">`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:32
streamexpandWithExprs(qw422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:32
qw422016.N().S(`</textarea></div></form></div><div>`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:37
streamwithExprsTutorial(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:37
qw422016.N().S(`</div></body></html>`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
func WriteExpandWithExprsResponse(qq422016 qtio422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
qw422016 := qt422016.AcquireWriter(qq422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
StreamExpandWithExprsResponse(qw422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
qt422016.ReleaseWriter(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
func ExpandWithExprsResponse(q string) string {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
qb422016 := qt422016.AcquireByteBuffer()
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
WriteExpandWithExprsResponse(qb422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
qs422016 := string(qb422016.B)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
qt422016.ReleaseByteBuffer(qb422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
return qs422016
//line app/vmselect/prometheus/expand-with-exprs.qtpl:41
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:43
func streamexpandWithExprs(qw422016 *qt422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:44
if len(q) == 0 {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:45
return
//line app/vmselect/prometheus/expand-with-exprs.qtpl:46
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:48
expr, err := metricsql.Parse(q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:49
if err != nil {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:49
qw422016.N().S(`Cannot parse query:`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:50
qw422016.E().V(err)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:51
} else {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:52
expr = metricsql.Optimize(expr)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:53
qw422016.E().Z(expr.AppendString(nil))
//line app/vmselect/prometheus/expand-with-exprs.qtpl:54
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
func writeexpandWithExprs(qq422016 qtio422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
qw422016 := qt422016.AcquireWriter(qq422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
streamexpandWithExprs(qw422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
qt422016.ReleaseWriter(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
func expandWithExprs(q string) string {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
qb422016 := qt422016.AcquireByteBuffer()
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
writeexpandWithExprs(qb422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
qs422016 := string(qb422016.B)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
qt422016.ReleaseByteBuffer(qb422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
return qs422016
//line app/vmselect/prometheus/expand-with-exprs.qtpl:55
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:59
func streamwithExprsTutorial(qw422016 *qt422016.Writer) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:59
qw422016.N().S(`
<h3>Tutorial for WITH expressions in <a href="https://docs.victoriametrics.com/MetricsQL.html">MetricsQL</a></h3>
<p>
Let's look at the following real query from <a href="https://grafana.com/grafana/dashboards/1860-node-exporter-full/">Node Exporter Full</a> dashboard:
</p>
<pre>
(
(
node_memory_MemTotal_bytes{instance=~"$node:$port", job=~"$job"}
-
node_memory_MemFree_bytes{instance=~"$node:$port", job=~"$job"}
)
/
node_memory_MemTotal_bytes{instance=~"$node:$port", job=~"$job"}
)
*
100
</pre>
<p>
It is clear the query calculates the percentage of used memory
for the given $node, $port and $job. Isn't it? :)
</p>
<p>
What's wrong with this query? Copy-pasted label filters for distinct timeseries
which makes it easy to mistype these filters during modification.
Let's simplify the query with WITH expressions:
</p>
<pre>
WITH (
commonFilters = {instance=~"$node:$port",job=~"$job"}
)
(
node_memory_MemTotal_bytes{commonFilters}
-
node_memory_MemFree_bytes{commonFilters}
)
/
node_memory_MemTotal_bytes{commonFilters} * 100
</pre>
<p>
Now label filters are located in a single place instead of three distinct places.
The query mentions node_memory_MemTotal_bytes metric twice and {commonFilters}
three times. WITH expressions may improve this:
</p>
<pre>
WITH (
my_resource_utilization(free, limit, filters) = (limit{filters} - free{filters}) / limit{filters} * 100
)
my_resource_utilization(
node_memory_MemFree_bytes,
node_memory_MemTotal_bytes,
{instance=~"$node:$port",job=~"$job"},
)
</pre>
<p>
Now the template function my_resource_utilization() may be used for monitoring arbitrary
resources - memory, CPU, network, storage, you name it.
</p>
<p>
Let's take another nice query from <a href="https://grafana.com/grafana/dashboards/1860-node-exporter-full/">Node Exporter Full</a> dashboard:
</p>
<pre>
(
(
(
count(
count(node_cpu_seconds_total{instance=~"$node:$port",job=~"$job"}) by (cpu)
)
)
-
avg(
sum by (mode) (rate(node_cpu_seconds_total{mode='idle',instance=~"$node:$port",job=~"$job"}[5m]))
)
)
*
100
)
/
count(
count(node_cpu_seconds_total{instance=~"$node:$port",job=~"$job"}) by (cpu)
)
</pre>
<p>
Do you understand what does this mess do? Is it manageable? :) WITH expressions are happy to help in a few iterations.
<br/>
<br/>
1. Extract common filters used in multiple places into a commonFilters variable:
</p>
<pre>
WITH (
commonFilters = {instance=~"$node:$port",job=~"$job"}
)
(
(
(
count(
count(node_cpu_seconds_total{commonFilters}) by (cpu)
)
)
-
avg(
sum by (mode) (rate(node_cpu_seconds_total{mode='idle',commonFilters}[5m]))
)
)
*
100
)
/
count(
count(node_cpu_seconds_total{commonFilters}) by (cpu)
)
</pre>
<p>
2. Extract "count(count(...) by (cpu))" into cpuCount variable:
</p>
<pre>
WITH (
commonFilters = {instance=~"$node:$port",job=~"$job"},
cpuCount = count(count(node_cpu_seconds_total{commonFilters}) by (cpu))
)
(
(
cpuCount
-
avg(
sum by (mode) (rate(node_cpu_seconds_total{mode='idle',commonFilters}[5m]))
)
)
*
100
) / cpuCount
</pre>
<p>
3. Extract rate(...) part into cpuIdle variable, since it is clear now that this part calculates the number of idle CPUs:
</p>
<pre>
WITH (
commonFilters = {instance=~"$node:$port",job=~"$job"},
cpuCount = count(count(node_cpu_seconds_total{commonFilters}) by (cpu)),
cpuIdle = sum(rate(node_cpu_seconds_total{mode='idle',commonFilters}[5m]))
)
((cpuCount - cpuIdle) * 100) / cpuCount
</pre>
<p>
4. Put node_cpu_seconds_total{commonFilters} into its own varialbe with the name cpuSeconds:
</p>
<pre>
WITH (
cpuSeconds = node_cpu_seconds_total{instance=~"$node:$port",job=~"$job"},
cpuCount = count(count(cpuSeconds) by (cpu)),
cpuIdle = sum(rate(cpuSeconds{mode='idle'}[5m]))
)
((cpuCount - cpuIdle) * 100) / cpuCount
</pre>
<p>
Now the query became more clear comparing to the initial query.
</p>
<p>
WITH expressions may be nested and may be put anywhere. Try expanding the following query:
</p>
<pre>
WITH (
f(a, b) = WITH (
f1(x) = b-x,
f2(x) = x+x
) f1(a)*f2(b)
) f(foo, with(x=bar) x)
</pre>
`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
func writewithExprsTutorial(qq422016 qtio422016.Writer) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
qw422016 := qt422016.AcquireWriter(qq422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
streamwithExprsTutorial(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
qt422016.ReleaseWriter(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
func withExprsTutorial() string {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
qb422016 := qt422016.AcquireByteBuffer()
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
writewithExprsTutorial(qb422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
qs422016 := string(qb422016.B)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
qt422016.ReleaseByteBuffer(qb422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
return qs422016
//line app/vmselect/prometheus/expand-with-exprs.qtpl:246
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:249
func StreamExpandWithExprsJSONResponse(qw422016 *qt422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:250
streamexpandWithExprsJSON(qw422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
func WriteExpandWithExprsJSONResponse(qq422016 qtio422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
qw422016 := qt422016.AcquireWriter(qq422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
StreamExpandWithExprsJSONResponse(qw422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
qt422016.ReleaseWriter(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
func ExpandWithExprsJSONResponse(q string) string {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
qb422016 := qt422016.AcquireByteBuffer()
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
WriteExpandWithExprsJSONResponse(qb422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
qs422016 := string(qb422016.B)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
qt422016.ReleaseByteBuffer(qb422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
return qs422016
//line app/vmselect/prometheus/expand-with-exprs.qtpl:251
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:253
func streamexpandWithExprsJSON(qw422016 *qt422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:254
if len(q) == 0 {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:254
qw422016.N().S(`{"status": "error","error": "query string cannot be empty"}`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:259
return
//line app/vmselect/prometheus/expand-with-exprs.qtpl:260
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:260
qw422016.N().S(`{`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:263
expr, err := metricsql.Parse(q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:264
if err != nil {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:264
qw422016.N().S(`"status": "error","error":`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:266
qw422016.N().Q(fmt.Sprintf("Cannot parse query: %s", err))
//line app/vmselect/prometheus/expand-with-exprs.qtpl:267
} else {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:268
expr = metricsql.Optimize(expr)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:268
qw422016.N().S(`"status": "success","expr":`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:270
qw422016.N().Q(string(expr.AppendString(nil)))
//line app/vmselect/prometheus/expand-with-exprs.qtpl:271
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:271
qw422016.N().S(`}`)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
func writeexpandWithExprsJSON(qq422016 qtio422016.Writer, q string) {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
qw422016 := qt422016.AcquireWriter(qq422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
streamexpandWithExprsJSON(qw422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
qt422016.ReleaseWriter(qw422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
}
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
func expandWithExprsJSON(q string) string {
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
qb422016 := qt422016.AcquireByteBuffer()
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
writeexpandWithExprsJSON(qb422016, q)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
qs422016 := string(qb422016.B)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
qt422016.ReleaseByteBuffer(qb422016)
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
return qs422016
//line app/vmselect/prometheus/expand-with-exprs.qtpl:273
}