From 92ef33d97a437dce2d7b55f06342de388d95f575 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= <peterke@gmail.com>
Date: Wed, 24 Jun 2015 18:30:00 +0300
Subject: [PATCH] rpc/api, cmd/geth: retrievel all percentiles, add time units

---
 cmd/geth/monitorcmd.go | 17 +++++++++++++----
 rpc/api/debug.go       | 43 +++++++++++++++++++++---------------------
 2 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/cmd/geth/monitorcmd.go b/cmd/geth/monitorcmd.go
index ec0dfb8f2..53eb61a46 100644
--- a/cmd/geth/monitorcmd.go
+++ b/cmd/geth/monitorcmd.go
@@ -76,7 +76,10 @@ func monitor(ctx *cli.Context) {
 
 	termui.UseTheme("helloworld")
 
-	rows := 5
+	rows := len(monitored)
+	if rows > 5 {
+		rows = 5
+	}
 	cols := (len(monitored) + rows - 1) / rows
 	for i := 0; i < rows; i++ {
 		termui.Body.AddRows(termui.NewRow())
@@ -207,8 +210,9 @@ func expandMetrics(metrics map[string]interface{}, path string) []string {
 // updateChart inserts a dataset into a line chart, scaling appropriately as to
 // not display weird labels, also updating the chart label accordingly.
 func updateChart(metric string, data []float64, chart *termui.LineChart) {
-	units := []string{"", "K", "M", "G", "T", "E", "P"}
-	colors := []termui.Attribute{termui.ColorBlue, termui.ColorCyan, termui.ColorGreen, termui.ColorYellow, termui.ColorRed, termui.ColorRed, termui.ColorRed}
+	dataUnits := []string{"", "K", "M", "G", "T", "E"}
+	timeUnits := []string{"ns", "µs", "ms", "s", "ks", "ms"}
+	colors := []termui.Attribute{termui.ColorBlue, termui.ColorCyan, termui.ColorGreen, termui.ColorYellow, termui.ColorRed, termui.ColorRed}
 
 	// Find the maximum value and scale under 1K
 	high := data[0]
@@ -225,7 +229,12 @@ func updateChart(metric string, data []float64, chart *termui.LineChart) {
 	}
 	// Update the chart's label with the scale units
 	chart.Border.Label = metric
-	if unit > 0 {
+
+	units := dataUnits
+	if strings.Contains(metric, "Percentiles") {
+		units = timeUnits
+	}
+	if len(units[unit]) > 0 {
 		chart.Border.Label += " [" + units[unit] + "]"
 	}
 	chart.LineColor = colors[unit]
diff --git a/rpc/api/debug.go b/rpc/api/debug.go
index 45c99f295..5975f88ab 100644
--- a/rpc/api/debug.go
+++ b/rpc/api/debug.go
@@ -193,6 +193,11 @@ func (self *debugApi) Metrics(req *shared.Request) (interface{}, error) {
 	format := func(total float64, rate float64) string {
 		return fmt.Sprintf("%s (%s/s)", round(total, 0), round(rate, 2))
 	}
+	// Create the percentile units
+	percentiles := make([]float64, 101)
+	for i := 0; i <= 100; i++ {
+		percentiles[i] = float64(i) / 100
+	}
 	// Iterate over all the metrics, and just dump for now
 	counters := make(map[string]interface{})
 	metrics.DefaultRegistry.Each(func(name string, metric interface{}) {
@@ -211,29 +216,25 @@ func (self *debugApi) Metrics(req *shared.Request) (interface{}, error) {
 			switch metric := metric.(type) {
 			case metrics.Meter:
 				root[name] = map[string]interface{}{
-					"Avg01Min": metric.Rate1(),
-					"Avg05Min": metric.Rate5(),
-					"Avg15Min": metric.Rate15(),
-					"AvgTotal": metric.RateMean(),
-					"Total":    float64(metric.Count()),
+					"AvgRate01Min": metric.Rate1(),
+					"AvgRate05Min": metric.Rate5(),
+					"AvgRate15Min": metric.Rate15(),
+					"MeanRate":     metric.RateMean(),
+					"Total":        float64(metric.Count()),
 				}
 
 			case metrics.Timer:
+				ps := make(map[string]interface{})
+				for i, p := range metric.Percentiles(percentiles) {
+					ps[fmt.Sprintf("%d", i)] = p
+				}
 				root[name] = map[string]interface{}{
-					"Avg01Min": metric.Rate1(),
-					"Avg05Min": metric.Rate5(),
-					"Avg15Min": metric.Rate15(),
-					"AvgTotal": metric.RateMean(),
-					"Total":    float64(metric.Count()),
-					"Maximum":  metric.Max(),
-					"Minimum":  metric.Min(),
-					"Percentile": map[string]interface{}{
-						"20": metric.Percentile(0.2),
-						"50": metric.Percentile(0.5),
-						"80": metric.Percentile(0.8),
-						"95": metric.Percentile(0.95),
-						"99": metric.Percentile(0.99),
-					},
+					"AvgRate01Min": metric.Rate1(),
+					"AvgRate05Min": metric.Rate5(),
+					"AvgRate15Min": metric.Rate15(),
+					"MeanRate":     metric.RateMean(),
+					"Total":        float64(metric.Count()),
+					"Percentiles":  ps,
 				}
 
 			default:
@@ -254,10 +255,10 @@ func (self *debugApi) Metrics(req *shared.Request) (interface{}, error) {
 					"Avg01Min": format(metric.Rate1()*60, metric.Rate1()),
 					"Avg05Min": format(metric.Rate5()*300, metric.Rate5()),
 					"Avg15Min": format(metric.Rate15()*900, metric.Rate15()),
-					"Count":    format(float64(metric.Count()), metric.RateMean()),
+					"Total":    format(float64(metric.Count()), metric.RateMean()),
 					"Maximum":  time.Duration(metric.Max()).String(),
 					"Minimum":  time.Duration(metric.Min()).String(),
-					"Percentile": map[string]interface{}{
+					"Percentiles": map[string]interface{}{
 						"20": time.Duration(metric.Percentile(0.2)).String(),
 						"50": time.Duration(metric.Percentile(0.5)).String(),
 						"80": time.Duration(metric.Percentile(0.8)).String(),
-- 
GitLab