cmd/geth: add attach and rows flags to the monitor command
This commit is contained in:
parent
1ce40d7581
commit
b98b444179
|
@ -72,6 +72,7 @@ func init() {
|
||||||
upgradedbCommand,
|
upgradedbCommand,
|
||||||
removedbCommand,
|
removedbCommand,
|
||||||
dumpCommand,
|
dumpCommand,
|
||||||
|
monitorCommand,
|
||||||
{
|
{
|
||||||
Action: makedag,
|
Action: makedag,
|
||||||
Name: "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.
|
which exposes a node admin interface as well as the Ðapp JavaScript API.
|
||||||
See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
|
See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
|
||||||
This command allows to open a console on a running geth node.
|
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.
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,48 +9,61 @@ import (
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"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"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||||
"github.com/gizak/termui"
|
"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.
|
// monitor starts a terminal UI based monitoring tool for the requested metrics.
|
||||||
func monitor(ctx *cli.Context) {
|
func monitor(ctx *cli.Context) {
|
||||||
var (
|
var (
|
||||||
client comms.EthereumClient
|
client comms.EthereumClient
|
||||||
args []string
|
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
// Attach to an Ethereum node over IPC or RPC
|
// Attach to an Ethereum node over IPC or RPC
|
||||||
if ctx.Args().Present() {
|
endpoint := ctx.String(monitorCommandAttachFlag.Name)
|
||||||
// Try to interpret the first parameter as an endpoint
|
if client, err = comms.ClientFromEndpoint(endpoint, codec.JSON); err != nil {
|
||||||
client, err = comms.ClientFromEndpoint(ctx.Args().First(), codec.JSON)
|
utils.Fatalf("Unable to attach to geth node: %v", err)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
xeth := rpc.NewXeth(client)
|
xeth := rpc.NewXeth(client)
|
||||||
|
|
||||||
// Retrieve all the available metrics and resolve the user pattens
|
// 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 {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to retrieve system metrics: %v", err)
|
utils.Fatalf("Failed to retrieve system metrics: %v", err)
|
||||||
}
|
}
|
||||||
monitored := resolveMetrics(metrics, args)
|
monitored := resolveMetrics(metrics, ctx.Args())
|
||||||
sort.Strings(monitored)
|
sort.Strings(monitored)
|
||||||
|
|
||||||
// Create the access function and check that the metric exists
|
// Create the access function and check that the metric exists
|
||||||
|
@ -77,8 +90,8 @@ func monitor(ctx *cli.Context) {
|
||||||
termui.UseTheme("helloworld")
|
termui.UseTheme("helloworld")
|
||||||
|
|
||||||
rows := len(monitored)
|
rows := len(monitored)
|
||||||
if rows > 5 {
|
if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max {
|
||||||
rows = 5
|
rows = max
|
||||||
}
|
}
|
||||||
cols := (len(monitored) + rows - 1) / rows
|
cols := (len(monitored) + rows - 1) / rows
|
||||||
for i := 0; i < rows; i++ {
|
for i := 0; i < rows; i++ {
|
||||||
|
@ -126,7 +139,7 @@ func monitor(ctx *cli.Context) {
|
||||||
termui.Render(termui.Body)
|
termui.Render(termui.Body)
|
||||||
}
|
}
|
||||||
case <-refresh:
|
case <-refresh:
|
||||||
metrics, err := xeth.Call("debug_metrics", []interface{}{true})
|
metrics, err := retrieveMetrics(xeth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to retrieve system metrics: %v", err)
|
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
|
// resolveMetrics takes a list of input metric patterns, and resolves each to one
|
||||||
// or more canonical metric names.
|
// or more canonical metric names.
|
||||||
func resolveMetrics(metrics map[string]interface{}, patterns []string) []string {
|
func resolveMetrics(metrics map[string]interface{}, patterns []string) []string {
|
||||||
|
|
Loading…
Reference in New Issue