Add /api/v1/format_query API endpoint for formatting queries (#11036)

* Add /api/v1/format_query API endpoint for formatting queries

This uses the formatting functionality introduced in
https://github.com/prometheus/prometheus/pull/10544.

I've chosen "query" instead of "expr" in both the endpoint and parameter
names to stay consistent with the existing API endpoints. Otherwise, I
would have preferred to use the term "expr".

Signed-off-by: Julius Volz <julius.volz@gmail.com>

* Add docs for /api/v1/format_query endpoint

Signed-off-by: Julius Volz <julius.volz@gmail.com>

* Add note that formatting expressions removes comments

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2022-07-20 14:55:09 +02:00 committed by GitHub
parent d61459d826
commit b57deb6eb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 0 deletions

View file

@ -206,6 +206,35 @@ $ curl 'http://localhost:9090/api/v1/query_range?query=up&start=2015-07-01T20:10
}
```
## Formatting query expressions
The following endpoint formats a PromQL expression in a prettified way:
```
GET /api/v1/format_query
POST /api/v1/format_query
```
URL query parameters:
- `query=<string>`: Prometheus expression query string.
You can URL-encode these parameters directly in the request body by using the `POST` method and
`Content-Type: application/x-www-form-urlencoded` header. This is useful when specifying a large
query that may breach server-side URL character limits.
The `data` section of the query result is a string containing the formatted query expression. Note that any comments are removed in the formatted string.
The following example formats the expression `foo/bar`:
```json
$ curl 'http://localhost:9090/api/v1/format_query?query=foo/bar'
{
"status" : "success",
"data" : "foo / bar"
}
```
## Querying metadata
Prometheus offers a set of API endpoints to query metadata about series and their labels.

View file

@ -323,6 +323,9 @@ func (api *API) Register(r *route.Router) {
r.Get("/query_exemplars", wrapAgent(api.queryExemplars))
r.Post("/query_exemplars", wrapAgent(api.queryExemplars))
r.Get("/format_query", wrapAgent(api.formatQuery))
r.Post("/format_query", wrapAgent(api.formatQuery))
r.Get("/labels", wrapAgent(api.labelNames))
r.Post("/labels", wrapAgent(api.labelNames))
r.Get("/label/:name/values", wrapAgent(api.labelValues))
@ -428,6 +431,15 @@ func (api *API) query(r *http.Request) (result apiFuncResult) {
}, nil, res.Warnings, qry.Close}
}
func (api *API) formatQuery(r *http.Request) (result apiFuncResult) {
expr, err := parser.ParseExpr(r.FormValue("query"))
if err != nil {
return invalidParamError(err, "query")
}
return apiFuncResult{expr.Pretty(0), nil, nil, nil}
}
func extractQueryOpts(r *http.Request) *promql.QueryOpts {
return &promql.QueryOpts{
EnablePerStepStats: r.FormValue("stats") == "all",

View file

@ -930,6 +930,20 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, es storage.E
},
errType: errorBadData,
},
{
endpoint: api.formatQuery,
query: url.Values{
"query": []string{"foo+bar"},
},
response: "foo + bar",
},
{
endpoint: api.formatQuery,
query: url.Values{
"query": []string{"invalid_expression/"},
},
errType: errorBadData,
},
{
endpoint: api.series,
query: url.Values{