本文整理匯總了Golang中github.com/GeoNet/mtr/ts.Plot類的典型用法代碼示例。如果您正苦於以下問題:Golang Plot類的具體用法?Golang Plot怎麽用?Golang Plot使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。
在下文中一共展示了Plot類的12個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: dataCompletenessSpark
/*
spark draws an svg spark line to b. Assumes f.loadPK has been called first.
*/
func dataCompletenessSpark(siteID, typeID string, b *bytes.Buffer) *weft.Result {
var p ts.Plot
p.SetXAxis(time.Now().UTC().Add(time.Hour*-12), time.Now().UTC())
var err error
var rows *sql.Rows
var expected int
var typePK int
if err = dbR.QueryRow(`SELECT typePK, expected FROM data.completeness_type WHERE typeID = $1`,
typeID).Scan(&typePK, &expected); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
expectedf := float64(expected)
if rows, err = dbR.Query(`SELECT date_trunc('hour',time) as t, sum(count) FROM data.completeness
WHERE sitePK = (SELECT sitePK FROM data.site WHERE siteID = $1)
AND typePK = $2
AND time > now() - interval '28 days'
GROUP BY date_trunc('hour',time)
ORDER BY t ASC`,
siteID, typePK); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var pts []ts.Point
for rows.Next() {
var pt ts.Point
var v int
if err = rows.Scan(&pt.DateTime, &v); err != nil {
return weft.InternalServerError(err)
}
// No need to scale spark data for display.
pt.Value = float64(v) / expectedf
pts = append(pts, pt)
}
if len(pts) > 0 {
p.AddSeries(ts.Series{Colour: "deepskyblue", Points: pts})
}
if err = ts.SparkLine.Draw(p, b); err != nil {
return weft.InternalServerError(err)
}
return &weft.StatusOK
}
示例2: dataLatencySpark
/*
spark draws an svg spark line to b. Assumes f.loadPK has been called first.
*/
func dataLatencySpark(siteID, typeID string, b *bytes.Buffer) *weft.Result {
var p ts.Plot
p.SetXAxis(time.Now().UTC().Add(time.Hour*-12), time.Now().UTC())
var err error
var rows *sql.Rows
if rows, err = dbR.Query(`SELECT date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t,
avg(mean) FROM data.latency
WHERE sitePK = (SELECT sitePK FROM data.site WHERE siteID = $1)
AND typePK = (SELECT typePK FROM data.type WHERE typeID = $2)
AND time > now() - interval '12 hours'
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min'
ORDER BY t ASC`,
siteID, typeID); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var pts []ts.Point
for rows.Next() {
var pt ts.Point
if err = rows.Scan(&pt.DateTime, &pt.Value); err != nil {
return weft.InternalServerError(err)
}
// No need to scale spark data for display.
pts = append(pts, pt)
}
rows.Close()
p.AddSeries(ts.Series{Colour: internal.Colour(int(internal.Mean)), Points: pts})
if err = ts.SparkLine.Draw(p, b); err != nil {
return weft.InternalServerError(err)
}
return &weft.StatusOK
}
示例3: dataCompletenessPlot
/*
plot draws an svg plot to b. Assumes f.loadPK has been called first.
*/
func dataCompletenessPlot(siteID, typeID, resolution string, plotter ts.SVGPlot, b *bytes.Buffer) *weft.Result {
var err error
// we need the sitePK often so read it once.
var sitePK int
if err = dbR.QueryRow(`SELECT sitePK FROM data.site WHERE siteID = $1`,
siteID).Scan(&sitePK); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
var typePK int
var expected int
if err = dbR.QueryRow(`SELECT typePK, expected FROM data.completeness_type WHERE typeID = $1`,
typeID).Scan(&typePK, &expected); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
expectedf := float64(expected)
var p ts.Plot
var tags []string
var rows *sql.Rows
if rows, err = dbR.Query(`SELECT tag FROM data.completeness_tag JOIN mtr.tag USING (tagpk) WHERE
sitePK = $1 AND typePK = $2
ORDER BY tag asc`,
sitePK, typePK); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
for rows.Next() {
var s string
if err = rows.Scan(&s); err != nil {
return weft.InternalServerError(err)
}
tags = append(tags, s)
}
rows.Close()
p.SetSubTitle("Tags: " + strings.Join(tags, ","))
p.SetTitle(fmt.Sprintf("Site: %s - %s", siteID, strings.Title(typeID)))
p.SetUnit("completeness")
switch resolution {
case "five_minutes":
p.SetXAxis(time.Now().UTC().Add(time.Hour*-24*2), time.Now().UTC())
p.SetXLabel("48 hours")
expectedf /= 288
rows, err = dbR.Query(`SELECT date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t,
sum(count) FROM data.completeness WHERE
sitePK = $1 AND typePK = $2
AND time > now() - interval '2 days'
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min'
ORDER BY t ASC`,
sitePK, typePK)
case "hour":
p.SetXAxis(time.Now().UTC().Add(time.Hour*-24*28), time.Now().UTC())
p.SetXLabel("4 weeks")
expectedf /= 24
rows, err = dbR.Query(`SELECT date_trunc('`+resolution+`',time) as t, sum(count) FROM data.completeness WHERE
sitePK = $1 AND typePK = $2
AND time > now() - interval '28 days'
GROUP BY date_trunc('`+resolution+`',time)
ORDER BY t ASC`,
sitePK, typePK)
case "twelve_hours":
p.SetXAxis(time.Now().UTC().Add(time.Hour*-24*28), time.Now().UTC())
p.SetXLabel("4 weeks")
expectedf /= 2
rows, err = dbR.Query(`SELECT date_trunc('hour', time) + extract(hour from time)::int / 12 * interval '12 hour' as t, sum(count) FROM data.completeness WHERE
sitePK = $1 AND typePK = $2
AND time > now() - interval '28 days'
GROUP BY date_trunc('hour', time) + extract(hour from time)::int / 12 * interval '12 hour'
ORDER BY t ASC`,
sitePK, typePK)
default:
return weft.BadRequest("invalid resolution")
}
if err != nil {
return weft.InternalServerError(err)
}
var pts []ts.Point
for rows.Next() {
//.........這裏部分代碼省略.........
示例4: plot
/*
plot draws an svg plot to b.
Valid values for resolution are 'minute', 'five_minutes', 'hour'.
*/
func (f fieldMetric) plot(deviceID, typeID, resolution string, plotter ts.SVGPlot, b *bytes.Buffer) *weft.Result {
// we need the devicePK often so read it once.
var devicePK int
if err := dbR.QueryRow(`SELECT devicePK FROM field.device WHERE deviceID = $1`,
deviceID).Scan(&devicePK); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
var typePK int
var scale float64
var display string
if err := dbR.QueryRow(`SELECT typePK, scale, display FROM field.type WHERE typeID = $1`,
typeID).Scan(&typePK, &scale, &display); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
var p ts.Plot
p.SetUnit(display)
var rows *sql.Rows
var err error
var lower, upper int
if err := dbR.QueryRow(`SELECT lower,upper FROM field.threshold
WHERE devicePK = $1 AND typePK = $2`,
devicePK, typePK).Scan(&lower, &upper); err != nil && err != sql.ErrNoRows {
return weft.InternalServerError(err)
}
if !(lower == 0 && upper == 0) {
p.SetThreshold(float64(lower)*scale, float64(upper)*scale)
}
var tags []string
if rows, err = dbR.Query(`SELECT tag FROM field.metric_tag JOIN mtr.tag USING (tagpk) WHERE
devicePK = $1 AND typePK = $2
ORDER BY tag asc`,
devicePK, typePK); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
for rows.Next() {
var s string
if err = rows.Scan(&s); err != nil {
return weft.InternalServerError(err)
}
tags = append(tags, s)
}
rows.Close()
p.SetSubTitle("Tags: " + strings.Join(tags, ","))
var mod string
// TODO move into first select for devicePK
if err = dbR.QueryRow(`SELECT modelid FROM field.device JOIN field.model using (modelpk)
WHERE devicePK = $1`,
devicePK).Scan(&mod); err != nil && err != sql.ErrNoRows {
return weft.InternalServerError(err)
}
p.SetTitle(fmt.Sprintf("Device: %s, Model: %s, Metric: %s", deviceID, mod, strings.Title(typeID)))
switch resolution {
case "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*2), 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 resolution")
}
var timeRange []time.Time
if timeRange, err = defaultTimeRange(resolution); err != nil {
return weft.InternalServerError(err)
}
rows, err = queryMetricRows(devicePK, typePK, resolution, timeRange)
if err != nil {
return weft.InternalServerError(err)
//.........這裏部分代碼省略.........
示例5: loadAppMetrics
func (a appMetric) loadAppMetrics(applicationID, resolution string, typeID internal.ID, timeRange []time.Time, p *ts.Plot) *weft.Result {
var err error
var rows *sql.Rows
rows, err = dbR.Query(`SELECT COUNT(*)
FROM app.type, app.application
WHERE applicationID = $1
AND typePK = $2`, applicationID, int(typeID))
defer rows.Close()
var nRows int
for rows.Next() {
if err = rows.Scan(&nRows); err != nil {
return weft.InternalServerError(err)
}
}
// missing applicationID or typePK should return a 404 while no data can be 200. See GeoNet/mtr#214
if nRows == 0 {
return &weft.NotFound
}
rows.Close()
switch resolution {
case "minute":
rows, err = dbR.Query(`SELECT instancePK, typePK, date_trunc('`+resolution+`',time) as t, avg(value)
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK = $2
AND time >= $3 AND time <= $4
GROUP BY date_trunc('`+resolution+`',time), typePK, instancePK
ORDER BY t ASC`, applicationID, int(typeID), timeRange[0], timeRange[1])
case "five_minutes":
rows, err = dbR.Query(`SELECT instancePK, typePK,
date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t, avg(value)
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK = $2
AND time >= $3 AND time <= $4
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min', typePK, instancePK
ORDER BY t ASC`, applicationID, int(typeID), timeRange[0], timeRange[1])
case "hour":
rows, err = dbR.Query(`SELECT instancePK, typePK, date_trunc('`+resolution+`',time) as t, avg(value)
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK = $2
AND time >= $3 AND time <= $4
GROUP BY date_trunc('`+resolution+`',time), typePK, instancePK
ORDER BY t ASC`, applicationID, int(typeID), timeRange[0], timeRange[1])
case "full":
rows, err = dbR.Query(`SELECT instancePK, typePK, time as t, value
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK = $2
AND time >= $3 AND time <= $4
ORDER BY time ASC`, applicationID, int(typeID), timeRange[0], timeRange[1])
default:
return weft.InternalServerError(fmt.Errorf("invalid resolution: %s", resolution))
}
if err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var t time.Time
var typePK, instancePK int
var avg float64
var instanceID string
pts := make(map[InstanceMetric][]ts.Point)
for rows.Next() {
if err = rows.Scan(&instancePK, &typePK, &t, &avg); err != nil {
return weft.InternalServerError(err)
}
key := InstanceMetric{instancePK: instancePK, typePK: typePK}
pts[key] = append(pts[key], ts.Point{DateTime: t, Value: avg})
}
rows.Close()
instanceIDs := make(map[int]string)
if rows, err = dbR.Query(`SELECT instancePK, instanceID FROM app.instance`); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
for rows.Next() {
if err = rows.Scan(&instancePK, &instanceID); err != nil {
return weft.InternalServerError(err)
}
instanceIDs[instancePK] = instanceID
}
rows.Close()
var keys InstanceMetrics
//.........這裏部分代碼省略.........
示例6: loadMemory
func (a appMetric) loadMemory(applicationID, resolution string, timeRange []time.Time, p *ts.Plot) *weft.Result {
var err error
var rows *sql.Rows
switch resolution {
case "minute":
rows, err = dbR.Query(`SELECT instancePK, typePK, date_trunc('`+resolution+`',time) as t, avg(value)
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK IN (1000, 1001, 1002)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('`+resolution+`',time), typePK, instancePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "five_minutes":
rows, err = dbR.Query(`SELECT instancePK, typePK,
date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t, avg(value)
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK IN (1000, 1001, 1002)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min', typePK, instancePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "hour":
rows, err = dbR.Query(`SELECT instancePK, typePK, date_trunc('`+resolution+`',time) as t, avg(value)
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK IN (1000, 1001, 1002)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('`+resolution+`',time), typePK, instancePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "full":
rows, err = dbR.Query(`SELECT instancePK, typePK, time, value
FROM app.metric
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND typePK IN (1000, 1001, 1002)
AND time >= $2 AND time <= $3
ORDER BY time ASC`, applicationID, timeRange[0], timeRange[1])
default:
return weft.InternalServerError(fmt.Errorf("invalid resolution: %s", resolution))
}
if err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var t time.Time
var typePK, instancePK int
var avg float64
var instanceID string
pts := make(map[InstanceMetric][]ts.Point)
for rows.Next() {
if err = rows.Scan(&instancePK, &typePK, &t, &avg); err != nil {
fmt.Println(err)
return weft.InternalServerError(err)
}
key := InstanceMetric{instancePK: instancePK, typePK: typePK}
pts[key] = append(pts[key], ts.Point{DateTime: t, Value: avg})
}
rows.Close()
instanceIDs := make(map[int]string)
if rows, err = dbR.Query(`SELECT instancePK, instanceID FROM app.instance`); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
for rows.Next() {
if err = rows.Scan(&instancePK, &instanceID); err != nil {
return weft.InternalServerError(err)
}
instanceIDs[instancePK] = instanceID
}
rows.Close()
var labels ts.Labels
for k := range pts {
p.AddSeries(ts.Series{Colour: internal.Colour(k.typePK), Points: pts[k]})
labels = append(labels, ts.Label{Colour: internal.Colour(k.typePK), Label: fmt.Sprintf("%s.%s", instanceIDs[k.instancePK], strings.TrimPrefix(internal.Label(k.typePK), `Mem `))})
}
p.SetLabels(labels)
return &weft.StatusOK
}
示例7: appMetricCsv
func appMetricCsv(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
a := appMetric{}
v := r.URL.Query()
applicationID := v.Get("applicationID")
resolution := v.Get("resolution")
if resolution == "" {
resolution = "minute"
}
var timeRange []time.Time
var err error
if timeRange, err = parseTimeRange(v); err != nil {
return weft.InternalServerError(err)
}
// the Plot type holds all the data used to plot svgs, we'll create a CSV from the labels and point values
var p ts.Plot
switch v.Get("group") {
case "counters":
if res := a.loadCounters(applicationID, resolution, timeRange, &p); !res.Ok {
return res
}
case "timers":
// "full" resolution for timers is 90th percentile max per minute over fourty days
sourceID := v.Get("sourceID")
if sourceID != "" {
if res := a.loadTimersWithSourceID(applicationID, sourceID, resolution, timeRange, &p); !res.Ok {
return res
}
} else {
if res := a.loadTimers(applicationID, resolution, timeRange, &p); !res.Ok {
return res
}
}
case "memory":
if res := a.loadMemory(applicationID, resolution, timeRange, &p); !res.Ok {
return res
}
case "objects":
if res := a.loadAppMetrics(applicationID, resolution, internal.MemHeapObjects, timeRange, &p); !res.Ok {
return res
}
case "routines":
if res := a.loadAppMetrics(applicationID, resolution, internal.Routines, timeRange, &p); !res.Ok {
return res
}
default:
return weft.BadRequest("invalid value for group")
}
// CSV headers, the first label is always time
labels := p.GetLabels()
var headers []string
for _, label := range labels {
headers = append(headers, label.Label)
}
// Labels can be in random order so keep a sorted list but with time always at 0
sort.Strings(headers)
headers = append([]string{"time"}, headers...)
values := make(map[time.Time]map[string]float64)
ts := times{} // maintaining an ordered and unique list of times in the map
// add all points to a map to collect duplicate times with different column names
allData := p.GetSeries()
for i, d := range allData {
points := d.Series.Points
for _, point := range points {
if _, ok := values[point.DateTime]; ok == false {
values[point.DateTime] = map[string]float64{labels[i].Label: point.Value}
ts = append(ts, point.DateTime)
} else {
v := values[point.DateTime]
v[labels[i].Label] = point.Value
}
}
}
if len(values) == 0 {
return &weft.StatusOK
}
w := csv.NewWriter(b)
sort.Sort(ts)
for i, t := range ts {
// CSV headers
if i == 0 {
if err = w.Write(headers); err != nil {
return weft.InternalServerError(err)
}
}
fields := []string{t.Format(DYGRAPH_TIME_FORMAT)}
// CSV data
//.........這裏部分代碼省略.........
示例8: loadTimersWithSourceID
func (a appMetric) loadTimersWithSourceID(applicationID, sourceID, resolution string, timeRange []time.Time, p *ts.Plot) *weft.Result {
var err error
var rows *sql.Rows
switch resolution {
case "minute":
rows, err = dbR.Query(`SELECT date_trunc('minute',time) as t, avg(average), max(fifty), max(ninety), sum(count)
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND sourcePK = (SELECT sourcePK from app.source WHERE sourceID = $2)
AND time >= $3 AND time <= $4
GROUP BY date_trunc('minute',time)
ORDER BY t ASC`, applicationID, sourceID, timeRange[0], timeRange[1])
case "five_minutes":
rows, err = dbR.Query(`SELECT
date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t,
avg(average), max(fifty), max(ninety), sum(count)
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND sourcePK = (SELECT sourcePK from app.source WHERE sourceID = $2)
AND time >= $3 AND time <= $4
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min'
ORDER BY t ASC`, applicationID, sourceID, timeRange[0], timeRange[1])
case "hour":
rows, err = dbR.Query(`SELECT date_trunc('hour',time) as t, avg(average), max(fifty), max(ninety), sum(count)
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND sourcePK = (SELECT sourcePK from app.source WHERE sourceID = $2)
AND time >= $3 AND time <= $4
GROUP BY date_trunc('hour', time)
ORDER BY t ASC`, applicationID, sourceID, timeRange[0], timeRange[1])
case "full":
rows, err = dbR.Query(`SELECT time, average, fifty, ninety, count
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND sourcePK = (SELECT sourcePK from app.source WHERE sourceID = $2)
AND time >= $3 AND time <= $4
ORDER BY time ASC`, applicationID, sourceID, timeRange[0], timeRange[1])
default:
return weft.InternalServerError(fmt.Errorf("invalid resolution: %s", resolution))
}
if err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var t time.Time
var avg_mean float64
var max_fifty, max_ninety, n int
pts := make(map[internal.ID][]ts.Point)
for rows.Next() {
if err = rows.Scan(&t, &avg_mean, &max_fifty, &max_ninety, &n); err != nil {
return weft.InternalServerError(err)
}
pts[internal.AvgMean] = append(pts[internal.AvgMean], ts.Point{DateTime: t, Value: avg_mean})
pts[internal.MaxFifty] = append(pts[internal.MaxFifty], ts.Point{DateTime: t, Value: float64(max_fifty)})
pts[internal.MaxNinety] = append(pts[internal.MaxNinety], ts.Point{DateTime: t, Value: float64(max_ninety)})
}
rows.Close()
var labels ts.Labels
for k, v := range pts {
i := int(k)
p.AddSeries(ts.Series{Points: v, Colour: internal.Colour(i)})
labels = append(labels, ts.Label{Label: fmt.Sprintf("%s (n=%d)", strings.TrimPrefix(internal.Label(i), `main.`), len(v)), Colour: internal.Colour(i)})
}
p.SetLabels(labels)
return &weft.StatusOK
}
示例9: loadTimers
func (a appMetric) loadTimers(applicationID, resolution string, timeRange []time.Time, p *ts.Plot) *weft.Result {
var err error
var rows *sql.Rows
switch resolution {
case "minute":
rows, err = dbR.Query(`SELECT sourcePK, date_trunc('`+resolution+`',time) as t, max(ninety), sum(count)
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('`+resolution+`',time), sourcePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "five_minutes":
rows, err = dbR.Query(`SELECT sourcePK,
date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t,
max(ninety), sum(count)
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min', sourcePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "hour":
rows, err = dbR.Query(`SELECT sourcePK, date_trunc('`+resolution+`',time) as t, max(ninety), sum(count)
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('`+resolution+`',time), sourcePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "full":
rows, err = dbR.Query(`SELECT sourcePK, time, ninety, count
FROM app.timer
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
ORDER BY time ASC`, applicationID, timeRange[0], timeRange[1])
default:
return weft.InternalServerError(fmt.Errorf("invalid resolution: %s", resolution))
}
if err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var t time.Time
var sourcePK, max, n int
var sourceID string
pts := make(map[int][]ts.Point)
total := make(map[int]int) // track the total counts (call) for each timer.
for rows.Next() {
if err = rows.Scan(&sourcePK, &t, &max, &n); err != nil {
return weft.InternalServerError(err)
}
pts[sourcePK] = append(pts[sourcePK], ts.Point{DateTime: t, Value: float64(max)})
total[sourcePK] += n
}
rows.Close()
sourceIDs := make(map[int]string)
if rows, err = dbR.Query(`SELECT sourcePK, sourceID FROM app.source`); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
for rows.Next() {
if err = rows.Scan(&sourcePK, &sourceID); err != nil {
return weft.InternalServerError(err)
}
sourceIDs[sourcePK] = sourceID
}
rows.Close()
// sort the sourcePKs based on number of calls.
keys := rank(total)
var labels ts.Labels
for _, k := range keys {
p.AddSeries(ts.Series{Points: pts[k.Key], Colour: "#e34a33"})
labels = append(labels, ts.Label{Label: fmt.Sprintf("%s (n=%d)", strings.TrimPrefix(sourceIDs[k.Key], `main.`), total[k.Key]), Colour: "lightgrey"})
}
p.SetLabels(labels)
return &weft.StatusOK
}
示例10: loadCounters
func (a appMetric) loadCounters(applicationID, resolution string, timeRange []time.Time, p *ts.Plot) *weft.Result {
var err error
var rows *sql.Rows
switch resolution {
case "minute":
rows, err = dbR.Query(`SELECT typePK, date_trunc('`+resolution+`',time) as t, sum(count)
FROM app.counter
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('`+resolution+`',time), typePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "five_minutes":
rows, err = dbR.Query(`SELECT typePK,
date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min' as t, sum(count)
FROM app.counter
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('hour', time) + extract(minute from time)::int / 5 * interval '5 min', typePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "hour":
rows, err = dbR.Query(`SELECT typePK, date_trunc('`+resolution+`',time) as t, sum(count)
FROM app.counter
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
GROUP BY date_trunc('`+resolution+`',time), typePK
ORDER BY t ASC`, applicationID, timeRange[0], timeRange[1])
case "full":
rows, err = dbR.Query(`SELECT typePK, time, count
FROM app.counter
JOIN app.type USING (typepk)
WHERE applicationPK = (SELECT applicationPK from app.application WHERE applicationID = $1)
AND time >= $2 AND time <= $3
ORDER BY time ASC`, applicationID, timeRange[0], timeRange[1])
default:
return weft.InternalServerError(fmt.Errorf("invalid resolution: %s", resolution))
}
if err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
var t time.Time
var typePK, count int
pts := make(map[int][]ts.Point)
total := make(map[int]int)
for rows.Next() {
if err = rows.Scan(&typePK, &t, &count); err != nil {
return weft.InternalServerError(err)
}
pts[typePK] = append(pts[typePK], ts.Point{DateTime: t, Value: float64(count)})
total[typePK] += count
}
rows.Close()
var keys []int
for k := range pts {
keys = append(keys, k)
}
sort.Ints(keys)
var labels ts.Labels
for _, k := range keys {
p.AddSeries(ts.Series{Colour: internal.Colour(k), Points: pts[k]})
labels = append(labels, ts.Label{Colour: internal.Colour(k), Label: fmt.Sprintf("%s (n=%d)", internal.Label(k), total[k])})
}
p.SetLabels(labels)
return &weft.StatusOK
}
示例11: appMetricSvg
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
}
//.........這裏部分代碼省略.........
示例12: dataLatencyPlot
func dataLatencyPlot(siteID, typeID, resolution string, plotter ts.SVGPlot, b *bytes.Buffer) *weft.Result {
var err error
// we need the sitePK often so read it once.
var sitePK int
if err = dbR.QueryRow(`SELECT sitePK FROM data.site WHERE siteID = $1`,
siteID).Scan(&sitePK); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
var typePK int
var scale float64
var display string
if err = dbR.QueryRow(`SELECT typePK, scale, display FROM data.type WHERE typeID = $1`,
typeID).Scan(&typePK, &scale, &display); err != nil {
if err == sql.ErrNoRows {
return &weft.NotFound
}
return weft.InternalServerError(err)
}
var p ts.Plot
p.SetUnit(display)
var lower, upper int
if err := dbR.QueryRow(`SELECT lower,upper FROM data.latency_threshold
WHERE sitePK = $1 AND typePK = $2`,
sitePK, typePK).Scan(&lower, &upper); err != nil && err != sql.ErrNoRows {
return weft.InternalServerError(err)
}
if !(lower == 0 && upper == 0) {
p.SetThreshold(float64(lower)*scale, float64(upper)*scale)
}
var tags []string
var rows *sql.Rows
if rows, err = dbR.Query(`SELECT tag FROM data.latency_tag JOIN mtr.tag USING (tagpk) WHERE
sitePK = $1 AND typePK = $2
ORDER BY tag asc`,
sitePK, typePK); err != nil {
return weft.InternalServerError(err)
}
defer rows.Close()
for rows.Next() {
var s string
if err = rows.Scan(&s); err != nil {
return weft.InternalServerError(err)
}
tags = append(tags, s)
}
rows.Close()
p.SetSubTitle("Tags: " + strings.Join(tags, ","))
p.SetTitle(fmt.Sprintf("Site: %s - %s", siteID, strings.Title(typeID)))
// TODO - loading avg(mean) at each resolution. Need to add max(fifty) and max(ninety) when there are some values.
switch resolution {
case "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*2), 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 resolution")
}
if err != nil {
return weft.InternalServerError(err)
}
var timeRange []time.Time
if timeRange, err = defaultTimeRange(resolution); err != nil {
weft.InternalServerError(err)
}
rows, err = queryLatencyRows(sitePK, typePK, resolution, timeRange)
defer rows.Close()
pts := make(map[internal.ID]([]ts.Point))
var mean float64
var fifty int
var ninety int
var pt ts.Point
for rows.Next() {
if err = rows.Scan(&pt.DateTime, &mean, &fifty, &ninety); err != nil {
//.........這裏部分代碼省略.........