First try for the quicklook plugin

This commit is contained in:
Nicolargo 2015-02-01 22:13:01 +01:00
parent 67e21a606e
commit ac2c1ba9e0
5 changed files with 164 additions and 18 deletions

View File

@ -118,6 +118,8 @@ Start the client browser (browser mode):\n\
dest='disable_process', help=_('disable process module')) dest='disable_process', help=_('disable process module'))
parser.add_argument('--disable-log', action='store_true', default=False, parser.add_argument('--disable-log', action='store_true', default=False,
dest='disable_log', help=_('disable log module')) dest='disable_log', help=_('disable log module'))
parser.add_argument('--disable-quicklook', action='store_true', default=False,
dest='disable_quicklook', help=_('disable quicklook module'))
parser.add_argument('--disable-bold', action='store_false', default=True, parser.add_argument('--disable-bold', action='store_false', default=True,
dest='disable_bold', help=_('disable bold mode in the terminal')) dest='disable_bold', help=_('disable bold mode in the terminal'))
parser.add_argument('--enable-process-extended', action='store_true', default=False, parser.add_argument('--enable-process-extended', action='store_true', default=False,

View File

@ -40,11 +40,18 @@ class Bar(object):
""" """
def __init__(self, size): def __init__(self, size,
pre_char='[',
post_char=']',
empty_char='_'):
# Bar size # Bar size
self.__size = size self.__size = size
# Bar current percent # Bar current percent
self.__percent = 0 self.__percent = 0
# Char used for the decoration
self.__pre_char = pre_char
self.__post_char = post_char
self.__empty_char = empty_char
def get_size(self): def get_size(self):
return self.__size return self.__size
@ -69,5 +76,5 @@ class Bar(object):
if frac > 0: if frac > 0:
ret += curses_bars[int(frac * 8)] ret += curses_bars[int(frac * 8)]
whole += 1 whole += 1
ret += '_' * int(self.get_size() - whole) ret += self.__empty_char * int(self.get_size() - whole)
return ret return self.__pre_char + ret + self.__post_char

View File

@ -36,7 +36,8 @@ if not is_windows:
import curses.panel import curses.panel
from curses.textpad import Textbox from curses.textpad import Textbox
except ImportError: 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) sys.exit(1)
else: else:
from glances.outputs.glances_colorconsole import WCurseLight from glances.outputs.glances_colorconsole import WCurseLight
@ -472,7 +473,9 @@ class _GlancesCurses(object):
# ... and exit # ... and exit
return False return False
# ==================================
# Display first line (system+uptime) # Display first line (system+uptime)
# ==================================
self.new_line() self.new_line()
l = self.get_stats_display_width( l = self.get_stats_display_width(
stats_system) + self.get_stats_display_width(stats_uptime) + self.space_between_column stats_system) + self.get_stats_display_width(stats_uptime) + self.space_between_column
@ -480,42 +483,68 @@ class _GlancesCurses(object):
self.new_column() self.new_column()
self.display_plugin(stats_uptime) self.display_plugin(stats_uptime)
# ========================================================
# Display second line (CPU|PERCPU+LOAD+MEM+SWAP+<SUMMARY>) # Display second line (CPU|PERCPU+LOAD+MEM+SWAP+<SUMMARY>)
# CPU|PERCPU # ========================================================
self.init_column() self.init_column()
self.new_line() self.new_line()
# Init quicklook
stats_quicklook = {'msgdict': []}
# Start with the mandatory stats:
# CPU | PERCPU
if self.args.percpu: if self.args.percpu:
l = self.get_stats_display_width(stats_percpu) cpu_width = self.get_stats_display_width(stats_percpu)
else: else:
l = self.get_stats_display_width(stats_cpu) cpu_width = self.get_stats_display_width(stats_cpu, without_option=(screen_x < 80))
l += self.get_stats_display_width(stats_load) + self.get_stats_display_width( l = cpu_width
stats_mem) + self.get_stats_display_width(stats_memswap) # MEM & SWAP & LOAD
# Space between column mem_width = self.get_stats_display_width(stats_mem, without_option=(screen_x < 100))
space_number = int(stats_load['msgdict'] != [ l += mem_width
]) + int(stats_mem['msgdict'] != []) + int(stats_memswap['msgdict'] != []) l += self.get_stats_display_width(stats_memswap)
l += self.get_stats_display_width(stats_load)
# Quicklook plugin size is dynamic
if screen_x > 126:
# TO be adapted to the screen...
quicklook_width = 16
try:
stats_quicklook = stats.get_plugin(
'quicklook').get_stats_display(max_width=quicklook_width, args=self.args)
except AttributeError as e:
logger.debug("Quicklook plugin not available (%s)" % e)
else:
l += self.get_stats_display_width(stats_quicklook)
# Compute space between column
space_number = int(stats_quicklook['msgdict'] != [])
space_number += int(stats_mem['msgdict'] != [])
space_number += int(stats_memswap['msgdict'] != [])
space_number += int(stats_load['msgdict'] != [])
if space_number == 0: if space_number == 0:
space_number = 1 space_number = 1
if screen_x > (space_number * self.space_between_column + l): if screen_x > (space_number * self.space_between_column + l):
self.space_between_column = int((screen_x - l) / space_number) self.space_between_column = int((screen_x - l) / space_number)
# Display # Display
# logger.info(">>> Screen X: %s / Stats size: %s / Space size: %s / Nb space: %s" % (screen_x, l, self.space_between_column, space_number))
self.display_plugin(stats_quicklook)
self.new_column()
if self.args.percpu: if self.args.percpu:
self.display_plugin(stats_percpu) self.display_plugin(stats_percpu)
else: else:
self.display_plugin(stats_cpu, display_optional=(screen_x >= 80)) self.display_plugin(stats_cpu, display_optional=(screen_x >= 80))
self.new_column() self.new_column()
self.display_plugin(stats_load) self.display_plugin(stats_mem, display_optional=(screen_x >= 100))
self.new_column()
self.display_plugin(stats_mem, display_optional=(
screen_x >= (space_number * self.space_between_column + l)))
self.new_column() self.new_column()
self.display_plugin(stats_memswap) self.display_plugin(stats_memswap)
self.new_column()
self.display_plugin(stats_load)
# Space between column # Space between column
self.space_between_column = 3 self.space_between_column = 3
# Backup line position # Backup line position
self.saved_line = self.next_line self.saved_line = self.next_line
# =============================================================
# Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time) # Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time)
# =============================================================
self.init_column() self.init_column()
if (not (self.args.disable_network and self.args.disable_diskio if (not (self.args.disable_network and self.args.disable_diskio
and self.args.disable_fs and self.args.disable_raid and self.args.disable_fs and self.args.disable_raid
@ -534,6 +563,9 @@ class _GlancesCurses(object):
self.new_line() self.new_line()
self.display_plugin(stats_now) self.display_plugin(stats_now)
# ====================================
# Display right stats (process and co)
# ====================================
# If space available... # If space available...
if screen_x > 52: if screen_x > 52:
# Restore line position # Restore line position
@ -753,7 +785,8 @@ class _GlancesCurses(object):
x_max = x x_max = x
# Compute the next Glances column/line position # Compute the next Glances column/line position
self.next_column = max(self.next_column, x_max + self.space_between_column) self.next_column = max(
self.next_column, x_max + self.space_between_column)
self.next_line = max(self.next_line, y + self.space_between_line) self.next_line = max(self.next_line, y + self.space_between_line)
def erase(self): def erase(self):

View File

@ -22,6 +22,7 @@
import psutil import psutil
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
from glances.core.glances_cpu_percent import cpu_percent
# from glances.core.glances_logging import logger # from glances.core.glances_logging import logger
# SNMP OID # SNMP OID
@ -82,7 +83,7 @@ class Plugin(GlancesPlugin):
# nice (UNIX), iowait (Linux), irq (Linux, FreeBSD), steal (Linux 2.6.11+) # nice (UNIX), iowait (Linux), irq (Linux, FreeBSD), steal (Linux 2.6.11+)
# The following stats are returned by the API but not displayed in the UI: # The following stats are returned by the API but not displayed in the UI:
# softirq (Linux), guest (Linux 2.6.24+), guest_nice (Linux 3.2.0+) # softirq (Linux), guest (Linux 2.6.24+), guest_nice (Linux 3.2.0+)
self.stats['total'] = psutil.cpu_percent(interval=0.0) self.stats['total'] = cpu_percent.get()
cpu_times_percent = psutil.cpu_times_percent(interval=0.0) cpu_times_percent = psutil.cpu_times_percent(interval=0.0)
for stat in ['user', 'system', 'idle', 'nice', 'iowait', for stat in ['user', 'system', 'idle', 'nice', 'iowait',
'irq', 'softirq', 'steal', 'guest', 'guest_nice']: 'irq', 'softirq', 'steal', 'guest', 'guest_nice']:

View File

@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2015 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# 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/>.
"""Quicklook plugin."""
import psutil
from glances.plugins.glances_plugin import GlancesPlugin
from glances.core.glances_cpu_percent import cpu_percent
from glances.outputs.glances_bars import Bar
from glances.core.glances_logging import logger
class Plugin(GlancesPlugin):
"""Glances quicklook plugin.
'stats' is a dictionary.
"""
def __init__(self, args=None):
"""Init the quicklook plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
self.display_curse = True
# Init stats
self.reset()
def reset(self):
"""Reset/init the stats."""
self.stats = {}
@GlancesPlugin._log_result_decorator
def update(self):
"""Update quicklook stats using the input method."""
# Reset stats
self.reset()
# Grab quicklook stats: CPU, MEM and SWAP
if self.get_input() == 'local':
# Get the latest CPU percent value
self.stats['cpu'] = cpu_percent.get()
# Use the PsUtil lib for the memory (virtual and swap)
self.stats['mem'] = psutil.virtual_memory().percent
self.stats['swap'] = psutil.swap_memory().percent
elif self.get_input() == 'snmp':
# Not available
pass
# Update the view
self.update_views()
return self.stats
def update_views(self):
"""Update stats views"""
# Call the father's method
GlancesPlugin.update_views(self)
def msg_curse(self, args=None, max_width=10):
"""Return the list to display in the UI"""
# Init the return message
ret = []
# Only process if stats exist...
if self.stats == {} or args.disable_quicklook:
return ret
# Build the string message
bar = Bar(max_width, pre_char='|', post_char='|', empty_char=' ')
bar.set_percent(self.stats['cpu'])
msg = '{0:>4} {1}'.format(_("CPU"), bar)
ret.append(self.curse_add_line(msg))
ret.append(self.curse_new_line())
bar.set_percent(self.stats['mem'])
msg = '{0:>4} {1}'.format(_("MEM"), bar)
ret.append(self.curse_add_line(msg))
ret.append(self.curse_new_line())
bar.set_percent(self.stats['swap'])
msg = '{0:>4} {1}'.format(_("SWAP"), bar)
ret.append(self.curse_add_line(msg))
ret.append(self.curse_new_line())
# Return the message with decoration
return ret