New Grafana Dashboard

This commit is contained in:
nicolargo 2018-04-02 21:54:47 +02:00
parent 80db8225c4
commit 5266a62d0c
7 changed files with 3008 additions and 2788 deletions

22
NEWS
View File

@ -25,6 +25,11 @@ Enhancements and new features:
* Add a new output mode to stdout #1168 * Add a new output mode to stdout #1168
* Huge refactor of the WebUI packaging thanks to @spike008t #1239 * Huge refactor of the WebUI packaging thanks to @spike008t #1239
One more thing ! A new Grafana Dash is available with:
* Network interface variable
* Disk variable
* Container CPU
Bugs corrected: Bugs corrected:
* Crash in the Wifi plugin on my Laptop #1151 * Crash in the Wifi plugin on my Laptop #1151
@ -68,6 +73,23 @@ News command line options:
News configuration keys in the glances.conf file: News configuration keys in the glances.conf file:
Graph:
[graph]
# Configuration for the --export graph option
# Set the path where the graph (.svg files) will be created
# Can be overwrite by the --graph-path command line option
path=/tmp
# It is possible to generate the graphs automatically by setting the
# generate_every to a non zero value corresponding to the seconds between
# two generation. Set it to 0 to disable graph auto generation.
generate_every=60
# See followings configuration keys definitions in the Pygal lib documentation
# http://pygal.org/en/stable/documentation/index.html
width=800
height=600
style=DarkStyle
Processes list Nice value: Processes list Nice value:
[processlist] [processlist]

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -92,10 +92,10 @@ class GlancesExport(object):
for opt in mandatories: for opt in mandatories:
setattr(self, opt, self.config.get_value(section, opt)) setattr(self, opt, self.config.get_value(section, opt))
except NoSectionError: except NoSectionError:
logger.critical("No {} configuration found".format(section)) logger.error("No {} configuration found".format(section))
return False return False
except NoOptionError as e: except NoOptionError as e:
logger.critical("Error in the {} configuration ({})".format(section, e)) logger.error("Error in the {} configuration ({})".format(section, e))
return False return False
# Load options # Load options

View File

@ -39,6 +39,31 @@ except ImportError as e:
else: else:
import_error_tag = False import_error_tag = False
# Define the items history list (list of items to add to history)
# TODO: For the moment limited to the CPU. Had to change the graph exports
# method to display one graph per container.
# items_history_list = [{'name': 'cpu_percent',
# 'description': 'Container CPU consumption in %',
# 'y_unit': '%'},
# {'name': 'memory_usage',
# 'description': 'Container memory usage in bytes',
# 'y_unit': 'B'},
# {'name': 'network_rx',
# 'description': 'Container network RX bitrate in bits per second',
# 'y_unit': 'bps'},
# {'name': 'network_tx',
# 'description': 'Container network TX bitrate in bits per second',
# 'y_unit': 'bps'},
# {'name': 'io_r',
# 'description': 'Container IO bytes read per second',
# 'y_unit': 'Bps'},
# {'name': 'io_w',
# 'description': 'Container IO bytes write per second',
# 'y_unit': 'Bps'}]
items_history_list = [{'name': 'cpu_percent',
'description': 'Container CPU consumption in %',
'y_unit': '%'}]
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""Glances Docker plugin. """Glances Docker plugin.
@ -48,7 +73,8 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin.""" """Init the plugin."""
super(Plugin, self).__init__(args=args) super(Plugin, self).__init__(args=args,
items_history_list=items_history_list)
# The plgin can be disable using: args.disable_docker # The plgin can be disable using: args.disable_docker
self.args = args self.args = args
@ -198,14 +224,26 @@ class Plugin(GlancesPlugin):
# Standards stats # Standards stats
if container_stats['Status'] in ('running', 'paused'): if container_stats['Status'] in ('running', 'paused'):
container_stats['cpu'] = self.get_docker_cpu(container.id, self.thread_list[container.id].stats) container_stats['cpu'] = self.get_docker_cpu(container.id, self.thread_list[container.id].stats)
container_stats['cpu_percent'] = container_stats['cpu'].get('total', None)
container_stats['memory'] = self.get_docker_memory(container.id, self.thread_list[container.id].stats) container_stats['memory'] = self.get_docker_memory(container.id, self.thread_list[container.id].stats)
container_stats['network'] = self.get_docker_network(container.id, self.thread_list[container.id].stats) container_stats['memory_usage'] = container_stats['memory'].get('usage', None)
container_stats['io'] = self.get_docker_io(container.id, self.thread_list[container.id].stats) container_stats['io'] = self.get_docker_io(container.id, self.thread_list[container.id].stats)
container_stats['io_r'] = container_stats['io'].get('ior', None)
container_stats['io_w'] = container_stats['io'].get('iow', None)
container_stats['network'] = self.get_docker_network(container.id, self.thread_list[container.id].stats)
container_stats['network_rx'] = container_stats['network'].get('rx', None)
container_stats['network_tx'] = container_stats['network'].get('tx', None)
else: else:
container_stats['cpu'] = {} container_stats['cpu'] = {}
container_stats['cpu_percent'] = None
container_stats['memory'] = {} container_stats['memory'] = {}
container_stats['network'] = {} container_stats['memory_percent'] = None
container_stats['io'] = {} container_stats['io'] = {}
container_stats['io_r'] = None
container_stats['io_w'] = None
container_stats['network'] = {}
container_stats['network_rx'] = None
container_stats['network_tx'] = None
# Add current container stats to the stats list # Add current container stats to the stats list
self.stats['containers'].append(container_stats) self.stats['containers'].append(container_stats)
@ -537,9 +575,10 @@ class Plugin(GlancesPlugin):
msg = '{:>7}'.format('_') msg = '{:>7}'.format('_')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
# IO R/W # IO R/W
unit = 'B'
for r in ['ior', 'iow']: for r in ['ior', 'iow']:
try: try:
value = self.auto_unit(int(container['io'][r] // container['io']['time_since_update'] * 8)) + "b" value = self.auto_unit(int(container['io'][r] // container['io']['time_since_update'])) + unit
msg = '{:>7}'.format(value) msg = '{:>7}'.format(value)
except KeyError: except KeyError:
msg = '{:>7}'.format('_') msg = '{:>7}'.format('_')

View File

@ -35,7 +35,6 @@ snmp_oid = {'default': {'interface_name': '1.3.6.1.2.1.2.2.1.2',
'cumulative_tx': '1.3.6.1.2.1.2.2.1.16'}} 'cumulative_tx': '1.3.6.1.2.1.2.2.1.16'}}
# Define the history items list # Define the history items list
# All items in this list will be historised if the --enable-history tag is set
items_history_list = [{'name': 'rx', items_history_list = [{'name': 'rx',
'description': 'Download rate per second', 'description': 'Download rate per second',
'y_unit': 'bit/s'}, 'y_unit': 'bit/s'},

View File

@ -162,13 +162,13 @@ class GlancesPlugin(object):
else: else:
item_name = self.get_key() item_name = self.get_key()
# Build the history # Build the history
if self.stats and self._history_enable(): if self.get_export() and self._history_enable():
for i in self.get_items_history_list(): for i in self.get_items_history_list():
if isinstance(self.stats, list): if isinstance(self.get_export(), list):
# Stats is a list of data # Stats is a list of data
# Iter throught it (for exemple, iter throught network # Iter throught it (for exemple, iter throught network
# interface) # interface)
for l in self.stats: for l in self.get_export():
self.stats_history.add( self.stats_history.add(
str(l[item_name]) + '_' + i['name'], str(l[item_name]) + '_' + i['name'],
l[i['name']], l[i['name']],
@ -178,7 +178,7 @@ class GlancesPlugin(object):
# Stats is not a list # Stats is not a list
# Add the item to the history directly # Add the item to the history directly
self.stats_history.add(i['name'], self.stats_history.add(i['name'],
self.stats[i['name']], self.get_export()[i['name']],
description=i['description'], description=i['description'],
history_max_size=self._limits['history_size']) history_max_size=self._limits['history_size'])