func appMetricSvg(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { a := appMetric{} v := r.URL.Query() applicationID := v.Get("applicationID") var p ts.Plot resolution := v.Get("resolution") switch resolution { case "", "minute": resolution = "minute" p.SetXAxis(time.Now().UTC().Add(time.Hour*-12), time.Now().UTC()) p.SetXLabel("12 hours") case "five_minutes": p.SetXAxis(time.Now().UTC().Add(time.Hour*-24*3), time.Now().UTC()) p.SetXLabel("48 hours") case "hour": p.SetXAxis(time.Now().UTC().Add(time.Hour*-24*28), time.Now().UTC()) p.SetXLabel("4 weeks") default: return weft.BadRequest("invalid value for resolution") } var err error if v.Get("yrange") != "" { y := strings.Split(v.Get("yrange"), `,`) var ymin, ymax float64 if len(y) != 2 { return weft.BadRequest("invalid yrange query param.") } if ymin, err = strconv.ParseFloat(y[0], 64); err != nil { return weft.BadRequest("invalid yrange query param.") } if ymax, err = strconv.ParseFloat(y[1], 64); err != nil { return weft.BadRequest("invalid yrange query param.") } p.SetYAxis(ymin, ymax) } resTitle := resolution resTitle = strings.Replace(resTitle, "_", " ", -1) resTitle = strings.Title(resTitle) var timeRange []time.Time if timeRange, err = parseTimeRange(v); err != nil { return weft.InternalServerError(err) } switch v.Get("group") { case "counters": if res := a.loadCounters(applicationID, resolution, timeRange, &p); !res.Ok { return res } p.SetTitle(fmt.Sprintf("Application: %s, Metric: Counters - Sum per %s", applicationID, resTitle)) err = ts.MixedAppMetrics.Draw(p, b) case "timers": sourceID := v.Get("sourceID") if sourceID != "" { if res := a.loadTimersWithSourceID(applicationID, sourceID, resolution, timeRange, &p); !res.Ok { return res } p.SetTitle(fmt.Sprintf("Application: %s, Source: %s, Metric: Timers - 90th Percentile (ms) per %s", applicationID, sourceID, resTitle)) } else { if res := a.loadTimers(applicationID, resolution, timeRange, &p); !res.Ok { return res } p.SetTitle(fmt.Sprintf("Application: %s, Metric: Timers - 90th Percentile (ms) - Max per %s", applicationID, resTitle)) } err = ts.ScatterAppTimers.Draw(p, b) case "memory": if res := a.loadMemory(applicationID, resolution, timeRange, &p); !res.Ok { return res } p.SetTitle(fmt.Sprintf("Application: %s, Metric: Memory (bytes) - Average per %s", applicationID, resTitle)) err = ts.LineAppMetrics.Draw(p, b) case "objects": if res := a.loadAppMetrics(applicationID, resolution, internal.MemHeapObjects, timeRange, &p); !res.Ok { return res } p.SetTitle(fmt.Sprintf("Application: %s, Metric: Memory Heap Objects (n) - Average per %s", applicationID, resTitle)) err = ts.LineAppMetrics.Draw(p, b) case "routines": if res := a.loadAppMetrics(applicationID, resolution, internal.Routines, timeRange, &p); !res.Ok { return res } p.SetTitle(fmt.Sprintf("Application: %s, Metric: Routines (n) - Average per %s", applicationID, resTitle)) err = ts.LineAppMetrics.Draw(p, b) default: return weft.BadRequest("invalid value for type") } if err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }