@@ -5,13 +5,19 @@ import (
5
5
"encoding/gob"
6
6
"errors"
7
7
"fmt"
8
- "io/ioutil "
8
+ "io"
9
9
"net/http"
10
10
"strconv"
11
11
"strings"
12
12
"time"
13
13
14
14
"github.com/ansel1/merry"
15
+ pb "github.com/go-graphite/protocol/carbonapi_v3_pb"
16
+ "github.com/lomik/zapwriter"
17
+ "github.com/msaf1980/go-stringutils"
18
+ uuid "github.com/satori/go.uuid"
19
+ "go.uber.org/zap"
20
+
15
21
"github.com/go-graphite/carbonapi/carbonapipb"
16
22
"github.com/go-graphite/carbonapi/cmd/carbonapi/config"
17
23
"github.com/go-graphite/carbonapi/date"
@@ -21,11 +27,6 @@ import (
21
27
"github.com/go-graphite/carbonapi/pkg/parser"
22
28
utilctx "github.com/go-graphite/carbonapi/util/ctx"
23
29
"github.com/go-graphite/carbonapi/zipper/helper"
24
- pb "github.com/go-graphite/protocol/carbonapi_v3_pb"
25
- "github.com/lomik/zapwriter"
26
- stringutils "github.com/msaf1980/go-stringutils"
27
- uuid "github.com/satori/go.uuid"
28
- "go.uber.org/zap"
29
30
)
30
31
31
32
func cleanupParams (r * http.Request ) {
@@ -205,7 +206,7 @@ func renderHandler(w http.ResponseWriter, r *http.Request) {
205
206
}
206
207
207
208
if format == protoV3Format {
208
- body , err := ioutil .ReadAll (r .Body )
209
+ body , err := io .ReadAll (r .Body )
209
210
if err != nil {
210
211
accessLogDetails .HTTPCode = http .StatusBadRequest
211
212
accessLogDetails .Reason = "failed to parse message body: " + err .Error ()
@@ -291,23 +292,46 @@ func renderHandler(w http.ResponseWriter, r *http.Request) {
291
292
results = make ([]* types.MetricData , 0 )
292
293
values := make (map [parser.MetricRequest ][]* types.MetricData )
293
294
294
- for _ , target := range targets {
295
- exp , e , err := parser .ParseExpr (target )
296
- if err != nil || e != "" {
297
- msg := buildParseErrorString (target , e , err )
298
- setError (w , accessLogDetails , msg , http .StatusBadRequest , uid .String ())
299
- logAsError = true
300
- return
295
+ if config .Config .CombineMultipleTargetsInOne && len (targets ) > 0 {
296
+ exprs := make ([]parser.Expr , 0 , len (targets ))
297
+ for _ , target := range targets {
298
+ exp , e , err := parser .ParseExpr (target )
299
+ if err != nil || e != "" {
300
+ msg := buildParseErrorString (target , e , err )
301
+ setError (w , accessLogDetails , msg , http .StatusBadRequest , uid .String ())
302
+ logAsError = true
303
+ return
304
+ }
305
+ exprs = append (exprs , exp )
301
306
}
302
307
303
308
ApiMetrics .RenderRequests .Add (1 )
304
309
305
- result , err := expr .FetchAndEvalExp (ctx , exp , from32 , until32 , values )
306
- if err != nil {
307
- errors [ target ] = merry . Wrap ( err )
310
+ result , errs := expr .FetchAndEvalExprs (ctx , exprs , from32 , until32 , values )
311
+ if errs != nil {
312
+ errors = errs
308
313
}
309
314
310
315
results = append (results , result ... )
316
+ } else {
317
+ for _ , target := range targets {
318
+ exp , e , err := parser .ParseExpr (target )
319
+ if err != nil || e != "" {
320
+ msg := buildParseErrorString (target , e , err )
321
+ setError (w , accessLogDetails , msg , http .StatusBadRequest , uid .String ())
322
+ logAsError = true
323
+ return
324
+ }
325
+
326
+ ApiMetrics .RenderRequests .Add (1 )
327
+
328
+ result , err := expr .FetchAndEvalExp (ctx , exp , from32 , until32 , values )
329
+ if err != nil {
330
+ errors [target ] = merry .Wrap (err )
331
+ }
332
+
333
+ results = append (results , result ... )
334
+ }
311
335
}
312
336
313
337
for mFetch := range values {
0 commit comments