Merge branch 'issue2734' into develop

pull/2742/head
nicolargo 2024-04-26 08:14:15 +02:00
commit 9dc221c789
12 changed files with 324 additions and 229 deletions

View File

@ -110,13 +110,18 @@ steal_critical=90
#steal_log=True
#
# Context switch limit (core / second)
# Leave commented to just use the default config (critical is 50000*# (Logical CPU cores)
# Leave commented to just use the default config critical is 50000*(Logical CPU cores)
#ctx_switches_careful=10000
#ctx_switches_warning=12000
#ctx_switches_critical=14000
[percpu]
disable=False
# Define the maximum number of CPU displayed at a time
# If the number of CPU is higher than the one configured in max_cpu_display then:
# - display top 'max_cpu_display' (sorted by CPU consumption)
# - a last line will be added with the mean of all other CPUs
max_cpu_display=4
# Define CPU thresholds in %
# Default values if not defined: 50/70/90
user_careful=50

View File

@ -110,13 +110,18 @@ steal_critical=90
#steal_log=True
#
# Context switch limit (core / second)
# Leave commented to just use the default config (critical is 50000*# (Logical CPU cores)
# Leave commented to just use the default config critical is 50000*(Logical CPU cores)
#ctx_switches_careful=10000
#ctx_switches_warning=12000
#ctx_switches_critical=14000
[percpu]
disable=False
# Define the maximum number of CPU displayed at a time
# If the number of CPU is higher than the one configured in max_cpu_display then:
# - display top 'max_cpu_display' (sorted by CPU consumption)
# - a last line will be added with the mean of all other CPUs
max_cpu_display=4
# Define CPU thresholds in %
# Default values if not defined: 50/70/90
user_careful=50

View File

@ -53,6 +53,19 @@ To switch to per-CPU stats, just hit the ``1`` key:
.. image:: ../_static/per-cpu.png
In this case, Glances will show on line per logical CPU on the system.
If you have multiple core, it is possible to define the maximun number
of CPU to display. The top 'max_cpu_display' will be display and an
extra line with the mean of all others CPU will be added.
.. code-block:: ini
[percpu]
# Define the maximum number of CPU display at a time
# If the number of CPU is higher than:
# - display the top 'max_cpu_display' (sorted by CPU consumption)
# - a last line will be added with the sum of all other CPUs
max_cpu_display=4
Logical cores means the number of physical cores multiplied by the number
of threads that can run on each core (this is known as Hyper Threading).

View File

@ -141,7 +141,7 @@ Get plugin stats::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.924252986907959},
"timer": 0.40851712226867676},
{"count": 0,
"countmax": 20.0,
"countmin": None,
@ -150,7 +150,7 @@ Get plugin stats::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.9241466522216797}]
"timer": 0.40842318534851074}]
Fields descriptions:
@ -178,7 +178,7 @@ Get a specific item when field matches the given value::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.924252986907959}]}
"timer": 0.40851712226867676}]}
GET cloud
---------
@ -226,18 +226,18 @@ Get plugin stats::
"engine": "docker",
"id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb",
"image": ["portainer/portainer-ce:2.9.3"],
"io": {"cumulative_ior": 65536, "cumulative_iow": 839680},
"io": {"cumulative_ior": 102400, "cumulative_iow": 991232},
"key": "name",
"memory": {"cache": None,
"limit": 7823499264,
"max_usage": None,
"rss": None,
"usage": 14393344},
"memory_usage": 14393344,
"usage": 13750272},
"memory_usage": 13750272,
"name": "portainer",
"network": {"cumulative_rx": 1619220, "cumulative_tx": 0},
"network": {"cumulative_rx": 2702092, "cumulative_tx": 0},
"status": "running",
"uptime": "yesterday"}]
"uptime": "2 days"}]
Fields descriptions:
@ -273,18 +273,18 @@ Get a specific item when field matches the given value::
"engine": "docker",
"id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb",
"image": ["portainer/portainer-ce:2.9.3"],
"io": {"cumulative_ior": 65536, "cumulative_iow": 839680},
"io": {"cumulative_ior": 102400, "cumulative_iow": 991232},
"key": "name",
"memory": {"cache": None,
"limit": 7823499264,
"max_usage": None,
"rss": None,
"usage": 14393344},
"memory_usage": 14393344,
"usage": 13750272},
"memory_usage": 13750272,
"name": "portainer",
"network": {"cumulative_rx": 1619220, "cumulative_tx": 0},
"network": {"cumulative_rx": 2702092, "cumulative_tx": 0},
"status": "running",
"uptime": "yesterday"}]}
"uptime": "2 days"}]}
GET core
--------
@ -311,19 +311,19 @@ Get plugin stats::
# curl http://localhost:61208/api/4/cpu
{"cpucore": 4,
"ctx_switches": 239191661,
"ctx_switches": 308101461,
"guest": 0.0,
"idle": 81.6,
"interrupts": 120974887,
"iowait": 0.4,
"idle": 75.0,
"interrupts": 153524970,
"iowait": 0.8,
"irq": 0.0,
"nice": 0.0,
"soft_interrupts": 64042196,
"soft_interrupts": 83624527,
"steal": 0.0,
"syscalls": 0,
"system": 2.7,
"total": 18.0,
"user": 15.3}
"system": 4.8,
"total": 24.2,
"user": 19.4}
Fields descriptions:
@ -356,7 +356,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/cpu/total
{"total": 18.0}
{"total": 24.2}
GET diskio
----------
@ -366,10 +366,10 @@ Get plugin stats::
# curl http://localhost:61208/api/4/diskio
[{"disk_name": "sda",
"key": "disk_name",
"read_bytes": 21587683840,
"read_count": 1376851,
"write_bytes": 25792397312,
"write_count": 710177},
"read_bytes": 25391079936,
"read_count": 1713349,
"write_bytes": 29189177344,
"write_count": 847905},
{"disk_name": "sda1",
"key": "disk_name",
"read_bytes": 3837952,
@ -404,10 +404,10 @@ Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/diskio/disk_name/sda
{"sda": [{"disk_name": "sda",
"key": "disk_name",
"read_bytes": 21587683840,
"read_count": 1376851,
"write_bytes": 25792397312,
"write_count": 710177}]}
"read_bytes": 25391079936,
"read_count": 1713349,
"write_bytes": 29189177344,
"write_count": 847905}]}
GET folders
-----------
@ -434,13 +434,13 @@ Get plugin stats::
# curl http://localhost:61208/api/4/fs
[{"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 30779019264,
"free": 30636216320,
"fs_type": "ext4",
"key": "mnt_point",
"mnt_point": "/",
"percent": 86.7,
"size": 243334156288,
"used": 200167682048},
"used": 200310484992},
{"device_name": "zsfpool",
"free": 31195136,
"fs_type": "zfs",
@ -469,13 +469,13 @@ Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/fs/mnt_point//
{"/": [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 30779019264,
"free": 30636216320,
"fs_type": "ext4",
"key": "mnt_point",
"mnt_point": "/",
"percent": 86.7,
"size": 243334156288,
"used": 200167682048}]}
"used": 200310484992}]}
GET gpu
-------
@ -508,8 +508,8 @@ GET ip
Get plugin stats::
# curl http://localhost:61208/api/4/ip
{"address": "192.168.0.32",
"gateway": "192.168.0.254",
{"address": "192.168.1.14",
"gateway": "192.168.1.1",
"mask": "255.255.255.0",
"mask_cidr": 24,
"public_address": "",
@ -527,7 +527,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/ip/gateway
{"gateway": "192.168.0.254"}
{"gateway": "192.168.1.1"}
GET irq
-------
@ -548,10 +548,7 @@ GET load
Get plugin stats::
# curl http://localhost:61208/api/4/load
{"cpucore": 4,
"min1": 0.88818359375,
"min15": 1.0537109375,
"min5": 1.0107421875}
{"cpucore": 4, "min1": 1.0244140625, "min15": 0.80859375, "min5": 1.01611328125}
Fields descriptions:
@ -563,7 +560,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/load/min1
{"min1": 0.88818359375}
{"min1": 1.0244140625}
GET mem
-------
@ -571,16 +568,16 @@ GET mem
Get plugin stats::
# curl http://localhost:61208/api/4/mem
{"active": 3001933824,
"available": 2005618688,
"buffers": 248893440,
"cached": 2834280448,
"free": 2005618688,
"inactive": 3382648832,
"percent": 74.4,
"shared": 988557312,
{"active": 2564489216,
"available": 1776594944,
"buffers": 197029888,
"cached": 2468925440,
"free": 1776594944,
"inactive": 3412475904,
"percent": 77.3,
"shared": 1127333888,
"total": 7823499264,
"used": 5817880576}
"used": 6046904320}
Fields descriptions:
@ -607,13 +604,13 @@ GET memswap
Get plugin stats::
# curl http://localhost:61208/api/4/memswap
{"free": 6126551040,
"percent": 24.2,
"sin": 1005674496,
"sout": 3159068672,
{"free": 5535707136,
"percent": 31.5,
"sin": 1238310912,
"sout": 4059365376,
"time_since_update": 1,
"total": 8082419712,
"used": 1955868672}
"used": 2546712576}
Fields descriptions:
@ -638,15 +635,15 @@ Get plugin stats::
# curl http://localhost:61208/api/4/network
[{"alias": None,
"bytes_all": 0,
"bytes_all_gauge": 2981693329,
"bytes_all_gauge": 3167828814,
"bytes_recv": 0,
"bytes_recv_gauge": 2799888851,
"bytes_recv_gauge": 2956590070,
"bytes_sent": 0,
"bytes_sent_gauge": 181804478,
"bytes_sent_gauge": 211238744,
"interface_name": "wlp2s0",
"key": "interface_name",
"speed": 0,
"time_since_update": 0.8728673458099365},
"time_since_update": 0.3503603935241699},
{"alias": None,
"bytes_all": 0,
"bytes_all_gauge": 393003,
@ -657,7 +654,7 @@ Get plugin stats::
"interface_name": "br_grafana",
"key": "interface_name",
"speed": 0,
"time_since_update": 0.8728673458099365}]
"time_since_update": 0.3503603935241699}]
Fields descriptions:
@ -692,15 +689,15 @@ Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/network/interface_name/wlp2s0
{"wlp2s0": [{"alias": None,
"bytes_all": 0,
"bytes_all_gauge": 2981693329,
"bytes_all_gauge": 3167828814,
"bytes_recv": 0,
"bytes_recv_gauge": 2799888851,
"bytes_recv_gauge": 2956590070,
"bytes_sent": 0,
"bytes_sent_gauge": 181804478,
"bytes_sent_gauge": 211238744,
"interface_name": "wlp2s0",
"key": "interface_name",
"speed": 0,
"time_since_update": 0.8728673458099365}]}
"time_since_update": 0.3503603935241699}]}
GET now
-------
@ -708,7 +705,7 @@ GET now
Get plugin stats::
# curl http://localhost:61208/api/4/now
"2024-04-24 19:39:29 CEST"
"2024-04-25 15:35:02 CEST"
GET percpu
----------
@ -719,29 +716,29 @@ Get plugin stats::
[{"cpu_number": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 73.2,
"idle": 57.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"softirq": 1.0,
"steal": 0.0,
"system": 3.6,
"total": 26.8,
"user": 23.2},
"system": 3.0,
"total": 43.0,
"user": 2.0},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 75.2,
"idle": 21.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 5.1,
"total": 24.8,
"user": 19.7}]
"system": 6.0,
"total": 79.0,
"user": 37.0}]
Fields descriptions:
@ -770,12 +767,12 @@ Get plugin stats::
# curl http://localhost:61208/api/4/ports
[{"description": "DefaultGateway",
"host": "192.168.0.254",
"host": "192.168.1.1",
"indice": "port_0",
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.004414,
"status": 0.004807,
"timeout": 3}]
Fields descriptions:
@ -792,19 +789,19 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/ports/host
{"host": ["192.168.0.254"]}
{"host": ["192.168.1.1"]}
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/ports/host/192.168.0.254
{"192.168.0.254": [{"description": "DefaultGateway",
"host": "192.168.0.254",
"indice": "port_0",
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.004414,
"timeout": 3}]}
# curl http://localhost:61208/api/4/ports/host/192.168.1.1
{"192.168.1.1": [{"description": "DefaultGateway",
"host": "192.168.1.1",
"indice": "port_0",
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.004807,
"timeout": 3}]}
GET processcount
----------------
@ -812,7 +809,7 @@ GET processcount
Get plugin stats::
# curl http://localhost:61208/api/4/processcount
{"pid_max": 0, "running": 1, "sleeping": 332, "thread": 1612, "total": 402}
{"pid_max": 0, "running": 1, "sleeping": 334, "thread": 1661, "total": 406}
Fields descriptions:
@ -825,7 +822,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/processcount/total
{"total": 402}
{"total": 406}
GET processlist
---------------
@ -865,67 +862,67 @@ GET quicklook
Get plugin stats::
# curl http://localhost:61208/api/4/quicklook
{"cpu": 18.0,
{"cpu": 24.2,
"cpu_hz": 3000000000.0,
"cpu_hz_current": 2549918750.0,
"cpu_hz_current": 2701786500.0,
"cpu_log_core": 4,
"cpu_name": "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz",
"cpu_phys_core": 2,
"load": 26.3,
"mem": 74.4,
"load": 20.2,
"mem": 77.3,
"percpu": [{"cpu_number": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 73.2,
"idle": 57.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"softirq": 1.0,
"steal": 0.0,
"system": 3.6,
"total": 26.8,
"user": 23.2},
"system": 3.0,
"total": 43.0,
"user": 2.0},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 75.2,
"idle": 21.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 5.1,
"total": 24.8,
"user": 19.7},
"system": 6.0,
"total": 79.0,
"user": 37.0},
{"cpu_number": 2,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 89.5,
"iowait": 1.8,
"idle": 58.0,
"iowait": 1.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.8,
"total": 10.5,
"user": 7.0},
"system": 0.0,
"total": 42.0,
"user": 5.0},
{"cpu_number": 3,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 87.0,
"iowait": 0.9,
"idle": 59.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.9,
"softirq": 0.0,
"steal": 0.0,
"system": 0.9,
"total": 13.0,
"user": 10.4}],
"swap": 24.2}
"system": 2.0,
"total": 41.0,
"user": 4.0}],
"swap": 31.5}
Fields descriptions:
@ -1047,7 +1044,7 @@ GET uptime
Get plugin stats::
# curl http://localhost:61208/api/4/uptime
"4 days, 8:19:34"
"5 days, 4:15:06"
GET version
-----------
@ -1107,34 +1104,34 @@ GET stats history
History of a plugin::
# curl http://localhost:61208/api/4/cpu/history
{"system": [["2024-04-24T19:39:30.842812", 2.7],
["2024-04-24T19:39:31.868404", 1.4],
["2024-04-24T19:39:32.992936", 1.4]],
"user": [["2024-04-24T19:39:30.842803", 15.3],
["2024-04-24T19:39:31.868395", 3.4],
["2024-04-24T19:39:32.992925", 3.4]]}
{"system": [["2024-04-25T15:35:03.217740", 4.8],
["2024-04-25T15:35:04.235742", 4.1],
["2024-04-25T15:35:05.356599", 4.1]],
"user": [["2024-04-25T15:35:03.217729", 19.4],
["2024-04-25T15:35:04.235737", 16.1],
["2024-04-25T15:35:05.356587", 16.1]]}
Limit history to last 2 values::
# curl http://localhost:61208/api/4/cpu/history/2
{"system": [["2024-04-24T19:39:31.868404", 1.4],
["2024-04-24T19:39:32.992936", 1.4]],
"user": [["2024-04-24T19:39:31.868395", 3.4],
["2024-04-24T19:39:32.992925", 3.4]]}
{"system": [["2024-04-25T15:35:04.235742", 4.1],
["2024-04-25T15:35:05.356599", 4.1]],
"user": [["2024-04-25T15:35:04.235737", 16.1],
["2024-04-25T15:35:05.356587", 16.1]]}
History for a specific field::
# curl http://localhost:61208/api/4/cpu/system/history
{"system": [["2024-04-24T19:39:29.207977", 2.7],
["2024-04-24T19:39:30.842812", 2.7],
["2024-04-24T19:39:31.868404", 1.4],
["2024-04-24T19:39:32.992936", 1.4]]}
{"system": [["2024-04-25T15:35:02.014345", 4.8],
["2024-04-25T15:35:03.217740", 4.8],
["2024-04-25T15:35:04.235742", 4.1],
["2024-04-25T15:35:05.356599", 4.1]]}
Limit history for a specific field to last 2 values::
# curl http://localhost:61208/api/4/cpu/system/history
{"system": [["2024-04-24T19:39:31.868404", 1.4],
["2024-04-24T19:39:32.992936", 1.4]]}
{"system": [["2024-04-25T15:35:04.235742", 4.1],
["2024-04-25T15:35:05.356599", 4.1]]}
GET limits (used for thresholds)
--------------------------------
@ -1231,6 +1228,7 @@ All limits/thresholds::
"percpu_iowait_careful": 50.0,
"percpu_iowait_critical": 90.0,
"percpu_iowait_warning": 70.0,
"percpu_max_cpu_display": 4.0,
"percpu_system_careful": 50.0,
"percpu_system_critical": 90.0,
"percpu_system_warning": 70.0,

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "GLANCES" "1" "Apr 24, 2024" "4.0.0_beta04" "Glances"
.TH "GLANCES" "1" "Apr 25, 2024" "4.0.0_beta04" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS

View File

@ -175,7 +175,13 @@ Examples of use:
help='task\'s cpu usage will be divided by the total number of CPUs',
)
parser.add_argument(
'-1', '--percpu', action='store_true', default=False, dest='percpu', help='start Glances in per CPU mode'
'-1',
'--percpu',
'--per-cpu',
action='store_true',
default=False,
dest='percpu',
help='start Glances in per CPU mode'
)
parser.add_argument(
'-2',

View File

@ -13,6 +13,8 @@ from __future__ import division
from math import modf
from glances.logger import logger
class Bar(object):
"""Manage bar (progression or status).

View File

@ -1,61 +1,35 @@
<template>
<section id="percpu" class="plugin">
<div class="table" v-for="(cpus, cpusChunkId) in cpusChunks" :key="cpusChunkId">
<div class="table">
<div class="table-row">
<div class="table-cell text-left title">
<span v-if="cpusChunkId === 0">PER CPU</span>
<div class="table-cell text-left title" v-if="args.disable_quicklook">CPU</div>
<div class="table-cell" v-if="args.disable_quicklook">total</div>
<div class="table-cell">user</div>
<div class="table-cell">system</div>
<div class="table-cell">idle</div>
<div class="table-cell">iowait</div>
<div class="table-cell">steal</div>
</div>
<div class="table-row" v-for="(percpu, percpuId) in percpuStats" :key="percpuId">
<div class="table-cell text-left" v-if="args.disable_quicklook">
CPU{{ percpu.cpu_number }}
</div>
<div class="table-cell" v-for="(percpu, percpuId) in cpus" :key="percpuId">
<div class="table-cell" v-if="args.disable_quicklook">
{{ percpu.total }}%
</div>
</div>
<div class="table-row">
<div class="table-cell text-left">user:</div>
<div
class="table-cell"
v-for="(percpu, percpuId) in cpus"
:key="percpuId"
:class="getUserAlert(percpu)"
>
<div class="table-cell" :class="getUserAlert(percpu)">
{{ percpu.user }}%
</div>
</div>
<div class="table-row">
<div class="table-cell text-left">system:</div>
<div
class="table-cell"
v-for="(percpu, percpuId) in cpus"
:key="percpuId"
:class="getSystemAlert(percpu)"
>
<div class="table-cell" :class="getSystemAlert(percpu)">
{{ percpu.system }}%
</div>
</div>
<div class="table-row">
<div class="table-cell text-left">idle:</div>
<div class="table-cell" v-for="(percpu, percpuId) in cpus" :key="percpuId">
<div class="table-cell" v-show="percpu.idle != undefined">
{{ percpu.idle }}%
</div>
</div>
<div class="table-row" v-if="cpus[0].iowait">
<div class="table-cell text-left">iowait:</div>
<div
class="table-cell"
v-for="(percpu, percpuId) in cpus"
:key="percpuId"
:class="getSystemAlert(percpu)"
>
<div class="table-cell" v-show="percpu.iowait != undefined" :class="getIOWaitAlert(percpu)">
{{ percpu.iowait }}%
</div>
</div>
<div class="table-row" v-if="cpus[0].steal">
<div class="table-cell text-left">steal:</div>
<div
class="table-cell"
v-for="(percpu, percpuId) in cpus"
:key="percpuId"
:class="getSystemAlert(percpu)"
>
<div class="table-cell" v-show="percpu.steal != undefined">
{{ percpu.steal }}%
</div>
</div>
@ -64,6 +38,7 @@
</template>
<script>
import { store } from '../store.js';
import { GlancesHelper } from '../services.js';
import { chunk } from 'lodash';
@ -73,23 +48,20 @@ export default {
type: Object
}
},
data() {
return {
store
};
},
computed: {
args() {
return this.store.args || {};
},
config() {
return this.store.config || {};
},
percpuStats() {
return this.data.stats['percpu'];
},
cpusChunks() {
const retval = this.percpuStats.map((cpuData) => {
return {
number: cpuData.cpu_number,
total: cpuData.total,
user: cpuData.user,
system: cpuData.system,
idle: cpuData.idle,
iowait: cpuData.iowait,
steal: cpuData.steal
};
});
return chunk(retval, 4);
}
},
methods: {
@ -98,6 +70,9 @@ export default {
},
getSystemAlert(cpu) {
return GlancesHelper.getAlert('percpu', 'percpu_system_', cpu.system);
},
getIOWaitAlert(cpu) {
return GlancesHelper.getAlert('percpu', 'percpu_iowait_', cpu.system);
}
}
};

View File

@ -82,6 +82,9 @@ export default {
args() {
return this.store.args || {};
},
config() {
return this.store.config || {};
},
stats() {
return this.data.stats['quicklook'];
},
@ -101,10 +104,22 @@ export default {
return this.stats.cpu_hz;
},
percpus() {
return this.stats.percpu.map(({ cpu_number: number, total }) => ({
number,
total
}));
var cpu_list = this.stats.percpu.map(({ cpu_number: number, total }) => ({ number, total }))
var max_cpu_display = parseInt(this.config.percpu.max_cpu_display)
if (this.stats.percpu.length > max_cpu_display) {
var cpu_list_sorted = cpu_list.sort(function (a, b) { return b.total - a.total; })
var other_cpu = {
number: "x",
total: Number((cpu_list_sorted.slice(max_cpu_display).reduce((n, { total }) => n + total, 0) / (this.stats.percpu.length - max_cpu_display)).toFixed(1))
}
// Add the top n this
// and the mean of others CPU
cpu_list_sorted = cpu_list_sorted.slice(0, max_cpu_display)
cpu_list_sorted.push(other_cpu)
}
return this.stats.percpu.length <= max_cpu_display
? cpu_list
: cpu_list_sorted
},
stats_list_after_cpu() {
return this.view.list.filter((key) => !key.includes('cpu'));

File diff suppressed because one or more lines are too long

View File

@ -9,6 +9,7 @@
"""Per-CPU plugin."""
from glances.logger import logger
from glances.cpu_percent import cpu_percent
from glances.plugins.plugin.model import GlancesPluginModel
@ -106,6 +107,9 @@ class PluginModel(GlancesPluginModel):
# We want to display the stat in the curse interface
self.display_curse = True
# Manage the maximum number of CPU to display (related to enhancement request #2734)
self.max_cpu_display = config.get_int_value('percpu', 'max_cpu_display', 4)
def get_key(self):
"""Return the key of the list."""
return 'cpu_number'
@ -139,29 +143,44 @@ class PluginModel(GlancesPluginModel):
if not self.stats or not self.args.percpu or self.is_disabled():
return ret
# Define the default header
header = ['user', 'system', 'idle', 'iowait', 'steal']
# Build the string message
if self.is_disabled('quicklook'):
msg = '{:7}'.format('PER CPU')
msg = '{:5}'.format('CPU')
ret.append(self.curse_add_line(msg, "TITLE"))
header.insert(0, 'total')
# Per CPU stats displayed per line
for stat in ['user', 'system', 'idle', 'iowait', 'steal']:
for stat in header:
if stat not in self.stats[0]:
continue
msg = '{:>7}'.format(stat)
ret.append(self.curse_add_line(msg))
# Manage the maximum number of CPU to display (related to enhancement request #2734)
if len(self.stats) > self.max_cpu_display:
# If the number of CPU is > max_cpu_display then sort and display top 'n'
percpu_list = sorted(self.stats, key=lambda x: x['total'], reverse=True)
else:
percpu_list = self.stats
# Per CPU stats displayed per column
for cpu in self.stats:
for cpu in percpu_list[0: self.max_cpu_display]:
ret.append(self.curse_new_line())
if self.is_disabled('quicklook'):
try:
msg = '{:6.1f}%'.format(cpu['total'])
cpu_id = cpu[cpu['key']]
if cpu_id < 10:
msg = 'CPU{:1} '.format(cpu_id)
else:
msg = '{:4} '.format(cpu_id)
except TypeError:
# TypeError: string indices must be integers (issue #1027)
msg = '{:>6}%'.format('?')
msg = '{:4} '.format('?')
ret.append(self.curse_add_line(msg))
for stat in ['user', 'system', 'idle', 'iowait', 'steal']:
for stat in header:
if stat not in self.stats[0]:
continue
try:
@ -170,4 +189,21 @@ class PluginModel(GlancesPluginModel):
msg = '{:>6}%'.format('?')
ret.append(self.curse_add_line(msg, self.get_alert(cpu[stat], header=stat)))
# Add a new line with sum of all others CPU
if len(self.stats) > self.max_cpu_display:
ret.append(self.curse_new_line())
if self.is_disabled('quicklook'):
ret.append(self.curse_add_line('CPU* '))
for stat in header:
if stat not in self.stats[0]:
continue
cpu_stat = sum([i[stat] for i in percpu_list[0: self.max_cpu_display]]) / len(
[i[stat] for i in percpu_list[0: self.max_cpu_display]]
)
try:
msg = '{:6.1f}%'.format(cpu_stat)
except TypeError:
msg = '{:>6}%'.format('?')
ret.append(self.curse_add_line(msg, self.get_alert(cpu_stat, header=stat)))
return ret

View File

@ -85,13 +85,15 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the quicklook plugin."""
super(PluginModel, self).__init__(
args=args, config=config,
items_history_list=items_history_list,
fields_description=fields_description
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
)
# We want to display the stat in the curse interface
self.display_curse = True
# Manage the maximum number of CPU to display (related to enhancement request #2734)
self.max_cpu_display = config.get_int_value('percpu', 'max_cpu_display', 4)
# Define the stats list
self.stats_list = self.get_conf_value('list', default=self.DEFAULT_STATS_LIST)
if not set(self.stats_list).issubset(self.AVAILABLE_STATS_LIST):
@ -158,9 +160,7 @@ class PluginModel(GlancesPluginModel):
self.views[key]['decoration'] = self.get_alert(self.stats[key], header=key)
# Alert for LOAD
self.views['load']['decoration'] = self.get_alert(
self.stats['load'], header='load'
)
self.views['load']['decoration'] = self.get_alert(self.stats['load'], header='load')
# Define the list of stats to display
self.views['list'] = self.stats_list
@ -186,8 +186,7 @@ class PluginModel(GlancesPluginModel):
data[key] = Sparkline(max_width)
else:
# Fallback to bar if Sparkline module is not installed
data[key] = Bar(max_width,
bar_char=self.get_conf_value('bar_char', default=['|'])[0])
data[key] = Bar(max_width, bar_char=self.get_conf_value('bar_char', default=['|'])[0])
# Build the string message
##########################
@ -209,23 +208,7 @@ class PluginModel(GlancesPluginModel):
# Loop over CPU, MEM and LOAD
for key in self.stats_list:
if key == 'cpu' and args.percpu:
if type(data[key]).__name__ == 'Sparkline':
raw_cpu = self.get_raw_history(item='percpu', nb=data[key].size)
for cpu_index, cpu in enumerate(self.stats['percpu']):
if type(data[key]).__name__ == 'Sparkline':
# Sparkline display an history
data[key].percents = [i[1][cpu_index]['total'] for i in raw_cpu]
# A simple padding in order to align metrics to the right
data[key].percents += [None] * (data[key].size - len(data[key].percents))
else:
# Bar only the last value
data[key].percent = cpu['total']
if cpu[cpu['key']] < 10:
msg = '{:3}{} '.format(key.upper(), cpu['cpu_number'])
else:
msg = '{:4} '.format(cpu['cpu_number'])
ret.extend(self._msg_create_line(msg, data[key], key))
ret.append(self.curse_new_line())
ret.extend(self._msg_per_cpu(data, key, max_width))
else:
if type(data[key]).__name__ == 'Sparkline':
# Sparkline display an history
@ -245,6 +228,63 @@ class PluginModel(GlancesPluginModel):
# Return the message with decoration
return ret
def _msg_per_cpu(self, data, key, max_width):
"""Create per-cpu view"""
ret = []
# Get history (only used with the sparkline option)
if type(data[key]).__name__ == 'Sparkline':
raw_cpu = self.get_raw_history(item='percpu', nb=data[key].size)
# Manage the maximum number of CPU to display (related to enhancement request #2734)
if len(self.stats['percpu']) > self.max_cpu_display:
# If the number of CPU is > max_cpu_display then sort and display top 'n'
percpu_list = sorted(self.stats['percpu'], key=lambda x: x['total'], reverse=True)
else:
percpu_list = self.stats['percpu']
# Display the first max_cpu_display CPU
for cpu in percpu_list[0: self.max_cpu_display]:
cpu_id = cpu[cpu['key']]
if type(data[key]).__name__ == 'Sparkline':
# Sparkline display an history
data[key].percents = [i[1][cpu_id]['total'] for i in raw_cpu]
# A simple padding in order to align metrics to the right
data[key].percents += [None] * (data[key].size - len(data[key].percents))
else:
# Bar will only display the last value
data[key].percent = cpu['total']
if cpu_id < 10:
msg = '{:3}{} '.format(key.upper(), cpu_id)
else:
msg = '{:4} '.format(cpu_id)
ret.extend(self._msg_create_line(msg, data[key], key))
ret.append(self.curse_new_line())
# Add a new line with sum of all others CPU
if len(self.stats['percpu']) > self.max_cpu_display:
if type(data[key]).__name__ == 'Sparkline':
sum_other = Sparkline(max_width)
# Sparkline display an history
sum_other.percents = [
sum([i['total'] for i in r[1] if i[i['key']] >= self.max_cpu_display])
/ len([i['total'] for i in r[1] if i[i['key']] >= self.max_cpu_display])
for r in raw_cpu
]
# A simple padding in order to align metrics to the right
sum_other.percents += [None] * (sum_other.size - len(sum_other.percents))
else:
# Bar will only display the last value
sum_other = Bar(max_width, bar_char=self.get_conf_value('bar_char', default=['|'])[0])
sum_other.percent = sum([i['total'] for i in percpu_list[self.max_cpu_display:]]) / len(
percpu_list[self.max_cpu_display:]
)
msg = msg = '{:3}* '.format(key.upper())
ret.extend(self._msg_create_line(msg, sum_other, key))
ret.append(self.curse_new_line())
return ret
def _msg_create_line(self, msg, data, key):
"""Create a new line to the Quick view."""
return [