Skip to content

Commit 9299649

Browse files
authored
Add bytes fetched in query frontend (#37)
2 parents ca8da96 + b6336d8 commit 9299649

File tree

4 files changed

+88
-8
lines changed

4 files changed

+88
-8
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) The Cortex Authors.
2+
// Licensed under the Apache License 2.0.
3+
4+
package queryrange
5+
6+
import (
7+
"strconv"
8+
)
9+
10+
// QueryBytesFetchedHeaderName is the http header name of number of bytes fetched by a query from m3readcoord.
11+
// This name is compatible with M3 and rule manager code
12+
const QueryBytesFetchedHeaderName = "M3-Fetched-Bytes-Estimate"
13+
14+
func sumQueryBytesFetched(responses ...Response) uint64 {
15+
var result uint64
16+
result = 0
17+
for _, resp := range responses {
18+
for _, hdr := range resp.GetHeaders() {
19+
if hdr.GetName() == QueryBytesFetchedHeaderName {
20+
for _, v := range hdr.GetValues() {
21+
n, err := strconv.ParseUint(v, 10, 64)
22+
if err != nil {
23+
continue
24+
}
25+
result += n
26+
}
27+
break
28+
}
29+
}
30+
}
31+
return result
32+
}
33+
34+
func QueryBytesFetchedPrometheusResponseHeaders(responses ...Response) []*PrometheusResponseHeader {
35+
n := sumQueryBytesFetched(responses...)
36+
if n == 0 {
37+
return nil
38+
}
39+
return []*PrometheusResponseHeader{{
40+
Name: QueryBytesFetchedHeaderName,
41+
Values: []string{strconv.FormatUint(n, 10)},
42+
}}
43+
}
44+
45+
func QueryBytesFetchedHttpHeaderValue(response Response) []string {
46+
var result []string
47+
for _, hdr := range response.GetHeaders() {
48+
if hdr.GetName() == QueryBytesFetchedHeaderName {
49+
result = hdr.GetValues()
50+
break
51+
}
52+
}
53+
return result
54+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) The Cortex Authors.
2+
// Licensed under the Apache License 2.0.
3+
4+
package queryrange
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestQueryBytesFetchedPrometheusResponseHeaders(t *testing.T) {
13+
resp1 := PrometheusResponse{Headers: []*PrometheusResponseHeader{&PrometheusResponseHeader{Name: "M3-Fetched-Bytes-Estimate", Values: []string{"100"}}}}
14+
resp2 := PrometheusResponse{Headers: []*PrometheusResponseHeader{&PrometheusResponseHeader{Name: "M3-Fetched-Bytes-Estimate", Values: []string{"1000"}}}}
15+
resp3 := PrometheusResponse{}
16+
hdrs := QueryBytesFetchedPrometheusResponseHeaders(&resp1, &resp2, &resp3)
17+
expected := []*PrometheusResponseHeader{{Name: QueryBytesFetchedHeaderName,
18+
Values: []string{"1100"}}}
19+
require.Equal(t, hdrs, expected)
20+
}

internal/cortex/querier/queryrange/query_range.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"context"
99
stdjson "encoding/json"
1010
"fmt"
11-
io "io"
11+
"io"
1212
"math"
1313
"net/http"
1414
"net/url"
@@ -278,12 +278,12 @@ func (prometheusCodec) MergeResponse(_ Request, responses ...Response) (Response
278278
Analysis: AnalyzesMerge(analyzes...),
279279
},
280280
}
281-
281+
response.Headers = QueryBytesFetchedPrometheusResponseHeaders(responses...)
282282
if len(resultsCacheGenNumberHeaderValues) != 0 {
283-
response.Headers = []*PrometheusResponseHeader{{
283+
response.Headers = append(response.Headers, &PrometheusResponseHeader{
284284
Name: ResultsCacheGenNumberHeaderName,
285285
Values: resultsCacheGenNumberHeaderValues,
286-
}}
286+
})
287287
}
288288

289289
return &response, nil
@@ -447,10 +447,13 @@ func (prometheusCodec) EncodeResponse(ctx context.Context, res Response) (*http.
447447

448448
sp.LogFields(otlog.Int("bytes", len(b)))
449449

450+
httpHeader := http.Header{
451+
"Content-Type": []string{"application/json"}}
452+
if queryBytesFetchedHttpHeaderValue := QueryBytesFetchedHttpHeaderValue(res); queryBytesFetchedHttpHeaderValue != nil {
453+
httpHeader[QueryBytesFetchedHeaderName] = queryBytesFetchedHttpHeaderValue
454+
}
450455
resp := http.Response{
451-
Header: http.Header{
452-
"Content-Type": []string{"application/json"},
453-
},
456+
Header: httpHeader,
454457
Body: io.NopCloser(bytes.NewBuffer(b)),
455458
StatusCode: http.StatusOK,
456459
ContentLength: int64(len(b)),

pkg/queryfrontend/queryinstant_codec.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ func (c queryInstantCodec) MergeResponse(req queryrange.Request, responses ...qu
7878
Analysis: queryrange.AnalyzesMerge(analyzes...),
7979
Stats: queryrange.StatsMerge(responses),
8080
},
81+
Headers: queryrange.QueryBytesFetchedPrometheusResponseHeaders(responses...),
8182
}
8283
default:
8384
v, err := vectorMerge(req, promResponses)
@@ -96,6 +97,7 @@ func (c queryInstantCodec) MergeResponse(req queryrange.Request, responses ...qu
9697
Analysis: queryrange.AnalyzesMerge(analyzes...),
9798
Stats: queryrange.StatsMerge(responses),
9899
},
100+
Headers: queryrange.QueryBytesFetchedPrometheusResponseHeaders(responses...),
99101
}
100102
}
101103

@@ -248,7 +250,8 @@ func (c queryInstantCodec) EncodeResponse(ctx context.Context, res queryrange.Re
248250

249251
resp := http.Response{
250252
Header: http.Header{
251-
"Content-Type": []string{"application/json"},
253+
"Content-Type": []string{"application/json"},
254+
queryrange.QueryBytesFetchedHeaderName: queryrange.QueryBytesFetchedHttpHeaderValue(res),
252255
},
253256
Body: io.NopCloser(bytes.NewBuffer(b)),
254257
StatusCode: http.StatusOK,

0 commit comments

Comments
 (0)