Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
d02f07a9
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d02f07a9
编写于
6月 25, 2015
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cmd/geth: polish monitor visuals, add footer, refresh flag
上级
b98b4441
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
71 addition
and
33 deletion
+71
-33
cmd/geth/monitorcmd.go
cmd/geth/monitorcmd.go
+71
-33
未找到文件。
cmd/geth/monitorcmd.go
浏览文件 @
d02f07a9
package
main
import
(
"fmt"
"math"
"reflect"
"sort"
...
...
@@ -20,12 +21,17 @@ var (
monitorCommandAttachFlag
=
cli
.
StringFlag
{
Name
:
"attach"
,
Value
:
"ipc:"
+
common
.
DefaultIpcPath
(),
Usage
:
"
IPC or RPC
API endpoint to attach to"
,
Usage
:
"API endpoint to attach to"
,
}
monitorCommandRowsFlag
=
cli
.
IntFlag
{
Name
:
"rows"
,
Value
:
5
,
Usage
:
"Rows (maximum) to display the charts in"
,
Usage
:
"Maximum rows in the chart grid"
,
}
monitorCommandRefreshFlag
=
cli
.
IntFlag
{
Name
:
"refresh"
,
Value
:
3
,
Usage
:
"Refresh interval in seconds"
,
}
monitorCommand
=
cli
.
Command
{
Action
:
monitor
,
...
...
@@ -39,6 +45,7 @@ to display multiple metrics simultaneously.
Flags
:
[]
cli
.
Flag
{
monitorCommandAttachFlag
,
monitorCommandRowsFlag
,
monitorCommandRefreshFlag
,
},
}
)
...
...
@@ -66,21 +73,6 @@ func monitor(ctx *cli.Context) {
monitored
:=
resolveMetrics
(
metrics
,
ctx
.
Args
())
sort
.
Strings
(
monitored
)
// Create the access function and check that the metric exists
value
:=
func
(
metrics
map
[
string
]
interface
{},
metric
string
)
float64
{
parts
,
found
:=
strings
.
Split
(
metric
,
"/"
),
true
for
_
,
part
:=
range
parts
[
:
len
(
parts
)
-
1
]
{
metrics
,
found
=
metrics
[
part
]
.
(
map
[
string
]
interface
{})
if
!
found
{
utils
.
Fatalf
(
"Metric not found: %s"
,
metric
)
}
}
if
v
,
ok
:=
metrics
[
parts
[
len
(
parts
)
-
1
]]
.
(
float64
);
ok
{
return
v
}
utils
.
Fatalf
(
"Metric not float64: %s"
,
metric
)
return
0
}
// Create and configure the chart UI defaults
if
err
:=
termui
.
Init
();
err
!=
nil
{
utils
.
Fatalf
(
"Unable to initialize terminal UI: %v"
,
err
)
...
...
@@ -98,6 +90,10 @@ func monitor(ctx *cli.Context) {
termui
.
Body
.
AddRows
(
termui
.
NewRow
())
}
// Create each individual data chart
footer
:=
termui
.
NewPar
(
""
)
footer
.
HasBorder
=
true
footer
.
Height
=
3
charts
:=
make
([]
*
termui
.
LineChart
,
len
(
monitored
))
data
:=
make
([][]
float64
,
len
(
monitored
))
for
i
:=
0
;
i
<
len
(
data
);
i
++
{
...
...
@@ -105,25 +101,28 @@ func monitor(ctx *cli.Context) {
}
for
i
,
metric
:=
range
monitored
{
charts
[
i
]
=
termui
.
NewLineChart
()
charts
[
i
]
.
Data
=
make
([]
float64
,
512
)
charts
[
i
]
.
DataLabels
=
[]
string
{
""
}
charts
[
i
]
.
Height
=
termui
.
TermHeight
(
)
/
rows
charts
[
i
]
.
Height
=
(
termui
.
TermHeight
()
-
footer
.
Height
)
/
rows
charts
[
i
]
.
AxesColor
=
termui
.
ColorWhite
charts
[
i
]
.
LineColor
=
termui
.
ColorGreen
charts
[
i
]
.
PaddingBottom
=
-
1
charts
[
i
]
.
Border
.
Label
=
metric
charts
[
i
]
.
Border
.
LabelFgColor
=
charts
[
i
]
.
Border
.
FgColor
charts
[
i
]
.
Border
.
LabelFgColor
=
charts
[
i
]
.
Border
.
FgColor
|
termui
.
AttrBold
charts
[
i
]
.
Border
.
FgColor
=
charts
[
i
]
.
Border
.
BgColor
row
:=
termui
.
Body
.
Rows
[
i
%
rows
]
row
.
Cols
=
append
(
row
.
Cols
,
termui
.
NewCol
(
12
/
cols
,
0
,
charts
[
i
]))
}
termui
.
Body
.
AddRows
(
termui
.
NewRow
(
termui
.
NewCol
(
12
,
0
,
footer
)))
termui
.
Body
.
Align
()
termui
.
Render
(
termui
.
Body
)
refresh
:=
time
.
Tick
(
time
.
Second
)
refreshCharts
(
xeth
,
monitored
,
data
,
charts
,
ctx
,
footer
)
termui
.
Render
(
termui
.
Body
)
// Watch for various system events, and periodically refresh the charts
refresh
:=
time
.
Tick
(
time
.
Duration
(
ctx
.
Int
(
monitorCommandRefreshFlag
.
Name
))
*
time
.
Second
)
for
{
select
{
case
event
:=
<-
termui
.
EventCh
()
:
...
...
@@ -133,20 +132,13 @@ func monitor(ctx *cli.Context) {
if
event
.
Type
==
termui
.
EventResize
{
termui
.
Body
.
Width
=
termui
.
TermWidth
()
for
_
,
chart
:=
range
charts
{
chart
.
Height
=
termui
.
TermHeight
(
)
/
rows
chart
.
Height
=
(
termui
.
TermHeight
()
-
footer
.
Height
)
/
rows
}
termui
.
Body
.
Align
()
termui
.
Render
(
termui
.
Body
)
}
case
<-
refresh
:
metrics
,
err
:=
retrieveMetrics
(
xeth
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Failed to retrieve system metrics: %v"
,
err
)
}
for
i
,
metric
:=
range
monitored
{
data
[
i
]
=
append
([]
float64
{
value
(
metrics
,
metric
)},
data
[
i
][
:
len
(
data
[
i
])
-
1
]
...
)
updateChart
(
metric
,
data
[
i
],
charts
[
i
])
}
refreshCharts
(
xeth
,
monitored
,
data
,
charts
,
ctx
,
footer
)
termui
.
Render
(
termui
.
Body
)
}
}
...
...
@@ -226,13 +218,42 @@ func expandMetrics(metrics map[string]interface{}, path string) []string {
return
list
}
// fetchMetric iterates over the metrics map and retrieves a specific one.
func
fetchMetric
(
metrics
map
[
string
]
interface
{},
metric
string
)
float64
{
parts
,
found
:=
strings
.
Split
(
metric
,
"/"
),
true
for
_
,
part
:=
range
parts
[
:
len
(
parts
)
-
1
]
{
metrics
,
found
=
metrics
[
part
]
.
(
map
[
string
]
interface
{})
if
!
found
{
return
0
}
}
if
v
,
ok
:=
metrics
[
parts
[
len
(
parts
)
-
1
]]
.
(
float64
);
ok
{
return
v
}
return
0
}
// refreshCharts retrieves a next batch of metrics, and inserts all the new
// values into the active datasets and charts
func
refreshCharts
(
xeth
*
rpc
.
Xeth
,
metrics
[]
string
,
data
[][]
float64
,
charts
[]
*
termui
.
LineChart
,
ctx
*
cli
.
Context
,
footer
*
termui
.
Par
)
{
values
,
err
:=
retrieveMetrics
(
xeth
)
for
i
,
metric
:=
range
metrics
{
data
[
i
]
=
append
([]
float64
{
fetchMetric
(
values
,
metric
)},
data
[
i
][
:
len
(
data
[
i
])
-
1
]
...
)
updateChart
(
metric
,
data
[
i
],
charts
[
i
],
err
)
}
updateFooter
(
ctx
,
err
,
footer
)
}
// 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
)
{
func
updateChart
(
metric
string
,
data
[]
float64
,
chart
*
termui
.
LineChart
,
err
error
)
{
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
}
// Extract only part of the data that's actually visible
data
=
data
[
:
chart
.
Width
*
2
]
// Find the maximum value and scale under 1K
high
:=
data
[
0
]
for
_
,
value
:=
range
data
[
1
:
]
{
...
...
@@ -256,5 +277,22 @@ func updateChart(metric string, data []float64, chart *termui.LineChart) {
if
len
(
units
[
unit
])
>
0
{
chart
.
Border
.
Label
+=
" ["
+
units
[
unit
]
+
"]"
}
chart
.
LineColor
=
colors
[
unit
]
chart
.
LineColor
=
colors
[
unit
]
|
termui
.
AttrBold
if
err
!=
nil
{
chart
.
LineColor
=
termui
.
ColorRed
|
termui
.
AttrBold
}
}
// updateFooter updates the footer contents based on any encountered errors.
func
updateFooter
(
ctx
*
cli
.
Context
,
err
error
,
footer
*
termui
.
Par
)
{
// Generate the basic footer
refresh
:=
time
.
Duration
(
ctx
.
Int
(
monitorCommandRefreshFlag
.
Name
))
*
time
.
Second
footer
.
Text
=
fmt
.
Sprintf
(
"Press q to quit. Refresh interval: %v."
,
refresh
)
footer
.
TextFgColor
=
termui
.
Theme
()
.
ParTextFg
|
termui
.
AttrBold
// Append any encountered errors
if
err
!=
nil
{
footer
.
Text
=
fmt
.
Sprintf
(
"Error: %v."
,
err
)
footer
.
TextFgColor
=
termui
.
ColorRed
|
termui
.
AttrBold
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录