func handleRenderPB(w http.ResponseWriter, req *http.Request, format string, responses []serverResponse) { metrics := make(map[string][]pb.FetchResponse) for _, r := range responses { var d pb.MultiFetchResponse err := d.Unmarshal(r.response) if err != nil { logger.Logf("error decoding protobuf response from server:%s: req:%s: err=%s", r.server, req.URL.RequestURI(), err) logger.Traceln("\n" + hex.Dump(r.response)) Metrics.RenderErrors.Add(1) continue } for _, m := range d.Metrics { metrics[m.GetName()] = append(metrics[m.GetName()], *m) } } var multi pb.MultiFetchResponse if len(metrics) == 0 { err := fmt.Sprintf("no decoded responses to merge for req: %s", req.URL.RequestURI()) logger.Logln(err) http.Error(w, err, http.StatusInternalServerError) Metrics.RenderErrors.Add(1) return } for name, decoded := range metrics { logger.Tracef("request: %s: %q %+v", req.URL.RequestURI(), name, decoded) if len(decoded) == 1 { logger.Debugf("only one decoded responses to merge for req: %q %s", name, req.URL.RequestURI()) m := decoded[0] multi.Metrics = append(multi.Metrics, &m) continue } // Use the metric with the highest resolution as our base var highest int for i, d := range decoded { if d.GetStepTime() < decoded[highest].GetStepTime() { highest = i } } decoded[0], decoded[highest] = decoded[highest], decoded[0] metric := decoded[0] mergeValues(req, &metric, decoded) multi.Metrics = append(multi.Metrics, &metric) } returnRender(w, format, multi) }