Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
蜕变的菜鸟
glances
提交
4f133b02
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 搜索 >>
提交
4f133b02
编写于
5月 24, 2021
作者:
N
Nicolas Hennion
浏览文件
操作
浏览文件
下载
差异文件
Make the refresh rate configurable per plugin #1870
上级
788ad374
a874ea8d
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
248 addition
and
151 deletion
+248
-151
Makefile
Makefile
+24
-0
conf/glances.conf
conf/glances.conf
+9
-3
docs/config.rst
docs/config.rst
+10
-2
docs/man/glances.1
docs/man/glances.1
+11
-3
glances/__init__.py
glances/__init__.py
+4
-5
glances/cpu_percent.py
glances/cpu_percent.py
+1
-1
glances/main.py
glances/main.py
+20
-7
glances/outputs/glances_curses.py
glances/outputs/glances_curses.py
+5
-7
glances/outputs/glances_stdout_csv.py
glances/outputs/glances_stdout_csv.py
+2
-2
glances/plugins/glances_connections.py
glances/plugins/glances_connections.py
+2
-3
glances/plugins/glances_core.py
glances/plugins/glances_core.py
+2
-0
glances/plugins/glances_cpu.py
glances/plugins/glances_cpu.py
+21
-25
glances/plugins/glances_diskio.py
glances/plugins/glances_diskio.py
+58
-50
glances/plugins/glances_docker.py
glances/plugins/glances_docker.py
+7
-3
glances/plugins/glances_folders.py
glances/plugins/glances_folders.py
+2
-2
glances/plugins/glances_mem.py
glances/plugins/glances_mem.py
+1
-0
glances/plugins/glances_network.py
glances/plugins/glances_network.py
+6
-1
glances/plugins/glances_plugin.py
glances/plugins/glances_plugin.py
+30
-3
glances/plugins/glances_ports.py
glances/plugins/glances_ports.py
+8
-10
glances/plugins/glances_processcount.py
glances/plugins/glances_processcount.py
+1
-0
glances/processes.py
glances/processes.py
+4
-5
glances/standalone.py
glances/standalone.py
+11
-9
glances/stats.py
glances/stats.py
+9
-10
未找到文件。
Makefile
浏览文件 @
4f133b02
...
...
@@ -16,4 +16,28 @@ docs-server: docs
webui
:
cd
glances/outputs/static/
&&
npm
install
&&
npm audit fix
&&
npm run build
venv
:
virtualenv
-p
/usr/bin/python3 venv
./venv/bin/pip
install
-r
requirements.txt
./venv/bin/pip
install
-r
optional-requirements.txt
venv-upgrade
:
./venv/bin/pip
install
--upgrade
-r
requirements.txt
./venv/bin/pip
install
--upgrade
-r
optional-requirements.txt
run
:
venv
./venv/bin/python
-m
glances
-C
./conf/glances.conf
run-debug
:
venv
./venv/bin/python
-m
glances
-C
./conf/glances.conf
-d
run-webserver
:
venv
./venv/bin/python
-m
glances
-C
./conf/glances.conf
-w
run-server
:
venv
./venv/bin/python
-m
glances
-C
./conf/glances.conf
-s
run-client
:
venv
./venv/bin/python
-m
glances
-C
./conf/glances.conf
-c
localhost
.PHONY
:
test docs docs-server
conf/glances.conf
浏览文件 @
4f133b02
...
...
@@ -3,6 +3,10 @@
##############################################################################
[
global
]
# Refresh rate (default is a minimum of 2 seconds)
# Can be overwrite by the -t <sec> option
# It is also possible to overwrite it in each plugin sections
refresh
=
2
# Does Glances should check if a newer version is available on PyPI ?
check_update
=
false
# History size (maximum number of values)
...
...
@@ -27,6 +31,8 @@ max_processes_display=30
# Set to true to disable a plugin
# Note: you can also disable it from the command line (see --disable-plugin <plugin_name>)
disable
=
False
# Set a specific refresh rate for this plugin by overwriting the default/refresh value
#refresh=3
# Graphical percentage char used in the terminal user interface (default is |)
percentage_char
=|
# Define CPU, MEM and SWAP thresholds in %
...
...
@@ -45,7 +51,7 @@ disable=False
# See https://scoutapm.com/blog/slow_server_flow_chart
#
# I/O wait percentage should be lower than 1/# (# = Logical CPU cores)
# Leave commented to just use the default config:
# Leave commented to just use the default config:
# Careful=1/#*100-20% / Warning=1/#*100-10% / Critical=1/#*100
#iowait_careful=30
#iowait_warning=40
...
...
@@ -414,8 +420,8 @@ style=DarkStyle
[
influxdb
]
# !!!
# Will be DEPRECATED in future release.
# Please have a look on the new influxdb2 export module (compatible with InfluxDB 1.8.x and 2.x)
# Will be DEPRECATED in future release.
# Please have a look on the new influxdb2 export module (compatible with InfluxDB 1.8.x and 2.x)
# !!!
# Configuration for the --export influxdb option
# https://influxdb.com/
...
...
docs/config.rst
浏览文件 @
4f133b02
...
...
@@ -39,8 +39,15 @@ A first section (called global) is available:
.. code-block:: ini
[global]
# Does Glances should check if a newer version is available on PyPI?
check_update=true
# Refresh rate (default is a minimum of 2 seconds)
# Can be overwrite by the -t <sec> option
# It is also possible to overwrite it in each plugin sections
refresh=2
# Does Glances should check if a newer version is available on PyPI ?
check_update=false
# History size (maximum number of values)
# Default is 28800: 1 day with 1 point every 3 seconds
history_size=28800
Each plugin, export module and application monitoring process (AMP) can
have a section. Below an example for the CPU plugin:
...
...
@@ -49,6 +56,7 @@ have a section. Below an example for the CPU plugin:
[cpu]
disable=False
refresh=3
user_careful=50
user_warning=70
user_critical=90
...
...
docs/man/glances.1
浏览文件 @
4f133b02
.\" Man page generated from reStructuredText.
.
.TH "GLANCES" "1" "May
06, 2021" "3.1.8b1
" "Glances"
.TH "GLANCES" "1" "May
23, 2021" "3.1.8b3
" "Glances"
.SH NAME
glances \- An eye on your system
.
...
...
@@ -565,8 +565,15 @@ A first section (called global) is available:
.nf
.ft C
[global]
# Does Glances should check if a newer version is available on PyPI?
check_update=true
# Refresh rate (default is a minimum of 2 seconds)
# Can be overwrite by the \-t <sec> option
# It is also possible to overwrite it in each plugin sections
refresh=2
# Does Glances should check if a newer version is available on PyPI ?
check_update=false
# History size (maximum number of values)
# Default is 28800: 1 day with 1 point every 3 seconds
history_size=28800
.ft P
.fi
.UNINDENT
...
...
@@ -581,6 +588,7 @@ have a section. Below an example for the CPU plugin:
.ft C
[cpu]
disable=False
refresh=3
user_careful=50
user_warning=70
user_critical=90
...
...
glances/__init__.py
浏览文件 @
4f133b02
...
...
@@ -44,7 +44,6 @@ except ImportError:
# Note: others Glances libs will be imported optionally
from
glances.logger
import
logger
from
glances.main
import
GlancesMain
from
glances.globals
import
WINDOWS
from
glances.timer
import
Counter
# Check locale
try
:
...
...
@@ -112,7 +111,7 @@ def start(config, args):
# Start the main loop
logger
.
debug
(
"Glances started in {} seconds"
.
format
(
start_duration
.
get
()))
if
args
.
stdout_issue
:
# Serve once for issue/test mode
# Serve once for issue/test mode
mode
.
serve_issue
()
else
:
# Serve forever
...
...
@@ -142,9 +141,9 @@ def main():
global
core
# Create the Glances main instance
# Glances options from the command line are readed first (in __init__)
# then the options from the config file (in parse_args)
core
=
GlancesMain
()
config
=
core
.
get_config
()
args
=
core
.
get_args
()
# Glances can be ran in standalone, client or server mode
start
(
config
=
co
nfig
,
args
=
args
)
start
(
config
=
co
re
.
get_config
(),
args
=
core
.
get_args
()
)
glances/cpu_percent.py
浏览文件 @
4f133b02
...
...
@@ -34,9 +34,9 @@ class CpuPercent(object):
# cached_time is the minimum time interval between stats updates
# since last update is passed (will retrieve old cached info instead)
self
.
cached_time
=
0
self
.
timer_cpu
=
Timer
(
0
)
self
.
timer_percpu
=
Timer
(
0
)
self
.
cached_time
=
cached_time
def
get_key
(
self
):
"""Return the key of the per CPU list."""
...
...
glances/main.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -33,8 +33,8 @@ from glances.logger import logger, LOG_FILENAME
class
GlancesMain
(
object
):
"""Main class to manage Glances instance."""
# Default stats'
refresh time is 3
seconds
refresh_time
=
3
# Default stats'
minimum refresh time is 2
seconds
DEFAULT_REFRESH_TIME
=
2
# Set the default cache lifetime to 1 second (only for server)
cached_time
=
1
# By default, Glances is ran in standalone mode (no client/server)
...
...
@@ -67,7 +67,7 @@ Examples of use:
Monitor local machine and export stats to a CSV file (standalone mode):
$ glances --export csv --export-csv-file /tmp/glances.csv
Monitor local machine and export stats to a InfluxDB server with 5s refresh
tim
e (standalone mode):
Monitor local machine and export stats to a InfluxDB server with 5s refresh
rat
e (standalone mode):
$ glances -t 5 --export influxdb
Start a Glances XML-RPC server (server mode):
...
...
@@ -205,12 +205,14 @@ Examples of use:
help
=
'SNMP authentication key (only for SNMPv3)'
)
parser
.
add_argument
(
'--snmp-force'
,
action
=
'store_true'
,
default
=
False
,
dest
=
'snmp_force'
,
help
=
'force SNMP mode'
)
parser
.
add_argument
(
'-t'
,
'--time'
,
default
=
self
.
refresh_time
,
type
=
float
,
dest
=
'time'
,
help
=
'set refresh time in seconds [default: {} sec]'
.
format
(
self
.
refresh_time
))
parser
.
add_argument
(
'-t'
,
'--time'
,
default
=
self
.
DEFAULT_REFRESH_TIME
,
type
=
float
,
dest
=
'time'
,
help
=
'set minumum refresh rate in seconds [default: {} sec]'
.
format
(
self
.
DEFAULT_REFRESH_TIME
))
parser
.
add_argument
(
'-w'
,
'--webserver'
,
action
=
'store_true'
,
default
=
False
,
dest
=
'webserver'
,
help
=
'run Glances in web server mode (bottle needed)'
)
parser
.
add_argument
(
'--cached-time'
,
default
=
self
.
cached_time
,
type
=
int
,
dest
=
'cached_time'
,
help
=
'set the server cache time [default: {} sec]'
.
format
(
self
.
cached_time
))
dest
=
'cached_time'
,
help
=
'set the server cache time [default: {} sec]'
.
format
(
self
.
cached_time
))
parser
.
add_argument
(
'--open-web-browser'
,
action
=
'store_true'
,
default
=
False
,
dest
=
'open_web_browser'
,
help
=
'try to open the Web UI in the default Web browser'
)
# Display options
...
...
@@ -258,6 +260,8 @@ Examples of use:
args
=
self
.
init_args
().
parse_args
()
# Load the configuration file, if it exists
# This function should be called after the parse_args
# because the configration file path can be defined
self
.
config
=
Config
(
args
.
conf_file
)
# Debug mode
...
...
@@ -268,6 +272,15 @@ Examples of use:
from
warnings
import
simplefilter
simplefilter
(
"ignore"
)
# Plugins refresh rate
if
self
.
config
.
has_section
(
'global'
):
global_refresh
=
self
.
config
.
get_float_value
(
'global'
,
'refresh'
,
default
=
self
.
DEFAULT_REFRESH_TIME
)
if
args
.
time
==
self
.
DEFAULT_REFRESH_TIME
:
args
.
time
=
global_refresh
logger
.
debug
(
'Global refresh rate is set to {} seconds'
.
format
(
args
.
time
))
# Plugins disable/enable
# Allow users to disable plugins from the glances.conf (issue #1378)
for
s
in
self
.
config
.
sections
():
...
...
glances/outputs/glances_curses.py
浏览文件 @
4f133b02
...
...
@@ -20,10 +20,9 @@
"""Curses interface class."""
from
__future__
import
unicode_literals
import
re
import
sys
from
glances.compat
import
to_ascii
,
nativestr
,
b
,
u
,
itervalues
,
enable
,
disable
from
glances.compat
import
nativestr
,
u
,
itervalues
,
enable
,
disable
from
glances.globals
import
MACOS
,
WINDOWS
from
glances.logger
import
logger
from
glances.events
import
glances_events
...
...
@@ -104,7 +103,7 @@ class _GlancesCurses(object):
# "<" (left arrow) navigation through process sort
# ">" (right arrow) navigation through process sort
# 'UP' > Up in the server list
# 'DOWN' > Down in the server list
# 'DOWN' > Down in the server list
}
_sort_loop
=
[
'cpu_percent'
,
'memory_percent'
,
'username'
,
...
...
@@ -666,9 +665,9 @@ class _GlancesCurses(object):
self
.
args
.
cursor_position
]
confirm
=
self
.
display_popup
(
'Kill process: {} (pid: {}) ?
\n\n
Confirm ([y]es/[n]o): '
.
format
(
selected_process_raw
[
'name'
],
selected_process_raw
[
'pid'
]),
popup_type
=
'yesno'
)
selected_process_raw
[
'name'
],
selected_process_raw
[
'pid'
]),
popup_type
=
'yesno'
)
if
confirm
.
lower
().
startswith
(
'y'
):
try
:
ret_kill
=
glances_processes
.
kill
(
selected_process_raw
[
'pid'
])
...
...
@@ -684,7 +683,6 @@ class _GlancesCurses(object):
'Kill process only available in standalone mode'
)
self
.
kill_process
=
False
# Display graph generation popup
if
self
.
args
.
generate_graph
:
self
.
display_popup
(
'Generate graph in {}'
.
format
(
self
.
args
.
export_graph_path
))
...
...
glances/outputs/glances_stdout_csv.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -77,7 +77,7 @@ class GlancesStdoutCsv(object):
if
isinstance
(
i
,
dict
)
and
'key'
in
i
:
for
k
in
i
.
keys
():
line
+=
'{}.{}.{}{}'
.
format
(
plugin
,
str
(
i
[
'key'
]),
str
(
i
[
i
[
'key'
]
]),
str
(
k
),
self
.
separator
)
else
:
...
...
glances/plugins/glances_connections.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -21,9 +21,8 @@
from
__future__
import
unicode_literals
from
glances.logger
import
logger
from
glances.timer
import
getTimeSinceLastUpdate
from
glances.plugins.glances_plugin
import
GlancesPlugin
from
glances.compat
import
n
,
u
,
b
,
n
ativestr
from
glances.compat
import
nativestr
import
psutil
...
...
glances/plugins/glances_core.py
浏览文件 @
4f133b02
...
...
@@ -40,6 +40,8 @@ class Plugin(GlancesPlugin):
# The core number is displayed by the load plugin
self
.
display_curse
=
False
@
GlancesPlugin
.
_check_decorator
@
GlancesPlugin
.
_log_result_decorator
def
update
(
self
):
"""Update core stats.
...
...
glances/plugins/glances_cpu.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -79,7 +79,6 @@ class Plugin(GlancesPlugin):
@
GlancesPlugin
.
_log_result_decorator
def
update
(
self
):
"""Update CPU stats using the input method."""
# Grab stats into self.stats
if
self
.
input_method
==
'local'
:
stats
=
self
.
update_local
()
...
...
@@ -105,39 +104,41 @@ class Plugin(GlancesPlugin):
stats
=
self
.
get_init_value
()
stats
[
'total'
]
=
cpu_percent
.
get
()
# Grab: 'user', 'system', 'idle', 'nice', 'iowait',
# 'irq', 'softirq', 'steal', 'guest', 'guest_nice'
cpu_times_percent
=
psutil
.
cpu_times_percent
(
interval
=
0.0
)
for
stat
in
[
'user'
,
'system'
,
'idle'
,
'nice'
,
'iowait'
,
'irq'
,
'softirq'
,
'steal'
,
'guest'
,
'guest_nice'
]:
if
hasattr
(
cpu_times_percent
,
stat
):
stats
[
stat
]
=
getattr
(
cpu_times_percent
,
stat
)
for
stat
in
cpu_times_percent
.
_fields
:
stats
[
stat
]
=
getattr
(
cpu_times_percent
,
stat
)
# Additional CPU stats (number of events not as a %; psutil>=4.1.0)
#
ctx_switches: number of context switches (voluntary + involuntary) per second
#
interrupts: number of interrupts per second
#
soft_interrupts: number of software interrupts per second
. Always set to 0 on Windows and SunOS.
# syscalls: number of system calls since boot. Always set to 0 on Linux.
#
- ctx_switches: number of context switches (voluntary + involuntary) since boot.
#
- interrupts: number of interrupts since boot.
#
- soft_interrupts: number of software interrupts since boot
. Always set to 0 on Windows and SunOS.
#
-
syscalls: number of system calls since boot. Always set to 0 on Linux.
cpu_stats
=
psutil
.
cpu_stats
()
# By storing time data we enable Rx/s and Tx/s calculations in the
# XML/RPC API, which would otherwise be overly difficult work
# for users of the API
time_since_update
=
getTimeSinceLastUpdate
(
'cpu'
)
stats
[
'time_since_update'
]
=
getTimeSinceLastUpdate
(
'cpu'
)
# Core number is needed to compute the CTX switch limit
stats
[
'cpucore'
]
=
self
.
nb_log_core
# Previous CPU stats are stored in the cpu_stats_old variable
if
not
hasattr
(
self
,
'cpu_stats_old'
):
# First call, we init the cpu_stats_old var
self
.
cpu_stats_old
=
cpu_stats
# Init the stats (needed to have the key name for export)
for
stat
in
cpu_stats
.
_fields
:
# @TODO: better to set it to None but should refactor views and UI...
stats
[
stat
]
=
0
else
:
# Others calls...
for
stat
in
cpu_stats
.
_fields
:
if
getattr
(
cpu_stats
,
stat
)
is
not
None
:
stats
[
stat
]
=
getattr
(
cpu_stats
,
stat
)
-
getattr
(
self
.
cpu_stats_old
,
stat
)
stats
[
'time_since_update'
]
=
time_since_update
# Core number is needed to compute the CTX switch limit
stats
[
'cpucore'
]
=
self
.
nb_log_core
# Save stats to compute next step
self
.
cpu_stats_old
=
cpu_stats
# Save stats to compute next step
self
.
cpu_stats_old
=
cpu_stats
return
stats
...
...
@@ -242,11 +243,6 @@ class Plugin(GlancesPlugin):
msg
=
'{:5.1f}%'
.
format
(
self
.
stats
[
'total'
])
ret
.
append
(
self
.
curse_add_line
(
msg
,
self
.
get_views
(
key
=
'total'
,
option
=
'decoration'
)))
# if idle_tag:
# ret.append(self.curse_add_line(
# msg, self.get_views(key='total', option='decoration')))
# else:
# ret.append(self.curse_add_line(msg))
# Idle CPU
if
'idle'
in
self
.
stats
and
not
idle_tag
:
msg
=
' {:8}'
.
format
(
'idle:'
)
...
...
glances/plugins/glances_diskio.py
浏览文件 @
4f133b02
...
...
@@ -52,6 +52,7 @@ class Plugin(GlancesPlugin):
# We want to display the stat in the curse interface
self
.
display_curse
=
True
# Hide stats if it has never been != 0
if
config
is
not
None
:
self
.
hide_zero
=
config
.
get_bool_value
(
...
...
@@ -60,6 +61,10 @@ class Plugin(GlancesPlugin):
self
.
hide_zero
=
False
self
.
hide_zero_fields
=
[
'read_bytes'
,
'write_bytes'
]
# Force a first update because we need two update to have the first stat
self
.
update
()
self
.
refresh_timer
.
set
(
0
)
def
get_key
(
self
):
"""Return the key of the list."""
return
'disk_name'
...
...
@@ -81,61 +86,64 @@ class Plugin(GlancesPlugin):
# read_time: time spent reading from disk (in milliseconds)
# write_time: time spent writing to disk (in milliseconds)
try
:
diskio
counters
=
psutil
.
disk_io_counters
(
perdisk
=
True
)
diskio
=
psutil
.
disk_io_counters
(
perdisk
=
True
)
except
Exception
:
return
stats
# Previous disk IO stats are stored in the diskio_old variable
if
not
hasattr
(
self
,
'diskio_old'
):
# First call, we init the diskio_old var
# By storing time data we enable Rx/s and Tx/s calculations in the
# XML/RPC API, which would otherwise be overly difficult work
# for users of the API
time_since_update
=
getTimeSinceLastUpdate
(
'disk'
)
diskio
=
diskio
for
disk
in
diskio
:
# By default, RamFS is not displayed (issue #714)
if
self
.
args
is
not
None
and
not
self
.
args
.
diskio_show_ramfs
and
disk
.
startswith
(
'ram'
):
continue
# Do not take hide disk into account
if
self
.
is_hide
(
disk
):
continue
# Compute count and bit rate
try
:
self
.
diskio_old
=
diskiocounters
except
(
IOError
,
UnboundLocalError
):
pass
else
:
# By storing time data we enable Rx/s and Tx/s calculations in the
# XML/RPC API, which would otherwise be overly difficult work
# for users of the API
time_since_update
=
getTimeSinceLastUpdate
(
'disk'
)
diskio_new
=
diskiocounters
for
disk
in
diskio_new
:
# By default, RamFS is not displayed (issue #714)
if
self
.
args
is
not
None
and
not
self
.
args
.
diskio_show_ramfs
and
disk
.
startswith
(
'ram'
):
continue
# Do not take hide disk into account
if
self
.
is_hide
(
disk
):
continue
# Compute count and bit rate
try
:
read_count
=
(
diskio_new
[
disk
].
read_count
-
self
.
diskio_old
[
disk
].
read_count
)
write_count
=
(
diskio_new
[
disk
].
write_count
-
self
.
diskio_old
[
disk
].
write_count
)
read_bytes
=
(
diskio_new
[
disk
].
read_bytes
-
self
.
diskio_old
[
disk
].
read_bytes
)
write_bytes
=
(
diskio_new
[
disk
].
write_bytes
-
self
.
diskio_old
[
disk
].
write_bytes
)
diskstat
=
{
'time_since_update'
:
time_since_update
,
'disk_name'
:
n
(
disk
),
'read_count'
:
read_count
,
'write_count'
:
write_count
,
'read_bytes'
:
read_bytes
,
'write_bytes'
:
write_bytes
}
# Add alias if exist (define in the configuration file)
if
self
.
has_alias
(
disk
)
is
not
None
:
diskstat
[
'alias'
]
=
self
.
has_alias
(
disk
)
except
KeyError
:
continue
else
:
diskstat
[
'key'
]
=
self
.
get_key
()
stats
.
append
(
diskstat
)
# Save stats to compute next bitrate
self
.
diskio_old
=
diskio_new
diskstat
=
{
'time_since_update'
:
time_since_update
,
'disk_name'
:
n
(
disk
),
'read_count'
:
diskio
[
disk
].
read_count
-
\
self
.
diskio_old
[
disk
].
read_count
,
'write_count'
:
diskio
[
disk
].
write_count
-
\
self
.
diskio_old
[
disk
].
write_count
,
'read_bytes'
:
diskio
[
disk
].
read_bytes
-
\
self
.
diskio_old
[
disk
].
read_bytes
,
'write_bytes'
:
diskio
[
disk
].
write_bytes
-
\
self
.
diskio_old
[
disk
].
write_bytes
}
except
(
KeyError
,
AttributeError
):
diskstat
=
{
'time_since_update'
:
time_since_update
,
'disk_name'
:
n
(
disk
),
'read_count'
:
0
,
'write_count'
:
0
,
'read_bytes'
:
0
,
'write_bytes'
:
0
}
# Add alias if exist (define in the configuration file)
if
self
.
has_alias
(
disk
)
is
not
None
:
diskstat
[
'alias'
]
=
self
.
has_alias
(
disk
)
# Add the dict key
diskstat
[
'key'
]
=
self
.
get_key
()
# Ad dthe current disk stat to the list
stats
.
append
(
diskstat
)
# Save stats to compute next bitrate
try
:
self
.
diskio_old
=
diskio
except
(
IOError
,
UnboundLocalError
):
pass
elif
self
.
input_method
==
'snmp'
:
# Update stats using SNMP
# No standard way for the moment...
...
...
glances/plugins/glances_docker.py
浏览文件 @
4f133b02
...
...
@@ -95,6 +95,10 @@ class Plugin(GlancesPlugin):
# value: instance of ThreadDockerGrabber
self
.
thread_list
=
{}
# Force a first update because we need two update to have the first stat
self
.
update
()
self
.
refresh_timer
.
set
(
0
)
def
exit
(
self
):
"""Overwrite the exit method to close threads."""
for
t
in
itervalues
(
self
.
thread_list
):
...
...
@@ -303,8 +307,8 @@ class Plugin(GlancesPlugin):
precpu_new
[
'system'
]
=
all_stats
[
'precpu_stats'
].
get
(
'system_cpu_usage'
,
None
)
# Issue #1857
# If either precpu_stats.online_cpus or cpu_stats.online_cpus is nil
# then for compatibility with older daemons the length of
# If either precpu_stats.online_cpus or cpu_stats.online_cpus is nil
# then for compatibility with older daemons the length of
# the corresponding cpu_usage.percpu_usage array should be used.
if
'online_cpus'
in
all_stats
[
'cpu_stats'
]
and
\
all_stats
[
'cpu_stats'
][
'online_cpus'
]
is
not
None
:
...
...
@@ -558,7 +562,7 @@ class Plugin(GlancesPlugin):
# Get the maximum containers name
# Max size is configurable. See feature request #1723.
name_max_width
=
min
(
self
.
config
.
get_int_value
(
'docker'
,
'max_name_size'
,
default
=
20
),
len
(
max
(
self
.
stats
[
'containers'
],
len
(
max
(
self
.
stats
[
'containers'
],
key
=
lambda
x
:
len
(
x
[
'name'
]))[
'name'
]))
msg
=
' {:{width}}'
.
format
(
'Name'
,
width
=
name_max_width
)
ret
.
append
(
self
.
curse_add_line
(
msg
))
...
...
glances/plugins/glances_folders.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -22,7 +22,7 @@ from __future__ import unicode_literals
import
numbers
from
glances.compat
import
nativestr
,
n
from
glances.compat
import
nativestr
from
glances.folder_list
import
FolderList
as
glancesFolderList
from
glances.plugins.glances_plugin
import
GlancesPlugin
from
glances.logger
import
logger
...
...
glances/plugins/glances_mem.py
浏览文件 @
4f133b02
...
...
@@ -19,6 +19,7 @@
"""Virtual memory plugin."""
from
glances.logger
import
logger
from
glances.compat
import
iterkeys
from
glances.plugins.glances_plugin
import
GlancesPlugin
...
...
glances/plugins/glances_network.py
浏览文件 @
4f133b02
...
...
@@ -60,6 +60,7 @@ class Plugin(GlancesPlugin):
# We want to display the stat in the curse interface
self
.
display_curse
=
True
# Hide stats if it has never been != 0
if
config
is
not
None
:
self
.
hide_zero
=
config
.
get_bool_value
(
...
...
@@ -68,11 +69,15 @@ class Plugin(GlancesPlugin):
self
.
hide_zero
=
False
self
.
hide_zero_fields
=
[
'rx'
,
'tx'
]
# Force a first update because we need two update to have the first stat
self
.
update
()
self
.
refresh_timer
.
set
(
0
)
def
get_key
(
self
):
"""Return the key of the list."""
return
'interface_name'
@
GlancesPlugin
.
_check_decorator
#
@GlancesPlugin._check_decorator
@
GlancesPlugin
.
_log_result_decorator
def
update
(
self
):
"""Update network stats using the input method.
...
...
glances/plugins/glances_plugin.py
浏览文件 @
4f133b02
...
...
@@ -34,7 +34,7 @@ from glances.history import GlancesHistory
from
glances.logger
import
logger
from
glances.events
import
glances_events
from
glances.thresholds
import
glances_thresholds
from
glances.timer
import
Counter
from
glances.timer
import
Counter
,
Timer
class
GlancesPlugin
(
object
):
...
...
@@ -104,6 +104,9 @@ class GlancesPlugin(object):
self
.
hide_zero
=
False
self
.
hide_zero_fields
=
[]
# Set the initial refresh time to display stats the first time
self
.
refresh_timer
=
Timer
(
0
)
# Init the stats
self
.
stats_init_value
=
stats_init_value
self
.
stats
=
None
...
...
@@ -584,6 +587,13 @@ class GlancesPlugin(object):
"""Set the limits to input_limits."""
self
.
_limits
=
input_limits
def
get_limits
(
self
,
item
=
None
):
"""Return the limits object."""
if
item
is
None
:
return
self
.
_limits
else
:
return
self
.
_limits
.
get
(
'{}_{}'
.
format
(
self
.
plugin_name
,
item
),
None
)
def
get_stats_action
(
self
):
"""Return stats for the action.
...
...
@@ -989,12 +999,29 @@ class GlancesPlugin(object):
ret
=
'
\\
'
return
ret
def
get_refresh_time
(
self
):
"""Return the plugin refresh time"""
ret
=
self
.
get_limits
(
item
=
'refresh'
)
if
ret
is
None
:
ret
=
self
.
args
.
time
return
ret
def
_check_decorator
(
fct
):
"""Check if the plugin is enabled."""
"""Check decorator for update method.
It checks:
- if the plugin is enabled.
- if the refresh_timer is finished
"""
def
wrapper
(
self
,
*
args
,
**
kw
):
if
self
.
is_enable
():
if
self
.
is_enable
()
and
(
self
.
refresh_timer
.
finished
()
or
self
.
stats
==
self
.
get_init_value
):
# Run the method
ret
=
fct
(
self
,
*
args
,
**
kw
)
# Reset the timer
self
.
refresh_timer
.
set
(
self
.
get_refresh_time
())
self
.
refresh_timer
.
reset
()
else
:
# No need to call the method
# Return the last result available
ret
=
self
.
stats
return
ret
return
wrapper
...
...
glances/plugins/glances_ports.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -60,9 +60,6 @@ class Plugin(GlancesPlugin):
self
.
stats
=
GlancesPortsList
(
config
=
config
,
args
=
args
).
get_ports_list
()
+
\
GlancesWebList
(
config
=
config
,
args
=
args
).
get_web_list
()
# Init global Timer
self
.
timer_ports
=
Timer
(
0
)
# Global Thread running all the scans
self
.
_thread
=
None
...
...
@@ -73,6 +70,7 @@ class Plugin(GlancesPlugin):
# Call the father class
super
(
Plugin
,
self
).
exit
()
@
GlancesPlugin
.
_check_decorator
@
GlancesPlugin
.
_log_result_decorator
def
update
(
self
):
"""Update the ports list."""
...
...
@@ -84,15 +82,15 @@ class Plugin(GlancesPlugin):
thread_is_running
=
False
else
:
thread_is_running
=
self
.
_thread
.
is_alive
()
if
self
.
timer_ports
.
finished
()
and
not
thread_is_running
:
if
not
thread_is_running
:
# Run ports scanner
self
.
_thread
=
ThreadScanner
(
self
.
stats
)
self
.
_thread
.
start
()
# Restart timer
if
len
(
self
.
stats
)
>
0
:
self
.
timer_ports
=
Timer
(
self
.
stats
[
0
][
'refresh'
])
else
:
self
.
timer_ports
=
Timer
(
0
)
#
#
Restart timer
#
if len(self.stats) > 0:
#
self.timer_ports = Timer(self.stats[0]['refresh'])
#
else:
#
self.timer_ports = Timer(0)
else
:
# Not available in SNMP mode
pass
...
...
glances/plugins/glances_processcount.py
浏览文件 @
4f133b02
...
...
@@ -62,6 +62,7 @@ class Plugin(GlancesPlugin):
# Note: 'glances_processes' is already init in the glances_processes.py script
@
GlancesPlugin
.
_check_decorator
@
GlancesPlugin
.
_log_result_decorator
def
update
(
self
):
"""Update processes stats using the input method."""
...
...
glances/processes.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -17,11 +17,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
operator
import
os
from
glances.compat
import
iter
items
,
itervalues
,
listitems
,
iter
keys
from
glances.globals
import
BSD
,
LINUX
,
MACOS
,
SUNOS
,
WINDOWS
,
WSL
from
glances.compat
import
iterkeys
from
glances.globals
import
BSD
,
LINUX
,
MACOS
,
WINDOWS
from
glances.timer
import
Timer
,
getTimeSinceLastUpdate
from
glances.filter
import
GlancesFilter
from
glances.logger
import
logger
...
...
@@ -403,7 +402,7 @@ class GlancesProcesses(object):
else
:
self
.
auto_sort
=
auto
self
.
_sort_key
=
key
def
kill
(
self
,
pid
,
timeout
=
3
):
"""Kill process with pid"""
assert
pid
!=
os
.
getpid
(),
"Glances can kill itself..."
...
...
glances/standalone.py
浏览文件 @
4f133b02
...
...
@@ -92,7 +92,7 @@ class GlancesStandalone(object):
# Init screen
self
.
screen
=
GlancesStdout
(
config
=
config
,
args
=
args
)
elif
args
.
stdout_csv
:
logger
.
info
(
"Stdout CSV mode is ON, following stats will be displayed: {}"
.
format
(
args
.
stdout
))
logger
.
info
(
"Stdout CSV mode is ON, following stats will be displayed: {}"
.
format
(
args
.
stdout
_csv
))
# Init screen
self
.
screen
=
GlancesStdoutCsv
(
config
=
config
,
args
=
args
)
else
:
...
...
@@ -129,15 +129,14 @@ class GlancesStandalone(object):
return True if we should continue (no exit key has been pressed)
"""
# Start a counter used to compute the time needed for
# update and export the stats
counter
=
Counter
()
# Update stats
# Start a counter used to compute the time needed
counter
=
Counter
()
self
.
stats
.
update
()
logger
.
debug
(
'Stats updated duration: {} seconds'
.
format
(
counter
.
get
()))
# Export stats
# Start a counter used to compute the time needed
counter_export
=
Counter
()
self
.
stats
.
export
(
self
.
stats
)
logger
.
debug
(
'Stats exported duration: {} seconds'
.
format
(
counter_export
.
get
()))
...
...
@@ -151,7 +150,8 @@ class GlancesStandalone(object):
if
not
self
.
quiet
:
# The update function return True if an exit key 'q' or 'ESC'
# has been pressed.
ret
=
not
self
.
screen
.
update
(
self
.
stats
,
duration
=
adapted_refresh
)
ret
=
not
self
.
screen
.
update
(
self
.
stats
,
duration
=
adapted_refresh
)
else
:
# Nothing is displayed
# Break should be done via a signal (CTRL-C)
...
...
@@ -162,9 +162,11 @@ class GlancesStandalone(object):
def
serve_forever
(
self
):
"""Wrapper to the serve_forever function."""
loop
=
True
while
loop
:
loop
=
self
.
__serve_once
()
# loop = True
# while loop:
# loop = self.__serve_once()
while
self
.
__serve_once
():
pass
self
.
end
()
def
end
(
self
):
...
...
glances/stats.py
浏览文件 @
4f133b02
...
...
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# Copyright (C) 20
19
Nicolargo <nicolas@nicolargo.com>
# Copyright (C) 20
21
Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
...
...
@@ -45,12 +45,9 @@ class GlancesStats(object):
self
.
args
=
args
# Load plugins and exports modules
self
.
first_export
=
True
self
.
load_modules
(
self
.
args
)
# Load the limits (for plugins)
# Not necessary anymore, configuration file is loaded on init
# self.load_limits(self.config)
def
__getattr__
(
self
,
item
):
"""Overwrite the getattr method in case of attribute is not found.
...
...
@@ -229,31 +226,33 @@ class GlancesStats(object):
# If current plugin is disable
# then continue to next plugin
continue
start_duration
=
Counter
()
# Update the stats...
self
.
_plugins
[
p
].
update
()
# ... the history
self
.
_plugins
[
p
].
update_stats_history
()
# ... and the views
self
.
_plugins
[
p
].
update_views
()
# logger.debug("Plugin {} update duration: {} seconds".format(p,
# start_duration.get()))
def
export
(
self
,
input_stats
=
None
):
"""Export all the stats.
Each export module is ran in a dedicated thread.
"""
# threads = []
if
self
.
first_export
:
logger
.
debug
(
"Do not export stats during the first iteration because some information are missing"
)
self
.
first_export
=
False
return
False
input_stats
=
input_stats
or
{}
for
e
in
self
.
_exports
:
logger
.
debug
(
"Export stats using the %s module"
%
e
)
thread
=
threading
.
Thread
(
target
=
self
.
_exports
[
e
].
update
,
args
=
(
input_stats
,))
# threads.append(thread)
thread
.
start
()
return
True
def
getAll
(
self
):
"""Return all the stats (list)."""
return
[
self
.
_plugins
[
p
].
get_raw
()
for
p
in
self
.
_plugins
]
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录