From 2aa8c8669ea7ecedb4f9ff09a49178c89217d51b Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 20 Oct 2014 13:51:39 +0100 Subject: [PATCH] Make query_range more robust. Gracefully handle decimal values, by truncating them. Limit amount of steps, to avoid accidentally pulling too much data. This limit returns up to ~500kB per timeseries, and allows for 60s granularity for a week and 1h granularity for a year. Change-Id: Ie549fc24deb2eecbc6c5d1b6088a548a6b02e849 --- web/api/query.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/web/api/query.go b/web/api/query.go index 043359ed4..aeca5cd6e 100644 --- a/web/api/query.go +++ b/web/api/query.go @@ -77,9 +77,14 @@ func (serv MetricsService) QueryRange(w http.ResponseWriter, r *http.Request) { params := http_utils.GetQueryParams(r) expr := params.Get("expr") - end, _ := strconv.ParseInt(params.Get("end"), 0, 64) - duration, _ := strconv.ParseInt(params.Get("range"), 0, 64) - step, _ := strconv.ParseInt(params.Get("step"), 0, 64) + + // Gracefully handle decimal input, by truncating it. + endFloat, _ := strconv.ParseFloat(params.Get("end"), 64) + durationFloat, _ := strconv.ParseFloat(params.Get("range"), 64) + stepFloat, _ := strconv.ParseFloat(params.Get("step"), 64) + end := int64(endFloat) + duration := int64(durationFloat) + step := int64(stepFloat) exprNode, err := rules.LoadExprFromString(expr) if err != nil { @@ -103,6 +108,13 @@ func (serv MetricsService) QueryRange(w http.ResponseWriter, r *http.Request) { duration = end } + // For safety, limit the number of returned points per timeseries. + // This is sufficient for 60s resolution for a week or 1h resolution for a year. + if duration/step > 11000 { + fmt.Fprint(w, ast.ErrorToJSON(errors.New("Exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)."))) + return + } + // Align the start to step "tick" boundary. end -= end % step