// GetPlots retrieves time series data from origin based on a query and a time interval. func (c *FacetteConnector) GetPlots(query *plot.Query) ([]*plot.Series, error) { var results []*plot.Series // Convert plotQuery into plotRequest-like to forward query to upstream Facette API plotReq := facettePlotRequest{ Time: query.StartTime, Range: utils.DurationToRange(query.EndTime.Sub(query.StartTime)), Sample: query.Sample, Graph: library.Graph{ Item: library.Item{ Name: "facette", }, Groups: []*library.OperGroup{ &library.OperGroup{ Name: "group0", Series: func(series []plot.QuerySeries) []*library.Series { out := make([]*library.Series, len(series)) for i, s := range series { out[i] = &library.Series{ Name: fmt.Sprintf("series%d", i), Origin: s.Origin, Source: s.Source, Metric: s.Metric, } } return out }(query.Series), }, }, }, } body, err := json.Marshal(plotReq) if err != nil { return nil, fmt.Errorf("facette[%s]: unable to marshal plot request: %s", c.name, err) } client := utils.NewHTTPClient(c.timeout, c.insecureTLS) r, err := http.NewRequest("POST", strings.TrimSuffix(c.upstream, "/")+facetteURLPlots, bytes.NewReader(body)) if err != nil { return nil, fmt.Errorf("facette[%s]: unable to set up HTTP request: %s", c.name, err) } r.Header.Add("Content-Type", "application/json") r.Header.Add("User-Agent", "Facette") r.Header.Add("X-Requested-With", "FacetteConnector") if query.Requestor != "" { r.Header.Add("X-Facette-Requestor", query.Requestor) } else { r.Header.Add("X-Facette-Requestor", c.serverID) } rsp, err := client.Do(r) if err != nil { return nil, fmt.Errorf("facette[%s]: unable to perform HTTP request: %s", c.name, err) } if err := facetteCheckConnectorResponse(rsp); err != nil { return nil, fmt.Errorf("facette[%s]: invalid upstream HTTP response: %s", c.name, err) } data, err := ioutil.ReadAll(rsp.Body) if err != nil { return nil, fmt.Errorf("facette[%s]: unable to read HTTP response body: %s", c.name, err) } defer rsp.Body.Close() plotRsp := facettePlotResponse{} if err := json.Unmarshal(data, &plotRsp); err != nil { return nil, fmt.Errorf("facette[%s]: unable to unmarshal upstream response: %s", c.name, err) } for _, s := range plotRsp.Series { results = append(results, &plot.Series{ Plots: s.Plots, Summary: s.Summary, }) } return results, nil }
// GetPlots retrieves time series data from origin based on a query and a time interval. func (connector *FacetteConnector) GetPlots(query *types.PlotQuery) ([]*types.PlotResult, error) { // Convert plotQuery into plotRequest-like to forward query to upstream Facette API plotRequest := facettePlotRequest{ Time: query.StartTime, Range: utils.DurationToRange(query.EndTime.Sub(query.StartTime)), Graph: library.Graph{ Item: library.Item{ Name: "facette", }, Groups: []*library.OperGroup{ &library.OperGroup{ Name: "group0", Type: query.Group.Type, Series: func(series []*types.SerieQuery) []*library.Serie { requestSeries := make([]*library.Serie, len(series)) for index, serie := range series { requestSeries[index] = &library.Serie{ Name: fmt.Sprintf("serie%d", index), Origin: serie.Metric.Origin, Source: serie.Metric.Source, Metric: serie.Metric.Name, Scale: serie.Scale, } } return requestSeries }(query.Group.Series), Scale: query.Group.Scale, }, }, }, } if query.Step != 0 { plotRequest.Sample = int((query.EndTime.Sub(query.StartTime) / query.Step).Seconds()) } requestBody, err := json.Marshal(plotRequest) if err != nil { return nil, fmt.Errorf("unable to marshal plot request: %s", err) } httpTransport := &http.Transport{ Dial: (&net.Dialer{ // Enable dual IPv4/IPv6 stack connectivity: DualStack: true, // Enforce HTTP connection timeout: Timeout: time.Duration(connector.timeout) * time.Second, }).Dial, } httpClient := http.Client{Transport: httpTransport} request, err := http.NewRequest( "POST", strings.TrimSuffix(connector.upstream, "/")+facetteURLLibraryGraphsPlots, bytes.NewReader(requestBody)) if err != nil { return nil, fmt.Errorf("unable to set up HTTP request: %s", err) } request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", "Facette") request.Header.Add("X-Requested-With", "FacetteConnector") response, err := httpClient.Do(request) if err != nil { return nil, fmt.Errorf("unable to perform HTTP request: %s", err) } if err := facetteCheckConnectorResponse(response); err != nil { return nil, fmt.Errorf("invalid upstream HTTP response: %s", err) } data, err := ioutil.ReadAll(response.Body) if err != nil { return nil, fmt.Errorf("unable to read HTTP response body: %s", err) } plotResponse := facettePlotResponse{} if err := json.Unmarshal(data, &plotResponse); err != nil { return nil, fmt.Errorf("unable to unmarshal upstream response: %s", err) } result := make([]*types.PlotResult, 0) for _, serie := range plotResponse.Series { result = append(result, &types.PlotResult{ Plots: serie.Plots, Info: serie.Info, }) } return result, nil }