mirror of
https://github.com/nicolargo/glances.git
synced 2024-12-01 22:14:06 +03:00
Add per container CPU and MEM monitoring in the Docker plugin (issue #490)
This commit is contained in:
parent
9b6e038a18
commit
6d32061754
2
NEWS
2
NEWS
@ -18,7 +18,7 @@ Enhancements and news features:
|
||||
* Refactor export module (CSV export option is now --export-csv). It is now possible to export stats from the Glances client mode (issue #463)
|
||||
* The Web inteface is now based on BootStarp / RWD grid (issue #417, #366 and #461) Thanks to Nicolas Hart @nclsHart
|
||||
* Add the RAID plugin (issue #447)
|
||||
* Add the Docker plugin (issue #440)
|
||||
* Add the Docker plugin (issue #440) with per container CPU and memory monitoring (issue #490)
|
||||
* It is possible, through the configuration file, to define if an alarm should be logged or not (using the _log option) (issue #437)
|
||||
* You can now set alarm for Disk IO
|
||||
* API: add getAllLimits and getAllViews methods (issue#481)
|
||||
|
@ -33,6 +33,9 @@ except ImportError as e:
|
||||
docker_tag = False
|
||||
else:
|
||||
docker_tag = True
|
||||
import os
|
||||
import re
|
||||
import numbers
|
||||
|
||||
|
||||
class Plugin(GlancesPlugin):
|
||||
@ -140,14 +143,58 @@ class Plugin(GlancesPlugin):
|
||||
# u'Names': [u'/webstack_nginx_1'],
|
||||
# u'Id': u'b0da859e84eb4019cf1d965b15e9323006e510352c402d2f442ea632d61faaa5'}]
|
||||
self.stats['containers'] = self.docker_client.containers()
|
||||
# Get CPU and MEMORY stats for containers
|
||||
for c in self.stats['containers']:
|
||||
c['cpu'] = self.get_docker_cpu(c['Id'])
|
||||
c['memory'] = self.get_docker_memory(c['Id'])
|
||||
|
||||
elif self.get_input() == 'snmp':
|
||||
# Update stats using SNMP
|
||||
# Not available
|
||||
pass
|
||||
|
||||
logger.info(self.stats)
|
||||
|
||||
return self.stats
|
||||
|
||||
def get_docker_cpu(self, id):
|
||||
"""Return the container CPU usage by reading /sys/fs/cgroup/...
|
||||
Input: id is the full container id
|
||||
Output: a dict {'total': 1.49, 'user': 0.65, 'system': 0.84}"""
|
||||
ret = {}
|
||||
# Read the stats
|
||||
with open('/sys/fs/cgroup/cpuacct/docker/' + id + '/cpuacct.stat', 'r') as f:
|
||||
for line in f:
|
||||
m = re.search(r"(system|user)\s+(\d+)", line)
|
||||
if m:
|
||||
ret[m.group(1)] = int(m.group(2))
|
||||
# Get the user ticks
|
||||
ticks = self.get_user_ticks()
|
||||
if isinstance(ret["system"], numbers.Number) and isinstance(ret["user"], numbers.Number):
|
||||
ret["total"] = ret["system"] + ret["user"]
|
||||
for k in ret.keys():
|
||||
ret[k] = float(ret[k]) / ticks
|
||||
# Return the stats
|
||||
return ret
|
||||
|
||||
def get_docker_memory(self, id):
|
||||
"""Return the container MEMORY usage by reading /sys/fs/cgroup/...
|
||||
Input: id is the full container id
|
||||
Output: a dict {'rss': 1015808, 'cache': 356352}"""
|
||||
ret = {}
|
||||
# Read the stats
|
||||
with open('/sys/fs/cgroup/memory/docker/' + id + '/memory.stat', 'r') as f:
|
||||
for line in f:
|
||||
m = re.search(r"(rss|cache)\s+(\d+)", line)
|
||||
if m:
|
||||
ret[m.group(1)] = int(m.group(2))
|
||||
# Return the stats
|
||||
return ret
|
||||
|
||||
def get_user_ticks(self):
|
||||
"""return the user ticks by reading the environment variable"""
|
||||
return os.sysconf(os.sysconf_names['SC_CLK_TCK'])
|
||||
|
||||
def msg_curse(self, args=None):
|
||||
"""Return the dict to display in the curse interface."""
|
||||
# Init the return message
|
||||
@ -175,6 +222,10 @@ class Plugin(GlancesPlugin):
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{0:>26}'.format(_("Status"))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{0:>6}'.format(_("CPU%"))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = '{0:>6}'.format(_("MEM"))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
msg = ' {0:8}'.format(_("Command"))
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# Data
|
||||
@ -196,6 +247,18 @@ class Plugin(GlancesPlugin):
|
||||
msg = container['Status'].replace("minute", "min")
|
||||
msg = '{0:>26}'.format(msg[0:25])
|
||||
ret.append(self.curse_add_line(msg, status))
|
||||
# CPU
|
||||
try:
|
||||
msg = '{0:>6.1f}'.format(container['cpu']['total'])
|
||||
except KeyError:
|
||||
msg = '{0:>6}'.format('?')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# MEM
|
||||
try:
|
||||
msg = '{0:>6}'.format(self.auto_unit(container['memory']['rss']))
|
||||
except KeyError:
|
||||
msg = '{0:>6}'.format('?')
|
||||
ret.append(self.curse_add_line(msg))
|
||||
# Command
|
||||
msg = ' {0}'.format(container['Command'])
|
||||
ret.append(self.curse_add_line(msg))
|
||||
|
Loading…
Reference in New Issue
Block a user