Skip to content

Commit

Permalink
Improve API compatibility.
Browse files Browse the repository at this point in the history
- keep supporting regex for old endpoint.
- use reserved keyword for removed property in grpc
  • Loading branch information
cyriltovena committed Sep 4, 2019
1 parent 8272f08 commit 8f9cd97
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 79 deletions.
7 changes: 4 additions & 3 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o
For doing instant queries at a single point in time, accepts the following parameters in the query-string:

- `query`: a logQL query
- `limit`: max number of entries to return (not used for sample expression)
- `limit`: max number of entries to return (not used for metric queries)
- `time`: the evaluation time for the query, as a nanosecond Unix epoch (nanoseconds since 1970). Default is always now.
- `direction`: `forward` or `backward`, useful when specifying a limit. Default is backward.

Expand Down Expand Up @@ -107,7 +107,7 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o
For doing queries over a range of time, accepts the following parameters in the query-string:

- `query`: a logQL query
- `limit`: max number of entries to return (not used for sample expression)
- `limit`: max number of entries to return (not used for metric queries)
- `start`: the start time for the query, as a nanosecond Unix epoch (nanoseconds since 1970). Default is always one hour ago.
- `end`: the end time for the query, as a nanosecond Unix epoch (nanoseconds since 1970). Default is always now.
- `step`: query resolution step width in seconds. Default 1 second.
Expand Down Expand Up @@ -211,7 +211,8 @@ The Loki server has the following API endpoints (_Note:_ Authentication is out o
so you need to specify the start and end labels accordingly. Querying a long time into the history will cause additional
load to the index server and make the query slower.

> This endpoint doesn't accept [sample query](./usage.md#counting-logs).
> This endpoint will be deprecated in the future you should use `api/v1/query_range` instead.
> You can only query for logs, it doesn't accept [queries returning metrics](./usage.md#counting-logs).

Responses looks like this:

Expand Down
135 changes: 68 additions & 67 deletions pkg/logproto/logproto.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions pkg/logproto/logproto.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ message QueryRequest {
google.protobuf.Timestamp start = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
google.protobuf.Timestamp end = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
Direction direction = 5;
reserved 6;
}

enum Direction {
Expand Down Expand Up @@ -66,9 +67,10 @@ message Entry {

message TailRequest {
string query = 1;
uint32 delayFor = 2;
uint32 limit = 3;
google.protobuf.Timestamp start = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
reserved 2;
uint32 delayFor = 3;
uint32 limit = 4;
google.protobuf.Timestamp start = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}

message TailResponse {
Expand Down
2 changes: 1 addition & 1 deletion pkg/logql/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (e *filterExpr) Filter() (Filter, error) {
}

default:
return nil, fmt.Errorf("unknow matcher: %v", e.match)
return nil, fmt.Errorf("unknown matcher: %v", e.match)
}
next, ok := e.left.(*filterExpr)
if ok {
Expand Down
4 changes: 4 additions & 0 deletions pkg/loki/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,12 @@ func (t *Loki) initQuerier() (err error) {
t.httpAuthMiddleware,
)
t.server.HTTP.Path("/ready").Handler(http.HandlerFunc(t.querier.ReadinessHandler))

t.server.HTTP.Handle("/api/v1/query_range", httpMiddleware.Wrap(http.HandlerFunc(t.querier.RangeQueryHandler)))
t.server.HTTP.Handle("/api/v1/query", httpMiddleware.Wrap(http.HandlerFunc(t.querier.InstantQueryHandler)))
t.server.HTTP.Handle("/api/v1/label", httpMiddleware.Wrap(http.HandlerFunc(t.querier.LabelHandler)))
t.server.HTTP.Handle("/api/v1/label/{name}/values", httpMiddleware.Wrap(http.HandlerFunc(t.querier.LabelHandler)))

t.server.HTTP.Handle("/api/prom/query", httpMiddleware.Wrap(http.HandlerFunc(t.querier.LogQueryHandler)))
t.server.HTTP.Handle("/api/prom/label", httpMiddleware.Wrap(http.HandlerFunc(t.querier.LabelHandler)))
t.server.HTTP.Handle("/api/prom/label/{name}/values", httpMiddleware.Wrap(http.HandlerFunc(t.querier.LabelHandler)))
Expand Down
37 changes: 32 additions & 5 deletions pkg/querier/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@ import (
"strings"
"time"

"github.com/prometheus/prometheus/promql"
"github.com/weaveworks/common/httpgrpc/server"

"github.com/weaveworks/common/httpgrpc"

"github.com/cortexproject/cortex/pkg/util"
"github.com/go-kit/kit/log/level"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/prometheus/promql"
"github.com/weaveworks/common/httpgrpc"
"github.com/weaveworks/common/httpgrpc/server"
)

const (
Expand Down Expand Up @@ -166,6 +165,22 @@ func httpRequestToLookback(httpRequest *http.Request) (limit uint32, start, end
return
}

// parseRegexQuery parses regex and query querystring from httpRequest and returns the combined LogQL query.
// This is used only to keep regexp query string support until it gets fully deprecated.
func parseRegexQuery(httpRequest *http.Request) (string, error) {
params := httpRequest.URL.Query()
query := params.Get("query")
regexp := params.Get("regexp")
if regexp != "" {
expr, err := logql.ParseLogSelector(query)
if err != nil {
return "", err
}
query = logql.NewFilterExpr(expr, labels.MatchRegexp, regexp).String()
}
return query, nil
}

type QueryResponse struct {
ResultType promql.ValueType `json:"resultType"`
Result promql.Value `json:"result"`
Expand Down Expand Up @@ -255,6 +270,12 @@ func (q *Querier) LogQueryHandler(w http.ResponseWriter, r *http.Request) {
server.WriteError(w, err)
return
}
request.query, err = parseRegexQuery(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

query := q.engine.NewRangeQuery(q, request.query, request.start, request.end, request.step, request.direction, request.limit)
result, err := query.Exec(ctx)
if err != nil {
Expand Down Expand Up @@ -326,6 +347,12 @@ func (q *Querier) TailHandler(w http.ResponseWriter, r *http.Request) {
return
}

tailRequestPtr.Query, err = parseRegexQuery(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

if tailRequestPtr.DelayFor > maxDelayForInTailing {
server.WriteError(w, fmt.Errorf("delay_for can't be greater than %d", maxDelayForInTailing))
level.Error(util.Logger).Log("Error in upgrading websocket", fmt.Sprintf("%v", err))
Expand Down

0 comments on commit 8f9cd97

Please sign in to comment.