Fix v1 label API to be Prometheus-compatible (#1322)

The label and label values API will now return the expected form
of:

```json
{
  "status": "success",
  "data": [
    "label1",
    "label2",
    "labeln"
  ]
}
```
pull/1326/head
Robert Fratto 6 years ago committed by GitHub
parent 715f215c50
commit 822e94fe6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 86
      docs/api.md
  2. 2
      pkg/logcli/labelquery/labels.go
  3. 3
      pkg/loghttp/labels.go
  4. 4
      pkg/logql/marshal/legacy/marshal_test.go
  5. 22
      pkg/logql/marshal/marshal.go
  6. 2
      pkg/logql/marshal/marshal_test.go

@ -14,6 +14,8 @@ The HTTP API includes the following endpoints:
- [`POST /loki/api/v1/push`](#post-lokiapiv1push)
- [`GET /api/prom/tail`](#get-apipromtail)
- [`GET /api/prom/query`](#get-apipromquery)
- [`GET /api/prom/label`](#get-apipromlabel)
- [`GET /api/prom/label/<name>/values`](#get-apipromlabelnamevalues)
- [`POST /api/prom/push`](#post-apiprompush)
- [`GET /ready`](#get-ready)
- [`POST /flush`](#post-flush)
@ -38,6 +40,8 @@ These endpoints are exposed by just the querier:
- [`GET /loki/api/v1/tail`](#get-lokiapiv1tail)
- [`GET /api/prom/tail`](#get-lokiapipromtail)
- [`GET /api/prom/query`](#get-apipromquery)
- [`GET /api/prom/label`](#get-apipromlabel)
- [`GET /api/prom/label/<name>/values`](#get-apipromlabelnamevalues)
While these endpoints are exposed by just the distributor:
@ -348,7 +352,8 @@ Response:
```
{
"values": [
"status": "success",
"data": [
<label string>,
...
]
@ -360,7 +365,8 @@ Response:
```bash
$ curl -G -s "http://localhost:3100/loki/api/v1/label" | jq
{
"values": [
"status": "success",
"data": [
"foo",
"bar",
"baz"
@ -383,7 +389,8 @@ Response:
```
{
"values": [
"status": "success",
"data": [
<label value>,
...
]
@ -395,7 +402,8 @@ Response:
```bash
$ curl -G -s "http://localhost:3100/loki/api/v1/label/foo/values" | jq
{
"values": [
"status": "success",
"data": [
"cat",
"dog",
"axolotl"
@ -597,11 +605,77 @@ $ curl -G -s "http://localhost:3100/api/prom/query" --data-urlencode '{foo="bar
}
```
## `GET /api/prom/label`
> **WARNING**: `/api/prom/label` is DEPRECATED; use `/loki/api/v1/label`
`/api/prom/label` retrieves the list of known labels within a given time span. It
accepts the following query parameters in the URL:
- `start`: The start time for the query as a nanosecond Unix epoch. Defaults to 6 hours ago.
- `end`: The start time for the query as a nanosecond Unix epoch. Defaults to now.
In microservices mode, `/api/prom/label` is exposed by the querier.
Response:
```
{
"values": [
<label string>,
...
]
}
```
### Examples
```bash
$ curl -H "Content-Type: application/json" -XPOST -s "https://localhost:3100/loki/api/v1/push" --data-raw \
'{"streams": [{ "labels": "{foo=\"bar\"}", "entries": [{ "ts": "2018-12-18T08:28:06.801064-04:00", "line": "fizzbuzz" }] }]}'
$ curl -G -s "http://localhost:3100/api/prom/label" | jq
{
"values": [
"foo",
"bar",
"baz"
]
}
```
## `GET /api/prom/label/<name>/values`
> **WARNING**: `/api/prom/label/<name>/values` is DEPRECATED; use `/loki/api/v1/label/<name>/values`
`/api/prom/label/<name>/values` retrieves the list of known values for a given
label within a given time span. It accepts the following query parameters in
the URL:
- `start`: The start time for the query as a nanosecond Unix epoch. Defaults to 6 hours ago.
- `end`: The start time for the query as a nanosecond Unix epoch. Defaults to now.
In microservices mode, `/api/prom/label/<name>/values` is exposed by the querier.
Response:
```
{
"values": [
<label value>,
...
]
}
```
### Examples
```bash
$ curl -G -s "http://localhost:3100/api/prom/label/foo/values" | jq
{
"values": [
"cat",
"dog",
"axolotl"
]
}
```
## `POST /api/prom/push`

@ -35,5 +35,5 @@ func (q *LabelQuery) ListLabels(c *client.Client) []string {
if err != nil {
log.Fatalf("Error doing request: %+v", err)
}
return labelResponse.Values
return labelResponse.Data
}

@ -12,7 +12,8 @@ import (
// LabelResponse represents the http json response to a label query
type LabelResponse struct {
Values []string `json:"values,omitempty"`
Status string `json:"status"`
Data []string `json:"data,omitempty"`
}
// LabelSet is a key/value pair mapping of labels

@ -37,7 +37,7 @@ var queryTests = []struct {
"entries":[
{
"ts": "2019-09-13T18:32:22.380001319Z",
"line": "super line"
"line": "super line"
}
]
}
@ -95,7 +95,7 @@ var tailTests = []struct {
"entries": [
{
"ts": "2019-09-13T18:32:22.380001319Z",
"line": "super line"
"line": "super line"
}
]
}

@ -1,5 +1,5 @@
// Package marshal converts internal objects to loghttp model objects. This package is designed to work with
// models in pkg/loghttp.
// Package marshal converts internal objects to loghttp model objects. This
// package is designed to work with models in pkg/loghttp.
package marshal
import (
@ -14,7 +14,8 @@ import (
"github.com/prometheus/prometheus/promql"
)
// WriteQueryResponseJSON marshals the promql.Value to v1 loghttp JSON and then writes it to the provided io.Writer
// WriteQueryResponseJSON marshals the promql.Value to v1 loghttp JSON and then
// writes it to the provided io.Writer.
func WriteQueryResponseJSON(v promql.Value, w io.Writer) error {
value, err := NewResultValue(v)
@ -34,14 +35,19 @@ func WriteQueryResponseJSON(v promql.Value, w io.Writer) error {
return json.NewEncoder(w).Encode(q)
}
// WriteLabelResponseJSON marshals a logproto.LabelResponse to v1 loghttp JSON and then writes it to the provided io.Writer
// Note that it simply directly marshals the value passed in. This is because the label currently marshals
// cleanly to the v1 http protocol. If this ever changes, it will be caught by testing.
// WriteLabelResponseJSON marshals a logproto.LabelResponse to v1 loghttp JSON
// and then writes it to the provided io.Writer.
func WriteLabelResponseJSON(l logproto.LabelResponse, w io.Writer) error {
return json.NewEncoder(w).Encode(l)
v1Response := loghttp.LabelResponse{
Status: "success",
Data: l.GetValues(),
}
return json.NewEncoder(w).Encode(v1Response)
}
// WriteTailResponseJSON marshals the legacy.TailResponse to v1 loghttp JSON and then writes it to the provided connection
// WriteTailResponseJSON marshals the legacy.TailResponse to v1 loghttp JSON and
// then writes it to the provided connection.
func WriteTailResponseJSON(r legacy.TailResponse, c *websocket.Conn) error {
v1Response, err := NewTailResponse(r)

@ -212,7 +212,7 @@ var labelTests = []struct {
"value",
},
},
`{"values": ["label1", "test", "value"]}`,
`{"status": "success", "data": ["label1", "test", "value"]}`,
},
}

Loading…
Cancel
Save