From b98b444179ed16d54fab1ff416cf561427151f87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= <peterke@gmail.com>
Date: Thu, 25 Jun 2015 10:36:47 +0300
Subject: cmd/geth: add attach and rows flags to the monitor command

---
 cmd/geth/main.go       | 11 +--------
 cmd/geth/monitorcmd.go | 65 ++++++++++++++++++++++++++++++++------------------
 2 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index f7b4810cd..f1c229d1f 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -72,6 +72,7 @@ func init() {
 		upgradedbCommand,
 		removedbCommand,
 		dumpCommand,
+		monitorCommand,
 		{
 			Action: makedag,
 			Name:   "makedag",
@@ -214,16 +215,6 @@ The Geth console is an interactive shell for the JavaScript runtime environment
 which exposes a node admin interface as well as the Ðapp JavaScript API.
 See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
 This command allows to open a console on a running geth node.
-`,
-		},
-		{
-			Action: monitor,
-			Name:   "monitor",
-			Usage:  `Geth Monitor: node metrics monitoring and visualization`,
-			Description: `
-The Geth monitor is a tool to collect and visualize various internal metrics
-gathered by the node, supporting different chart types as well as the capacity
-to display multiple metrics simultaneously.
 `,
 		},
 		{
diff --git a/cmd/geth/monitorcmd.go b/cmd/geth/monitorcmd.go
index 53eb61a46..7b0076860 100644
--- a/cmd/geth/monitorcmd.go
+++ b/cmd/geth/monitorcmd.go
@@ -9,48 +9,61 @@ import (
 
 	"github.com/codegangsta/cli"
 	"github.com/ethereum/go-ethereum/cmd/utils"
+	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/rpc"
 	"github.com/ethereum/go-ethereum/rpc/codec"
 	"github.com/ethereum/go-ethereum/rpc/comms"
 	"github.com/gizak/termui"
 )
 
+var (
+	monitorCommandAttachFlag = cli.StringFlag{
+		Name:  "attach",
+		Value: "ipc:" + common.DefaultIpcPath(),
+		Usage: "IPC or RPC API endpoint to attach to",
+	}
+	monitorCommandRowsFlag = cli.IntFlag{
+		Name:  "rows",
+		Value: 5,
+		Usage: "Rows (maximum) to display the charts in",
+	}
+	monitorCommand = cli.Command{
+		Action: monitor,
+		Name:   "monitor",
+		Usage:  `Geth Monitor: node metrics monitoring and visualization`,
+		Description: `
+The Geth monitor is a tool to collect and visualize various internal metrics
+gathered by the node, supporting different chart types as well as the capacity
+to display multiple metrics simultaneously.
+`,
+		Flags: []cli.Flag{
+			monitorCommandAttachFlag,
+			monitorCommandRowsFlag,
+		},
+	}
+)
+
 // monitor starts a terminal UI based monitoring tool for the requested metrics.
 func monitor(ctx *cli.Context) {
 	var (
 		client comms.EthereumClient
-		args   []string
 		err    error
 	)
 	// Attach to an Ethereum node over IPC or RPC
-	if ctx.Args().Present() {
-		// Try to interpret the first parameter as an endpoint
-		client, err = comms.ClientFromEndpoint(ctx.Args().First(), codec.JSON)
-		if err == nil {
-			args = ctx.Args().Tail()
-		}
-	}
-	if !ctx.Args().Present() || err != nil {
-		// Either no args were given, or not endpoint, use defaults
-		cfg := comms.IpcConfig{
-			Endpoint: ctx.GlobalString(utils.IPCPathFlag.Name),
-		}
-		args = ctx.Args()
-		client, err = comms.NewIpcClient(cfg, codec.JSON)
-	}
-	if err != nil {
-		utils.Fatalf("Unable to attach to geth node - %v", err)
+	endpoint := ctx.String(monitorCommandAttachFlag.Name)
+	if client, err = comms.ClientFromEndpoint(endpoint, codec.JSON); err != nil {
+		utils.Fatalf("Unable to attach to geth node: %v", err)
 	}
 	defer client.Close()
 
 	xeth := rpc.NewXeth(client)
 
 	// Retrieve all the available metrics and resolve the user pattens
-	metrics, err := xeth.Call("debug_metrics", []interface{}{true})
+	metrics, err := retrieveMetrics(xeth)
 	if err != nil {
 		utils.Fatalf("Failed to retrieve system metrics: %v", err)
 	}
-	monitored := resolveMetrics(metrics, args)
+	monitored := resolveMetrics(metrics, ctx.Args())
 	sort.Strings(monitored)
 
 	// Create the access function and check that the metric exists
@@ -77,8 +90,8 @@ func monitor(ctx *cli.Context) {
 	termui.UseTheme("helloworld")
 
 	rows := len(monitored)
-	if rows > 5 {
-		rows = 5
+	if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max {
+		rows = max
 	}
 	cols := (len(monitored) + rows - 1) / rows
 	for i := 0; i < rows; i++ {
@@ -126,7 +139,7 @@ func monitor(ctx *cli.Context) {
 				termui.Render(termui.Body)
 			}
 		case <-refresh:
-			metrics, err := xeth.Call("debug_metrics", []interface{}{true})
+			metrics, err := retrieveMetrics(xeth)
 			if err != nil {
 				utils.Fatalf("Failed to retrieve system metrics: %v", err)
 			}
@@ -139,6 +152,12 @@ func monitor(ctx *cli.Context) {
 	}
 }
 
+// retrieveMetrics contacts the attached geth node and retrieves the entire set
+// of collected system metrics.
+func retrieveMetrics(xeth *rpc.Xeth) (map[string]interface{}, error) {
+	return xeth.Call("debug_metrics", []interface{}{true})
+}
+
 // resolveMetrics takes a list of input metric patterns, and resolves each to one
 // or more canonical metric names.
 func resolveMetrics(metrics map[string]interface{}, patterns []string) []string {
-- 
cgit v1.2.3