Skip to content

Commit

Permalink
Make Loki HTTP API more similar to Prometheus
Browse files Browse the repository at this point in the history
  • Loading branch information
cyriltovena authored and Ed Welch committed Sep 11, 2019
1 parent 2508dc1 commit 364b5bc
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 102 deletions.
210 changes: 115 additions & 95 deletions docs/loki/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o

```json
{
"resultType": "vector" | "streams",
"result": <value>
"status" : "success",
"data": {
"resultType": "vector" | "streams",
"result": <value>
}
}
```

Expand All @@ -50,56 +53,63 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o
```bash
$ curl -G -s "http://localhost:3100/api/v1/query" --data-urlencode 'query=sum(rate({job="varlogs"}[10m])) by (level)' | jq
{
"resultType": "vector",
"result": [
{
"metric": {},
"value": [
1559848867745737,
"1267.1266666666666"
]
},
{
"metric": {
"level": "warn"
"status" : "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {},
"value": [
1559848867745737,
"1267.1266666666666"
]
},
"value": [
1559848867745737,
"37.77166666666667"
]
},
{
"metric": {
"level": "info"
{
"metric": {
"level": "warn"
},
"value": [
1559848867745737,
"37.77166666666667"
]
},
"value": [
1559848867745737,
"37.69"
]
}
]
{
"metric": {
"level": "info"
},
"value": [
1559848867745737,
"37.69"
]
}
]
}
}
```

```bash
curl -G -s "http://localhost:3100/api/v1/query" --data-urlencode 'query={job="varlogs"}' | jq
{
"resultType": "streams",
"result": [
{
"labels": "{filename=\"/var/log/myproject.log\", job=\"varlogs\", level=\"info\"}",
"entries": [
"status" : "success",
"data": {
"resultType": "streams",
"result": [
{
"ts": "2019-06-06T19:25:41.972739Z",
"line": "foo"
},
{
"ts": "2019-06-06T19:25:41.972722Z",
"line": "bar"
"labels": "{filename=\"/var/log/myproject.log\", job=\"varlogs\", level=\"info\"}",
"entries": [
{
"ts": "2019-06-06T19:25:41.972739Z",
"line": "foo"
},
{
"ts": "2019-06-06T19:25:41.972722Z",
"line": "bar"
}
]
}
]
}
]
}
```

- `GET /api/v1/query_range`
Expand All @@ -121,8 +131,11 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o

```json
{
"resultType": "matrix" | "streams",
"result": <value>
"status" : "success",
"data": {
"resultType": "matrix" | "streams",
"result": <value>
}
}
```

Expand All @@ -131,69 +144,76 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o
```bash
$ curl -G -s "http://localhost:3100/api/v1/query_range" --data-urlencode 'query=sum(rate({job="varlogs"}[10m])) by (level)' --data-urlencode 'step=300' | jq
{
"resultType": "matrix",
"result": [
{
"metric": {
"level": "info"
},
"values": [
[
1559848958663735,
"137.95"
],
[
1559849258663735,
"467.115"
],
[
1559849558663735,
"658.8516666666667"
]
]
},
"status" : "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"level": "warn"
"level": "info"
},
"values": [
[
1559848958663735,
"137.95"
],
[
1559849258663735,
"467.115"
],
[
1559849558663735,
"658.8516666666667"
]
]
},
"values": [
[
1559848958663735,
"137.27833333333334"
],
[
1559849258663735,
"467.69"
],
[
1559849558663735,
"660.6933333333334"
{
"metric": {
"level": "warn"
},
"values": [
[
1559848958663735,
"137.27833333333334"
],
[
1559849258663735,
"467.69"
],
[
1559849558663735,
"660.6933333333334"
]
]
]
}
]
}
]
}
}
```

```bash
curl -G -s "http://localhost:3100/api/v1/query_range" --data-urlencode 'query={job="varlogs"}' | jq
{
"resultType": "streams",
"result": [
{
"labels": "{filename=\"/var/log/myproject.log\", job=\"varlogs\", level=\"info\"}",
"entries": [
{
"ts": "2019-06-06T19:25:41.972739Z",
"line": "foo"
},
{
"ts": "2019-06-06T19:25:41.972722Z",
"line": "bar"
}
]
}
]
"status" : "success",
"data": {
"resultType": "streams",
"result": [
{
"labels": "{filename=\"/var/log/myproject.log\", job=\"varlogs\", level=\"info\"}",
"entries": [
{
"ts": "2019-06-06T19:25:41.972739Z",
"line": "foo"
},
{
"ts": "2019-06-06T19:25:41.972722Z",
"line": "bar"
}
]
}
]
}
}
```

- `GET /api/prom/query`
Expand Down
7 changes: 7 additions & 0 deletions pkg/logql/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ func (ng *Engine) exec(ctx context.Context, q *query) (promql.Value, error) {
ctx, cancel := context.WithTimeout(ctx, ng.timeout)
defer cancel()

if q.qs == "1+1" {
if q.isInstant() {
return promql.Vector{}, nil
}
return promql.Matrix{}, nil
}

expr, err := ParseExpr(q.qs)
if err != nil {
return nil, err
Expand Down
30 changes: 23 additions & 7 deletions pkg/querier/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"math"
"net/http"
"net/url"
"strconv"
Expand Down Expand Up @@ -46,14 +47,23 @@ func unixNanoTimeParam(values url.Values, name string, def time.Time) (time.Time
return def, nil
}

if strings.Contains(value, ".") {
if t, err := strconv.ParseFloat(value, 64); err == nil {
s, ns := math.Modf(t)
ns = math.Round(ns*1000) / 1000
return time.Unix(int64(s), int64(ns*float64(time.Second))), nil
}
}
nanos, err := strconv.ParseInt(value, 10, 64)
if err != nil {
if ts, err := time.Parse(time.RFC3339Nano, value); err == nil {
return ts, nil
}
return time.Time{}, err
}

if len(value) <= 10 {
return time.Unix(nanos, 0), nil
}
return time.Unix(0, nanos), nil
}

Expand Down Expand Up @@ -219,9 +229,12 @@ func (q *Querier) RangeQueryHandler(w http.ResponseWriter, r *http.Request) {
return
}

response := &QueryResponse{
ResultType: result.Type(),
Result: result,
response := map[string]interface{}{
"status": "success",
"data": &QueryResponse{
ResultType: result.Type(),
Result: result,
},
}

if err := json.NewEncoder(w).Encode(response); err != nil {
Expand All @@ -248,9 +261,12 @@ func (q *Querier) InstantQueryHandler(w http.ResponseWriter, r *http.Request) {
return
}

response := &QueryResponse{
ResultType: result.Type(),
Result: result,
response := map[string]interface{}{
"status": "success",
"data": &QueryResponse{
ResultType: result.Type(),
Result: result,
},
}

if err := json.NewEncoder(w).Encode(response); err != nil {
Expand Down

0 comments on commit 364b5bc

Please sign in to comment.