Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
蜕变的菜鸟
glances
提交
41342c81
G
glances
项目概览
蜕变的菜鸟
/
glances
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
glances
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
41342c81
编写于
10月 16, 2014
作者:
N
Nicolargo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add Network, FS, diskio to the graph generation feature
上级
94614e1f
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
312 addition
and
149 deletion
+312
-149
glances/core/glances_main.py
glances/core/glances_main.py
+1
-1
glances/outputs/glances_curses.py
glances/outputs/glances_curses.py
+85
-59
glances/outputs/glances_history.py
glances/outputs/glances_history.py
+111
-29
glances/plugins/glances_cpu.py
glances/plugins/glances_cpu.py
+5
-3
glances/plugins/glances_diskio.py
glances/plugins/glances_diskio.py
+10
-1
glances/plugins/glances_fs.py
glances/plugins/glances_fs.py
+13
-9
glances/plugins/glances_memswap.py
glances/plugins/glances_memswap.py
+31
-14
glances/plugins/glances_network.py
glances/plugins/glances_network.py
+13
-4
glances/plugins/glances_plugin.py
glances/plugins/glances_plugin.py
+43
-29
未找到文件。
glances/core/glances_main.py
浏览文件 @
41342c81
...
...
@@ -197,7 +197,7 @@ class GlancesMain(object):
if
not
os
.
access
(
args
.
path_history
,
os
.
W_OK
):
logger
.
critical
(
_
(
"History output path (%s) do not exist or is not writable"
)
%
args
.
path_history
)
sys
.
exit
(
2
)
logger
.
info
(
_
(
"History output path is
%s"
)
%
args
.
path_history
)
logger
.
debug
(
_
(
"History output path is set to
%s"
)
%
args
.
path_history
)
return
args
...
...
glances/outputs/glances_curses.py
浏览文件 @
41342c81
...
...
@@ -23,7 +23,7 @@
import
sys
# Import Glances lib
from
glances.core.glances_globals
import
glances_logs
,
glances_processes
,
is_
linux
,
is_bsd
,
is_
mac
,
is_windows
,
logger
from
glances.core.glances_globals
import
glances_logs
,
glances_processes
,
is_mac
,
is_windows
,
logger
from
glances.core.glances_timer
import
Timer
# Import curses lib for "normal" operating system and consolelog for Windows
...
...
@@ -31,9 +31,10 @@ if not is_windows:
try
:
import
curses
import
curses.panel
from
curses.textpad
import
Textbox
,
rectangle
from
curses.textpad
import
Textbox
except
ImportError
:
logger
.
critical
(
'Curses module not found. Glances cannot start in standalone mode.'
)
logger
.
critical
(
'Curses module not found. Glances cannot start in standalone mode.'
)
sys
.
exit
(
1
)
else
:
from
glances.outputs.glances_colorconsole
import
WCurseLight
...
...
@@ -184,15 +185,17 @@ class GlancesCurses(object):
self
.
reset_history_tag
=
False
self
.
history_tag
=
False
if
args
.
enable_history
:
logger
.
info
(
'Stats history enabled with output path %s'
%
args
.
path_history
)
logger
.
info
(
'Stats history enabled with output path %s'
%
args
.
path_history
)
from
glances.outputs.glances_history
import
GlancesHistory
self
.
glances_history
=
GlancesHistory
(
args
.
path_history
)
if
not
self
.
glances_history
.
graph_enabled
():
args
.
enable_history
=
False
logger
.
error
(
'Stats history disabled because MatPlotLib is not installed'
)
logger
.
error
(
'Stats history disabled because MatPlotLib is not installed'
)
def
set_cursor
(
self
,
value
):
"""Configure the cursor
"""Configure the cursor
0: invisible
1: visible
2: very visible
...
...
@@ -234,7 +237,7 @@ class GlancesCurses(object):
self
.
args
.
percpu
=
not
self
.
args
.
percpu
elif
self
.
pressedkey
==
ord
(
'2'
):
# '2' > Enable/disable left sidebar
self
.
args
.
disable_left_sidebar
=
not
self
.
args
.
disable_left_sidebar
self
.
args
.
disable_left_sidebar
=
not
self
.
args
.
disable_left_sidebar
elif
self
.
pressedkey
==
ord
(
'/'
):
# '/' > Switch between short/long name for processes
self
.
args
.
process_short_name
=
not
self
.
args
.
process_short_name
...
...
@@ -289,7 +292,7 @@ class GlancesCurses(object):
glances_processes
.
setmanualsortkey
(
self
.
args
.
process_sorted_by
)
elif
self
.
pressedkey
==
ord
(
'r'
):
# 'r' > Reset history
self
.
reset_history_tag
=
not
self
.
reset_history_tag
self
.
reset_history_tag
=
not
self
.
reset_history_tag
elif
self
.
pressedkey
==
ord
(
's'
):
# 's' > Show/hide sensors stats (Linux-only)
self
.
args
.
disable_sensors
=
not
self
.
args
.
disable_sensors
...
...
@@ -318,7 +321,7 @@ class GlancesCurses(object):
return
self
.
pressedkey
def
end
(
self
):
"""Shutdown the curses window."""
"""Shutdown the curses window."""
if
hasattr
(
curses
,
'echo'
):
curses
.
echo
()
if
hasattr
(
curses
,
'nocbreak'
):
...
...
@@ -329,7 +332,7 @@ class GlancesCurses(object):
except
Exception
:
pass
curses
.
endwin
()
def
init_line_column
(
self
):
"""Init the line and column position for the curses inteface"""
self
.
line
=
0
...
...
@@ -386,10 +389,10 @@ class GlancesCurses(object):
# Update the stats messages
###########################
# Update the client server status
self
.
args
.
cs_status
=
cs_status
stats_system
=
stats
.
get_plugin
(
'system'
).
get_stats_display
(
args
=
self
.
args
)
stats_system
=
stats
.
get_plugin
(
'system'
).
get_stats_display
(
args
=
self
.
args
)
stats_uptime
=
stats
.
get_plugin
(
'uptime'
).
get_stats_display
()
if
self
.
args
.
percpu
:
stats_percpu
=
stats
.
get_plugin
(
'percpu'
).
get_stats_display
()
...
...
@@ -398,27 +401,37 @@ class GlancesCurses(object):
stats_load
=
stats
.
get_plugin
(
'load'
).
get_stats_display
()
stats_mem
=
stats
.
get_plugin
(
'mem'
).
get_stats_display
()
stats_memswap
=
stats
.
get_plugin
(
'memswap'
).
get_stats_display
()
stats_network
=
stats
.
get_plugin
(
'network'
).
get_stats_display
(
args
=
self
.
args
,
max_width
=
plugin_max_width
)
stats_diskio
=
stats
.
get_plugin
(
'diskio'
).
get_stats_display
(
args
=
self
.
args
)
stats_fs
=
stats
.
get_plugin
(
'fs'
).
get_stats_display
(
args
=
self
.
args
,
max_width
=
plugin_max_width
)
stats_sensors
=
stats
.
get_plugin
(
'sensors'
).
get_stats_display
(
args
=
self
.
args
)
stats_network
=
stats
.
get_plugin
(
'network'
).
get_stats_display
(
args
=
self
.
args
,
max_width
=
plugin_max_width
)
stats_diskio
=
stats
.
get_plugin
(
'diskio'
).
get_stats_display
(
args
=
self
.
args
)
stats_fs
=
stats
.
get_plugin
(
'fs'
).
get_stats_display
(
args
=
self
.
args
,
max_width
=
plugin_max_width
)
stats_sensors
=
stats
.
get_plugin
(
'sensors'
).
get_stats_display
(
args
=
self
.
args
)
stats_now
=
stats
.
get_plugin
(
'now'
).
get_stats_display
()
stats_processcount
=
stats
.
get_plugin
(
'processcount'
).
get_stats_display
(
args
=
self
.
args
)
stats_monitor
=
stats
.
get_plugin
(
'monitor'
).
get_stats_display
(
args
=
self
.
args
)
stats_alert
=
stats
.
get_plugin
(
'alert'
).
get_stats_display
(
args
=
self
.
args
)
stats_processcount
=
stats
.
get_plugin
(
'processcount'
).
get_stats_display
(
args
=
self
.
args
)
stats_monitor
=
stats
.
get_plugin
(
'monitor'
).
get_stats_display
(
args
=
self
.
args
)
stats_alert
=
stats
.
get_plugin
(
'alert'
).
get_stats_display
(
args
=
self
.
args
)
# Adapt number of processes to the available space
max_processes_displayed
=
screen_y
-
11
-
self
.
get_stats_display_height
(
stats_alert
)
max_processes_displayed
=
screen_y
-
11
-
\
self
.
get_stats_display_height
(
stats_alert
)
if
not
self
.
args
.
disable_process_extended
:
max_processes_displayed
-=
4
if
max_processes_displayed
<
0
:
max_processes_displayed
=
0
max_processes_displayed
=
0
if
glances_processes
.
get_max_processes
()
is
None
or
\
glances_processes
.
get_max_processes
()
!=
max_processes_displayed
:
logger
.
debug
(
_
(
"Set number of displayed processes to %s"
)
%
max_processes_displayed
)
logger
.
debug
(
_
(
"Set number of displayed processes to %s"
)
%
max_processes_displayed
)
glances_processes
.
set_max_processes
(
max_processes_displayed
)
stats_processlist
=
stats
.
get_plugin
(
'processlist'
).
get_stats_display
(
args
=
self
.
args
)
stats_processlist
=
stats
.
get_plugin
(
'processlist'
).
get_stats_display
(
args
=
self
.
args
)
# Display the stats on the curses interface
###########################################
...
...
@@ -426,13 +439,15 @@ class GlancesCurses(object):
# Help screen (on top of the other stats)
if
self
.
args
.
help_tag
:
# Display the stats...
self
.
display_plugin
(
stats
.
get_plugin
(
'help'
).
get_stats_display
(
args
=
self
.
args
))
self
.
display_plugin
(
stats
.
get_plugin
(
'help'
).
get_stats_display
(
args
=
self
.
args
))
# ... and exit
return
False
# Display first line (system+uptime)
self
.
new_line
()
l
=
self
.
get_stats_display_width
(
stats_system
)
+
self
.
get_stats_display_width
(
stats_uptime
)
+
self
.
space_between_column
l
=
self
.
get_stats_display_width
(
stats_system
)
+
self
.
get_stats_display_width
(
stats_uptime
)
+
self
.
space_between_column
self
.
display_plugin
(
stats_system
,
display_optional
=
(
screen_x
>=
l
))
self
.
new_column
()
self
.
display_plugin
(
stats_uptime
)
...
...
@@ -440,14 +455,16 @@ class GlancesCurses(object):
# Display second line (CPU|PERCPU+LOAD+MEM+SWAP+<SUMMARY>)
# CPU|PERCPU
self
.
init_column
()
self
.
new_line
()
self
.
new_line
()
if
self
.
args
.
percpu
:
l
=
self
.
get_stats_display_width
(
stats_percpu
)
else
:
l
=
self
.
get_stats_display_width
(
stats_cpu
)
l
+=
self
.
get_stats_display_width
(
stats_load
)
+
self
.
get_stats_display_width
(
stats_mem
)
+
self
.
get_stats_display_width
(
stats_memswap
)
l
+=
self
.
get_stats_display_width
(
stats_load
)
+
self
.
get_stats_display_width
(
stats_mem
)
+
self
.
get_stats_display_width
(
stats_memswap
)
# Space between column
space_number
=
int
(
stats_load
[
'msgdict'
]
!=
[])
+
int
(
stats_mem
[
'msgdict'
]
!=
[])
+
int
(
stats_memswap
[
'msgdict'
]
!=
[])
space_number
=
int
(
stats_load
[
'msgdict'
]
!=
[
])
+
int
(
stats_mem
[
'msgdict'
]
!=
[])
+
int
(
stats_memswap
[
'msgdict'
]
!=
[])
if
space_number
==
0
:
space_number
=
1
if
screen_x
>
(
space_number
*
self
.
space_between_column
+
l
):
...
...
@@ -460,7 +477,8 @@ class GlancesCurses(object):
self
.
new_column
()
self
.
display_plugin
(
stats_load
)
self
.
new_column
()
self
.
display_plugin
(
stats_mem
,
display_optional
=
(
screen_x
>=
(
space_number
*
self
.
space_between_column
+
l
)))
self
.
display_plugin
(
stats_mem
,
display_optional
=
(
screen_x
>=
(
space_number
*
self
.
space_between_column
+
l
)))
self
.
new_column
()
self
.
display_plugin
(
stats_memswap
)
# Space between column
...
...
@@ -471,9 +489,9 @@ class GlancesCurses(object):
# Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time)
self
.
init_column
()
if
(
not
(
self
.
args
.
disable_network
and
self
.
args
.
disable_diskio
\
and
self
.
args
.
disable_fs
and
self
.
args
.
disable_sensors
))
\
and
not
self
.
args
.
disable_left_sidebar
:
if
(
not
(
self
.
args
.
disable_network
and
self
.
args
.
disable_diskio
and
self
.
args
.
disable_fs
and
self
.
args
.
disable_sensors
))
\
and
not
self
.
args
.
disable_left_sidebar
:
self
.
new_line
()
self
.
display_plugin
(
stats_network
)
self
.
new_line
()
...
...
@@ -490,18 +508,19 @@ class GlancesCurses(object):
# Restore line position
self
.
next_line
=
self
.
saved_line
# Display right sidebar (PROCESS_COUNT+MONITORED+PROCESS_LIST+ALERT)
# Display right sidebar
# (PROCESS_COUNT+MONITORED+PROCESS_LIST+ALERT)
self
.
new_column
()
self
.
new_line
()
self
.
display_plugin
(
stats_processcount
)
if
glances_processes
.
get_process_filter
()
==
None
and
cs_status
==
'None'
:
if
glances_processes
.
get_process_filter
()
is
None
and
cs_status
==
'None'
:
# Do not display stats monitor list if a filter exist
self
.
new_line
()
self
.
display_plugin
(
stats_monitor
)
self
.
new_line
()
self
.
display_plugin
(
stats_processlist
,
display_optional
=
(
screen_x
>
102
),
display_additional
=
(
is_mac
==
False
),
display_additional
=
(
not
is_mac
),
max_y
=
(
screen_y
-
self
.
get_stats_display_height
(
stats_alert
)
-
2
))
self
.
new_line
()
self
.
display_plugin
(
stats_alert
)
...
...
@@ -509,36 +528,40 @@ class GlancesCurses(object):
# History option
# Generate history graph
if
self
.
history_tag
and
self
.
args
.
enable_history
:
self
.
display_popup
(
_
(
"Graphs history generated in %s"
)
%
self
.
glances_history
.
get_output_folder
())
self
.
display_popup
(
_
(
"Generate graphs history in %s
\n
Please wait..."
)
%
self
.
glances_history
.
get_output_folder
())
self
.
glances_history
.
generate_graph
(
stats
)
elif
self
.
reset_history_tag
and
self
.
args
.
enable_history
:
self
.
display_popup
(
_
(
"Reset history"
))
self
.
glances_history
.
reset
(
stats
)
self
.
glances_history
.
reset
(
stats
)
elif
(
self
.
history_tag
or
self
.
reset_history_tag
)
and
not
self
.
args
.
enable_history
:
try
:
self
.
glances_history
.
graph_enabled
()
except
:
self
.
display_popup
(
_
(
"History disabled
\n
Enable it using --enable-history"
))
self
.
display_popup
(
_
(
"History disabled
\n
Enable it using --enable-history"
))
else
:
self
.
display_popup
(
_
(
"History disabled
\n
Please install MatPlotLib"
))
self
.
display_popup
(
_
(
"History disabled
\n
Please install MatPlotLib"
))
self
.
history_tag
=
False
self
.
reset_history_tag
=
False
# Display edit filter popup
# Only in standalone mode (cs_status == 'None')
if
self
.
edit_filter
and
cs_status
==
'None'
:
new_filter
=
self
.
display_popup
(
_
(
"Process filter pattern: "
),
new_filter
=
self
.
display_popup
(
_
(
"Process filter pattern: "
),
is_input
=
True
,
input_value
=
glances_processes
.
get_process_filter
())
glances_processes
.
set_process_filter
(
new_filter
)
elif
self
.
edit_filter
and
cs_status
!=
'None'
:
self
.
display_popup
(
_
(
"Process filter only available in standalone mode"
))
self
.
display_popup
(
_
(
"Process filter only available in standalone mode"
))
self
.
edit_filter
=
False
return
True
def
display_popup
(
self
,
message
,
size_x
=
None
,
size_y
=
None
,
def
display_popup
(
self
,
message
,
size_x
=
None
,
size_y
=
None
,
duration
=
3
,
is_input
=
False
,
input_size
=
30
,
...
...
@@ -553,7 +576,7 @@ class GlancesCurses(object):
Display a centered popup with the given message and a input field
If size_x and size_y: set the popup size
else set it automatically
Return the input string or None if the field is empty
Return the input string or None if the field is empty
"""
# Center the popup
...
...
@@ -568,13 +591,13 @@ class GlancesCurses(object):
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
if
size_x
>
screen_x
or
size_y
>
screen_y
:
# No size to display the popup => abord
return
False
return
False
pos_x
=
int
((
screen_x
-
size_x
)
/
2
)
pos_y
=
int
((
screen_y
-
size_y
)
/
2
)
# Create the popup
popup
=
curses
.
newwin
(
size_y
,
size_x
,
pos_y
,
pos_x
)
# Fill the popup
popup
.
border
()
...
...
@@ -600,7 +623,8 @@ class GlancesCurses(object):
textbox
.
edit
()
self
.
set_cursor
(
0
)
if
textbox
.
gather
()
!=
''
:
logger
.
debug
(
_
(
"User enters the following process filter patern: %s"
)
%
textbox
.
gather
())
logger
.
debug
(
_
(
"User enters the following process filter patern: %s"
)
%
textbox
.
gather
())
return
textbox
.
gather
()[:
-
1
]
else
:
logger
.
debug
(
_
(
"User clears the process filter patern"
))
...
...
@@ -611,9 +635,9 @@ class GlancesCurses(object):
curses
.
napms
(
duration
*
1000
)
return
True
def
display_plugin
(
self
,
plugin_stats
,
def
display_plugin
(
self
,
plugin_stats
,
display_optional
=
True
,
display_additional
=
True
,
display_additional
=
True
,
max_y
=
65535
):
"""Display the plugin_stats on the screen.
...
...
@@ -643,7 +667,7 @@ class GlancesCurses(object):
display_y
=
screen_y
-
self
.
get_stats_display_height
(
plugin_stats
)
else
:
display_y
=
self
.
line
# Display
x
=
display_x
y
=
display_y
...
...
@@ -673,8 +697,9 @@ class GlancesCurses(object):
try
:
self
.
term_window
.
addnstr
(
y
,
x
,
m
[
'msg'
],
screen_x
-
x
,
# Do not disply outside the screen
self
.
__colors_list
[
m
[
'decoration'
]])
# Do not disply outside the screen
screen_x
-
x
,
self
.
__colors_list
[
m
[
'decoration'
]])
except
:
pass
else
:
...
...
@@ -721,7 +746,7 @@ class GlancesCurses(object):
# Getkey
if
self
.
__catch_key
()
>
-
1
:
# Redraw display
self
.
flush
(
stats
,
cs_status
=
cs_status
)
self
.
flush
(
stats
,
cs_status
=
cs_status
)
# Wait 100ms...
curses
.
napms
(
100
)
...
...
@@ -734,11 +759,11 @@ class GlancesCurses(object):
if
without_option
:
# Size without options
c
=
len
(
max
(
''
.
join
([(
i
[
'msg'
]
if
not
i
[
'optional'
]
else
""
)
for
i
in
curse_msg
[
'msgdict'
]]).
split
(
'
\n
'
),
key
=
len
))
for
i
in
curse_msg
[
'msgdict'
]]).
split
(
'
\n
'
),
key
=
len
))
else
:
# Size with all options
c
=
len
(
max
(
''
.
join
([
i
[
'msg'
]
for
i
in
curse_msg
[
'msgdict'
]]).
split
(
'
\n
'
),
key
=
len
))
for
i
in
curse_msg
[
'msgdict'
]]).
split
(
'
\n
'
),
key
=
len
))
except
:
return
0
else
:
...
...
@@ -758,14 +783,15 @@ class GlancesCurses(object):
if
not
is_windows
:
class
glances_textbox
(
Textbox
):
"""
"""
def
__init__
(
*
args
,
**
kwargs
):
Textbox
.
__init__
(
*
args
,
**
kwargs
)
def
do_command
(
self
,
ch
):
if
ch
==
10
:
# Enter
if
ch
==
10
:
# Enter
return
0
if
ch
==
127
:
# Enter
if
ch
==
127
:
# Enter
return
8
return
Textbox
.
do_command
(
self
,
ch
)
\ No newline at end of file
return
Textbox
.
do_command
(
self
,
ch
)
glances/outputs/glances_history.py
浏览文件 @
41342c81
...
...
@@ -29,10 +29,10 @@ from glances.core.glances_globals import logger
try
:
from
matplotlib
import
__version__
as
matplotlib_version
import
matplotlib.pyplot
as
plt
import
matplotlib.dates
as
dates
except
:
matplotlib_check
=
False
logger
.
warning
(
'Can not load Matplotlib library. Please install it using "pip install matplotlib"'
)
logger
.
warning
(
'Can not load Matplotlib library. Please install it using "pip install matplotlib"'
)
else
:
matplotlib_check
=
True
logger
.
info
(
'Load Matplotlib version %s'
%
matplotlib_version
)
...
...
@@ -65,6 +65,28 @@ class GlancesHistory(object):
stats
.
get_plugin
(
p
).
reset_stats_history
()
return
True
def
get_graph_color
(
self
,
item
):
"""
Get the item's color
"""
try
:
ret
=
item
[
'color'
]
except
KeyError
:
return
'#FFFFFF'
else
:
return
ret
def
get_graph_ylegend
(
self
,
item
):
"""
Get the item's Y legend
"""
try
:
ret
=
item
[
'label_y'
]
except
KeyError
:
return
''
else
:
return
' '
+
ret
def
generate_graph
(
self
,
stats
):
"""
Generate graphs from plugins history
...
...
@@ -74,32 +96,92 @@ class GlancesHistory(object):
for
p
in
stats
.
getAllPlugins
():
h
=
stats
.
get_plugin
(
p
).
get_stats_history
()
if
h
is
not
None
:
# Build the graph
# fig = plt.figure(dpi=72)
ax
=
plt
.
subplot
(
1
,
1
,
1
)
# Label
plt
.
title
(
"%s stats"
%
p
)
handles
=
[]
for
i
in
stats
.
get_plugin
(
p
).
get_items_history_list
():
handles
.
append
(
plt
.
Rectangle
((
0
,
0
),
1
,
1
,
fc
=
i
[
'color'
],
ec
=
i
[
'color'
],
linewidth
=
1
))
labels
=
[
i
[
'name'
]
for
i
in
stats
.
get_plugin
(
p
).
get_items_history_list
()]
plt
.
legend
(
handles
,
labels
,
loc
=
1
,
prop
=
{
'size'
:
9
})
formatter
=
dates
.
DateFormatter
(
'%H:%M:%S'
)
ax
.
xaxis
.
set_major_formatter
(
formatter
)
# ax.set_ylabel('%')
# Draw the stats
for
i
in
stats
.
get_plugin
(
p
).
get_items_history_list
():
ax
.
plot_date
(
h
[
'date'
],
h
[
i
[
'name'
]],
i
[
'color'
],
label
=
'%s'
%
i
[
'name'
],
xdate
=
True
,
ydate
=
False
)
# Save and display
plt
.
savefig
(
os
.
path
.
join
(
self
.
output_folder
,
'glances_%s.png'
%
p
),
dpi
=
72
)
# plt.show()
# Init graph
plt
.
clf
()
fig
=
plt
.
gcf
()
fig
.
set_size_inches
(
20
,
10
)
# Data
if
h
is
None
:
# History (h) not available for plugin (p)
continue
index_graph
=
0
for
i
in
stats
.
get_plugin
(
p
).
get_items_history_list
():
if
i
[
'name'
]
in
h
.
keys
():
# The key exist
# Add the curve in the current chart
logger
.
debug
(
"Generate graph: %s %s"
%
(
p
,
i
[
'name'
]))
index_graph
+=
1
plt
.
title
(
p
.
capitalize
())
plt
.
subplot
(
len
(
stats
.
get_plugin
(
p
).
get_items_history_list
()),
1
,
index_graph
)
plt
.
ylabel
(
i
[
'name'
]
+
self
.
get_graph_ylegend
(
i
))
plt
.
grid
(
True
)
plt
.
plot_date
(
h
[
'date'
],
h
[
i
[
'name'
]],
fmt
=
''
,
drawstyle
=
'default'
,
linestyle
=
'-'
,
color
=
self
.
get_graph_color
(
i
),
xdate
=
True
,
ydate
=
False
)
else
:
# The key did not exist
# Find if anothers key ends with the key
# Ex: key='tx' => 'ethernet_tx'
stats_history_filtered
=
sorted
([
key
for
key
in
h
.
keys
()
if
key
.
endswith
(
i
[
'name'
])])
logger
.
debug
(
"Generate graphs: %s %s"
%
(
p
,
stats_history_filtered
))
if
len
(
stats_history_filtered
)
>
0
:
# Create 'n' graph
# Each graph iter through the stats
plt
.
clf
()
index_item
=
0
for
k
in
stats_history_filtered
:
index_item
+=
1
plt
.
title
(
p
.
capitalize
())
plt
.
subplot
(
len
(
stats_history_filtered
),
1
,
index_item
)
plt
.
ylabel
(
k
+
self
.
get_graph_ylegend
(
i
))
plt
.
grid
(
True
)
plt
.
plot_date
(
h
[
'date'
],
h
[
k
],
fmt
=
''
,
drawstyle
=
'default'
,
linestyle
=
'-'
,
color
=
self
.
get_graph_color
(
i
),
xdate
=
True
,
ydate
=
False
)
# Save the graph to output file
plt
.
xlabel
(
'Date'
)
plt
.
savefig
(
os
.
path
.
join
(
self
.
output_folder
,
'glances_%s_%s.png'
%
(
p
,
i
[
'name'
])),
dpi
=
72
)
if
index_graph
>
0
:
# Save the graph to output file
plt
.
xlabel
(
'Date'
)
plt
.
savefig
(
os
.
path
.
join
(
self
.
output_folder
,
'glances_%s.png'
%
(
p
)),
dpi
=
72
)
plt
.
close
()
return
True
def
generate_graph_OLD
(
self
,
stats
):
"""
Generate graphs from plugins history
"""
if
not
self
.
graph_enabled
():
return
False
for
p
in
stats
.
getAllPlugins
():
h
=
stats
.
get_plugin
(
p
).
get_stats_history
()
# Generate graph (init)
plt
.
clf
()
# Title and axis
plt
.
title
(
p
.
capitalize
())
plt
.
grid
(
True
)
if
h
is
not
None
:
# History (h) available for plugin (p)
index
=
1
for
k
,
v
in
h
.
iteritems
():
if
k
!=
'date'
:
plt
.
subplot
(
len
(
h
),
1
,
index
)
index
+=
1
plt
.
xlabel
(
'Date'
)
plt
.
ylabel
(
self
.
get_graph_ylegend
(
stats
,
p
,
k
))
# Data
plt
.
plot_date
(
h
[
'date'
],
h
[
k
],
fmt
=
''
,
drawstyle
=
'default'
,
linestyle
=
'-'
,
color
=
self
.
get_graph_color
(
stats
,
p
,
k
),
xdate
=
True
,
ydate
=
False
)
# Save the graph to output file
plt
.
savefig
(
os
.
path
.
join
(
self
.
output_folder
,
'glances_%s_%s.png'
%
(
p
,
k
)),
dpi
=
72
)
return
True
glances/plugins/glances_cpu.py
浏览文件 @
41342c81
...
...
@@ -34,10 +34,12 @@ snmp_oid = {'default': {'user': '1.3.6.1.4.1.2021.11.9.0',
'esxi'
:
{
'percent'
:
'1.3.6.1.2.1.25.3.3.1.2'
}}
# Define the history items list
# 'color' define the graph color in #RGB format
# - 'name' define the stat identifier
# - 'color' define the graph color in #RGB format
# - 'label_y' define the Y label
# All items in this list will be historised if the --enable-history tag is set
items_history_list
=
[{
'name'
:
'user'
,
'color'
:
'#00FF00'
},
{
'name'
:
'system'
,
'color'
:
'#FF0000'
}]
items_history_list
=
[{
'name'
:
'user'
,
'color'
:
'#00FF00'
,
'label_y'
:
'(%)'
},
{
'name'
:
'system'
,
'color'
:
'#FF0000'
,
'label_y'
:
'(%)'
}]
class
Plugin
(
GlancesPlugin
):
...
...
glances/plugins/glances_diskio.py
浏览文件 @
41342c81
...
...
@@ -25,6 +25,12 @@ from glances.plugins.glances_plugin import GlancesPlugin
import
psutil
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list
=
[{
'name'
:
'read_bytes'
,
'color'
:
'#00FF00'
,
'label_y'
:
'(B/s)'
},
{
'name'
:
'write_bytes'
,
'color'
:
'#FF0000'
,
'label_y'
:
'(B/s)'
}]
class
Plugin
(
GlancesPlugin
):
...
...
@@ -35,7 +41,7 @@ class Plugin(GlancesPlugin):
def
__init__
(
self
,
args
=
None
):
"""Init the plugin."""
GlancesPlugin
.
__init__
(
self
,
args
=
args
)
GlancesPlugin
.
__init__
(
self
,
args
=
args
,
items_history_list
=
items_history_list
)
# We want to display the stat in the curse interface
self
.
display_curse
=
True
...
...
@@ -104,6 +110,9 @@ class Plugin(GlancesPlugin):
# No standard way for the moment...
pass
# Update the history list
self
.
update_stats_history
(
'disk_name'
)
return
self
.
stats
def
msg_curse
(
self
,
args
=
None
):
...
...
glances/plugins/glances_fs.py
浏览文件 @
41342c81
...
...
@@ -19,11 +19,7 @@
"""File system plugin."""
# System libs
import
base64
# Glances libs
from
glances.core.glances_globals
import
version
,
logger
from
glances.plugins.glances_plugin
import
GlancesPlugin
# PSutil lib for local grab
...
...
@@ -54,6 +50,11 @@ snmp_oid = {'default': {'mnt_point': '1.3.6.1.4.1.2021.9.1.2',
'used'
:
'1.3.6.1.2.1.25.2.3.1.6'
}}
snmp_oid
[
'esxi'
]
=
snmp_oid
[
'windows'
]
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list
=
[{
'name'
:
'percent'
,
'color'
:
'#00FF00'
}]
class
Plugin
(
GlancesPlugin
):
...
...
@@ -64,7 +65,7 @@ class Plugin(GlancesPlugin):
def
__init__
(
self
,
args
=
None
):
"""Init the plugin."""
GlancesPlugin
.
__init__
(
self
,
args
=
args
)
GlancesPlugin
.
__init__
(
self
,
args
=
args
,
items_history_list
=
items_history_list
)
# We want to display the stat in the curse interface
self
.
display_curse
=
True
...
...
@@ -114,12 +115,12 @@ class Plugin(GlancesPlugin):
elif
self
.
get_input
()
==
'snmp'
:
# Update stats using SNMP
# SNMP bulk command to get all file system in one shot
# SNMP bulk command to get all file system in one shot
try
:
fs_stat
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
self
.
get_short_system_name
()],
fs_stat
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
self
.
get_short_system_name
()],
bulk
=
True
)
except
KeyError
:
fs_stat
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
'default'
],
fs_stat
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
'default'
],
bulk
=
True
)
# Loop over fs
...
...
@@ -135,7 +136,7 @@ class Plugin(GlancesPlugin):
fs_current
[
'size'
]
=
int
(
fs_stat
[
fs
][
'size'
])
*
int
(
fs_stat
[
fs
][
'alloc_unit'
])
fs_current
[
'used'
]
=
int
(
fs_stat
[
fs
][
'used'
])
*
int
(
fs_stat
[
fs
][
'alloc_unit'
])
fs_current
[
'percent'
]
=
float
(
fs_current
[
'used'
]
*
100
/
fs_current
[
'size'
])
self
.
stats
.
append
(
fs_current
)
self
.
stats
.
append
(
fs_current
)
else
:
# Default behavor
for
fs
in
fs_stat
:
...
...
@@ -147,6 +148,9 @@ class Plugin(GlancesPlugin):
fs_current
[
'percent'
]
=
float
(
fs_stat
[
fs
][
'percent'
])
self
.
stats
.
append
(
fs_current
)
# Update the history list
self
.
update_stats_history
(
'mnt_point'
)
return
self
.
stats
def
msg_curse
(
self
,
args
=
None
,
max_width
=
None
):
...
...
glances/plugins/glances_memswap.py
浏览文件 @
41342c81
...
...
@@ -31,7 +31,12 @@ snmp_oid = {'default': {'total': '1.3.6.1.4.1.2021.4.3.0',
'windows'
:
{
'mnt_point'
:
'1.3.6.1.2.1.25.2.3.1.3'
,
'alloc_unit'
:
'1.3.6.1.2.1.25.2.3.1.4'
,
'size'
:
'1.3.6.1.2.1.25.2.3.1.5'
,
'used'
:
'1.3.6.1.2.1.25.2.3.1.6'
}}
'used'
:
'1.3.6.1.2.1.25.2.3.1.6'
}}
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list
=
[{
'name'
:
'percent'
,
'color'
:
'#00FF00'
}]
class
Plugin
(
GlancesPlugin
):
...
...
@@ -43,7 +48,8 @@ class Plugin(GlancesPlugin):
def
__init__
(
self
,
args
=
None
):
"""Init the plugin."""
GlancesPlugin
.
__init__
(
self
,
args
=
args
)
GlancesPlugin
.
__init__
(
self
,
args
=
args
,
items_history_list
=
items_history_list
)
# We want to display the stat in the curse interface
self
.
display_curse
=
True
...
...
@@ -71,7 +77,8 @@ class Plugin(GlancesPlugin):
# free: free swap memory in bytes
# percent: the percentage usage
# sin: the number of bytes the system has swapped in from disk (cumulative)
# sout: the number of bytes the system has swapped out from disk (cumulative)
# sout: the number of bytes the system has swapped out from disk
# (cumulative)
for
swap
in
[
'total'
,
'used'
,
'free'
,
'percent'
,
'sin'
,
'sout'
]:
if
hasattr
(
sm_stats
,
swap
):
...
...
@@ -81,21 +88,26 @@ class Plugin(GlancesPlugin):
if
self
.
get_short_system_name
()
==
'windows'
:
# Mem stats for Windows OS are stored in the FS table
try
:
fs_stat
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
self
.
get_short_system_name
()],
fs_stat
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
self
.
get_short_system_name
()],
bulk
=
True
)
except
KeyError
:
self
.
reset
()
else
:
for
fs
in
fs_stat
:
# The virtual memory concept is used by the operating system to extend (virtually) the physical
# memory and thus to run more programs by swapping unused memory zone (page) to a disk file.
for
fs
in
fs_stat
:
# The virtual memory concept is used by the operating system to extend (virtually) the physical
# memory and thus to run more programs by swapping
# unused memory zone (page) to a disk file.
if
fs
==
'Virtual Memory'
:
self
.
stats
[
'total'
]
=
int
(
fs_stat
[
fs
][
'size'
])
*
int
(
fs_stat
[
fs
][
'alloc_unit'
])
self
.
stats
[
'used'
]
=
int
(
fs_stat
[
fs
][
'used'
])
*
int
(
fs_stat
[
fs
][
'alloc_unit'
])
self
.
stats
[
'percent'
]
=
float
(
self
.
stats
[
'used'
]
*
100
/
self
.
stats
[
'total'
])
self
.
stats
[
'free'
]
=
self
.
stats
[
'total'
]
-
self
.
stats
[
'used'
]
self
.
stats
[
'total'
]
=
int
(
fs_stat
[
fs
][
'size'
])
*
int
(
fs_stat
[
fs
][
'alloc_unit'
])
self
.
stats
[
'used'
]
=
int
(
fs_stat
[
fs
][
'used'
])
*
int
(
fs_stat
[
fs
][
'alloc_unit'
])
self
.
stats
[
'percent'
]
=
float
(
self
.
stats
[
'used'
]
*
100
/
self
.
stats
[
'total'
])
self
.
stats
[
'free'
]
=
self
.
stats
[
'total'
]
-
self
.
stats
[
'used'
]
break
else
:
else
:
self
.
stats
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
'default'
])
if
self
.
stats
[
'total'
]
==
''
:
...
...
@@ -109,8 +121,13 @@ class Plugin(GlancesPlugin):
# used=total-free
self
.
stats
[
'used'
]
=
self
.
stats
[
'total'
]
-
self
.
stats
[
'free'
]
# percent: the percentage usage calculated as (total - available) / total * 100.
self
.
stats
[
'percent'
]
=
float
((
self
.
stats
[
'total'
]
-
self
.
stats
[
'free'
])
/
self
.
stats
[
'total'
]
*
100
)
# percent: the percentage usage calculated as (total -
# available) / total * 100.
self
.
stats
[
'percent'
]
=
float
(
(
self
.
stats
[
'total'
]
-
self
.
stats
[
'free'
])
/
self
.
stats
[
'total'
]
*
100
)
# Update the history list
self
.
update_stats_history
()
return
self
.
stats
...
...
glances/plugins/glances_network.py
浏览文件 @
41342c81
...
...
@@ -33,6 +33,12 @@ snmp_oid = {'default': {'interface_name': '1.3.6.1.2.1.2.2.1.2',
'cumulative_rx'
:
'1.3.6.1.2.1.2.2.1.10'
,
'cumulative_tx'
:
'1.3.6.1.2.1.2.2.1.16'
}}
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
# 'color' define the graph color in #RGB format
items_history_list
=
[{
'name'
:
'rx'
,
'color'
:
'#00FF00'
,
'label_y'
:
'(bit/s)'
},
{
'name'
:
'tx'
,
'color'
:
'#FF0000'
,
'label_y'
:
'(bit/s)'
}]
class
Plugin
(
GlancesPlugin
):
...
...
@@ -43,7 +49,7 @@ class Plugin(GlancesPlugin):
def
__init__
(
self
,
args
=
None
):
"""Init the plugin."""
GlancesPlugin
.
__init__
(
self
,
args
=
args
)
GlancesPlugin
.
__init__
(
self
,
args
=
args
,
items_history_list
=
items_history_list
)
# We want to display the stat in the curse interface
self
.
display_curse
=
True
...
...
@@ -90,7 +96,7 @@ class Plugin(GlancesPlugin):
for
net
in
network_new
:
try
:
# Try necessary to manage dynamic network interface
netstat
=
{}
netstat
=
{}
netstat
[
'interface_name'
]
=
net
netstat
[
'time_since_update'
]
=
time_since_update
netstat
[
'cumulative_rx'
]
=
network_new
[
net
].
bytes_recv
...
...
@@ -115,10 +121,10 @@ class Plugin(GlancesPlugin):
# SNMP bulk command to get all network interface in one shot
try
:
netiocounters
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
self
.
get_short_system_name
()],
netiocounters
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
self
.
get_short_system_name
()],
bulk
=
True
)
except
KeyError
:
netiocounters
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
'default'
],
netiocounters
=
self
.
set_stats_snmp
(
snmp_oid
=
snmp_oid
[
'default'
],
bulk
=
True
)
# Previous network interface stats are stored in the network_old variable
...
...
@@ -166,6 +172,9 @@ class Plugin(GlancesPlugin):
# Save stats to compute next bitrate
self
.
network_old
=
network_new
# Update the history list
self
.
update_stats_history
(
'interface_name'
)
return
self
.
stats
def
msg_curse
(
self
,
args
=
None
,
max_width
=
None
):
...
...
glances/plugins/glances_plugin.py
浏览文件 @
41342c81
...
...
@@ -70,39 +70,48 @@ class GlancesPlugin(object):
"""Return the human-readable stats."""
return
str
(
self
.
stats
)
def
add_item_history
(
self
,
key
,
value
):
"""Add an new item (key, value) to the current history"""
try
:
self
.
stats_history
[
key
].
append
(
value
)
except
KeyError
:
self
.
stats_history
[
key
]
=
[
value
]
def
init_stats_history
(
self
):
"""Init the stats history (dict of list)"""
ret
=
None
if
self
.
args
is
not
None
and
self
.
args
.
enable_history
and
self
.
get_items_history_list
()
is
not
None
:
iList
=
[
i
[
'name'
]
for
i
in
self
.
get_items_history_list
()]
logger
.
debug
(
_
(
"Stats history activated for plugin %s (items: %s)"
)
%
(
self
.
plugin_name
,
iList
))
logger
.
debug
(
_
(
"Stats history activated for plugin %s (items: %s)"
)
%
(
self
.
plugin_name
,
iList
))
ret
=
{}
# First column for the date
ret
[
'date'
]
=
[]
for
i
in
self
.
get_items_history_list
():
# One column per item
ret
[
i
[
'name'
]]
=
[]
return
ret
def
reset_stats_history
(
self
):
"""Reset the stats history (dict of list)"""
if
self
.
args
is
not
None
and
self
.
args
.
enable_history
and
self
.
get_items_history_list
()
is
not
None
:
iList
=
[
i
[
'name'
]
for
i
in
self
.
get_items_history_list
()]
logger
.
debug
(
_
(
"Reset history for plugin %s (items: %s)"
)
%
(
self
.
plugin_name
,
iList
))
logger
.
debug
(
_
(
"Reset history for plugin %s (items: %s)"
)
%
(
self
.
plugin_name
,
iList
))
self
.
stats_history
=
{}
# First column for the date
self
.
stats_history
[
'date'
]
=
[]
for
i
in
self
.
get_items_history_list
():
# One column per item
self
.
stats_history
[
i
[
'name'
]]
=
[]
return
self
.
stats_history
def
update_stats_history
(
self
):
def
update_stats_history
(
self
,
item_name
=
''
):
"""Update stats history"""
if
self
.
args
is
not
None
and
self
.
args
.
enable_history
and
self
.
get_items_history_list
()
is
not
None
:
self
.
stats_history
[
'date'
].
append
(
datetime
.
now
())
if
self
.
stats
!=
[]
and
self
.
args
is
not
None
and
self
.
args
.
enable_history
and
self
.
get_items_history_list
()
is
not
None
:
self
.
add_item_history
(
'date'
,
datetime
.
now
())
for
i
in
self
.
get_items_history_list
():
self
.
stats_history
[
i
[
'name'
]].
append
(
self
.
stats
[
i
[
'name'
]])
if
type
(
self
.
stats
)
is
list
:
# Stats is a list of data
# Iter throught it (for exemple, iter throught network
# interface)
for
l
in
self
.
stats
:
self
.
add_item_history
(
l
[
item_name
]
+
'_'
+
i
[
'name'
],
l
[
i
[
'name'
]])
else
:
# Stats is not a list
# Add the item to the history directly
self
.
add_item_history
(
i
[
'name'
],
self
.
stats
[
i
[
'name'
]])
return
self
.
stats_history
def
get_stats_history
(
self
):
...
...
@@ -160,10 +169,11 @@ class GlancesPlugin(object):
if
len
(
snmp_oid
)
==
1
:
# Bulk command for only one OID
# Note: key is the item indexed but the OID result
# Note: key is the item indexed but the OID result
for
item
in
snmpresult
:
if
item
.
keys
()[
0
].
startswith
(
snmp_oid
.
values
()[
0
]):
ret
[
snmp_oid
.
keys
()[
0
]
+
item
.
keys
()[
0
].
split
(
snmp_oid
.
values
()[
0
])[
1
]]
=
item
.
values
()[
0
]
ret
[
snmp_oid
.
keys
()[
0
]
+
item
.
keys
()
[
0
].
split
(
snmp_oid
.
values
()[
0
])[
1
]]
=
item
.
values
()[
0
]
else
:
# Build the internal dict with the SNMP result
# Note: key is the first item in the snmp_oid
...
...
@@ -203,19 +213,20 @@ class GlancesPlugin(object):
"""
Return the stats object for a specific item (in JSON format)
Stats should be a list of dict (processlist, network...)
"""
"""
if
type
(
self
.
stats
)
is
not
list
:
if
type
(
self
.
stats
)
is
dict
:
try
:
return
json
.
dumps
({
item
:
self
.
stats
[
item
]
})
return
json
.
dumps
({
item
:
self
.
stats
[
item
]
})
except
KeyError
as
e
:
logger
.
error
(
_
(
"Can not get item %s (%s)"
)
%
(
item
,
e
))
else
:
return
None
else
:
try
:
# Source: http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
return
json
.
dumps
({
item
:
map
(
itemgetter
(
item
),
self
.
stats
)
})
# Source:
# http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
return
json
.
dumps
({
item
:
map
(
itemgetter
(
item
),
self
.
stats
)})
except
(
KeyError
,
ValueError
)
as
e
:
logger
.
error
(
_
(
"Can not get item %s (%s)"
)
%
(
item
,
e
))
return
None
...
...
@@ -231,9 +242,10 @@ class GlancesPlugin(object):
if
value
.
isdigit
():
value
=
int
(
value
)
try
:
return
json
.
dumps
({
value
:
[
i
for
i
in
self
.
stats
if
i
[
item
]
==
value
]
})
return
json
.
dumps
({
value
:
[
i
for
i
in
self
.
stats
if
i
[
item
]
==
value
]})
except
(
KeyError
,
ValueError
)
as
e
:
logger
.
error
(
_
(
"Can not get item(%s)=value(%s) (%s)"
)
%
(
item
,
value
,
e
))
logger
.
error
(
_
(
"Can not get item(%s)=value(%s) (%s)"
)
%
(
item
,
value
,
e
))
return
None
def
load_limits
(
self
,
config
):
...
...
@@ -243,9 +255,11 @@ class GlancesPlugin(object):
for
s
,
v
in
config
.
items
(
self
.
plugin_name
):
# Read limits
try
:
self
.
limits
[
self
.
plugin_name
+
'_'
+
s
]
=
config
.
get_option
(
self
.
plugin_name
,
s
)
self
.
limits
[
self
.
plugin_name
+
'_'
+
s
]
=
config
.
get_option
(
self
.
plugin_name
,
s
)
except
ValueError
:
self
.
limits
[
self
.
plugin_name
+
'_'
+
s
]
=
config
.
get_raw_option
(
self
.
plugin_name
,
s
).
split
(
","
)
self
.
limits
[
self
.
plugin_name
+
'_'
+
s
]
=
config
.
get_raw_option
(
self
.
plugin_name
,
s
).
split
(
","
)
def
set_limits
(
self
,
input_limits
):
"""Set the limits to input_limits."""
...
...
@@ -389,8 +403,8 @@ class GlancesPlugin(object):
return
ret
def
curse_add_line
(
self
,
msg
,
decoration
=
"DEFAULT"
,
optional
=
False
,
additional
=
False
,
def
curse_add_line
(
self
,
msg
,
decoration
=
"DEFAULT"
,
optional
=
False
,
additional
=
False
,
splittable
=
False
):
"""Return a dict with
...
...
@@ -424,7 +438,7 @@ class GlancesPlugin(object):
def
set_align
(
self
,
align
=
'left'
):
"""Set the Curse align"""
if
align
in
(
'left'
,
'right'
,
'bottom'
):
if
align
in
(
'left'
,
'right'
,
'bottom'
):
self
.
align
=
align
else
:
self
.
align
=
'left'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录