Merge pull request #52 from jeromelebleu/dev

Implement monitoring and statistics management
This commit is contained in:
Alexis Gavoty 2013-12-17 07:55:42 -08:00
commit 2cee93d846
5 changed files with 126 additions and 33 deletions

View file

@ -39,7 +39,7 @@ general_arguments:
full: --version
help: Display YunoHost version
action: version
version: YunoHost 2.0 beta1
version: YunoHost %version%
#############################
# User #
@ -569,6 +569,19 @@ monitor:
- week
- month
### monitor_enable()
enable:
action_help: Enable server monitoring
arguments:
-n:
full: --no-stats
help: Disable monitoring statistics
action: store_true
### monitor_disable()
disable:
action_help: Disable server monitoring
#############################
# Service #

View file

@ -1,25 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__credits__ = """
Copyright (C) 2012 YunoHost
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, see http://www.gnu.org/licenses
"""
__author__ = 'Kload <kload@kload.fr>'
__version__ = '2.0 beta1'
import os
import sys
import argparse

View file

@ -22,6 +22,26 @@
"""
YunoHost core classes & functions
"""
__credits__ = """
Copyright (C) 2012 YunoHost
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, see http://www.gnu.org/licenses
"""
__author__ = 'Kload <kload@kload.fr>'
__version__ = '2.0-beta3'
import os
import sys
try:
@ -468,10 +488,13 @@ def parse_dict(action_map):
# Add general arguments
for arg_name, arg_params in action_map['general_arguments'].items():
if 'version' in arg_params:
v = arg_params['version']
arg_params['version'] = v.replace('%version%', __version__)
if 'full' in arg_params:
arg_names = [arg_name, arg_params['full']]
arg_fullname = arg_params['full']
del arg_params['full']
arg_names = [arg_name, arg_params['full']]
arg_fullname = arg_params['full']
del arg_params['full']
else: arg_names = [arg_name]
parsers['general'].add_argument(*arg_names, **arg_params)

View file

@ -34,10 +34,13 @@ import os.path
import cPickle as pickle
from urllib import urlopen
from datetime import datetime, timedelta
from yunohost import YunoHostError
from yunohost import YunoHostError, win_msg
from yunohost_service import (service_enable, service_disable,
service_start, service_stop, service_status)
glances_uri = 'http://127.0.0.1:61209'
stats_path = '/var/lib/yunohost/stats'
glances_uri = 'http://127.0.0.1:61209'
stats_path = '/var/lib/yunohost/stats'
crontab_path = '/etc/cron.d/yunohost-monitor'
def monitor_disk(units=None, mountpoint=None, human_readable=False):
"""
@ -336,6 +339,60 @@ def monitor_show_stats(period, date=None):
return result
def monitor_enable(no_stats=False):
"""
Enable server monitoring
Keyword argument:
no_stats -- Disable monitoring statistics
"""
glances = service_status('glances')
if glances['status'] != 'running':
service_start('glances')
if glances['loaded'] != 'enabled':
try:
service_enable('glances')
except:
# TODO: log error
pass
# Install crontab
if not no_stats:
cmd = 'yunohost monitor update-stats'
rules = ('*/5 * * * * root %(cmd)s day --no-ldap >> /dev/null\n' + \
'0 * * * * root %(cmd)s week --no-ldap >> /dev/null\n' + \
'* */4 * * * root %(cmd)s month --no-ldap >> /dev/null') % {'cmd': cmd}
os.system("touch %s" % crontab_path)
os.system("echo '%s' >%s" % (rules, crontab_path))
win_msg(_("Server monitoring enabled"))
def monitor_disable():
"""
Disable server monitoring
"""
glances = service_status('glances')
if glances['status'] != 'inactive':
service_stop('glances')
if glances['loaded'] != 'disabled':
try:
service_disable('glances')
except:
# TODO: log error
pass
# Remove crontab
try:
os.remove(crontab_path)
except:
pass
win_msg(_("Server monitoring disabled"))
def _get_glances_api():
"""
Retrieve Glances API running on the local server
@ -345,10 +402,13 @@ def _get_glances_api():
p = xmlrpclib.ServerProxy(glances_uri)
p.system.methodHelp('getAll')
except (xmlrpclib.ProtocolError, IOError):
# TODO: Try to start Glances service
raise YunoHostError(1, _("Connection to Glances server failed"))
pass
else:
return p
return p
if service_status('glances')['status'] != 'running':
raise YunoHostError(1, _("Monitoring is disabled"))
raise YunoHostError(1, _("Connection to Glances server failed"))
def _extract_inet(string, skip_netmask=False):
@ -563,8 +623,12 @@ def _calculate_stats_mean(stats):
if isinstance(v, dict):
s[k] = _mean(v, t, ts)
elif isinstance(v, list):
nums = [ float(x * t[i]) for i, x in enumerate(v) ]
s[k] = sum(nums) / float(ts)
try:
nums = [ float(x * t[i]) for i, x in enumerate(v) ]
except:
pass
else:
s[k] = sum(nums) / float(ts)
return s
stats = _mean(stats, timestamp, t_sum)

View file

@ -38,6 +38,8 @@ def service_start(names):
names -- Services name to start
"""
if isinstance(names, str):
names = [names]
for name in names:
if _run_service_command('start', name):
win_msg(_("'%s' service started") % name)
@ -53,6 +55,8 @@ def service_stop(names):
name -- Services name to stop
"""
if isinstance(names, str):
names = [names]
for name in names:
if _run_service_command('stop', name):
win_msg(_("'%s' service stopped") % name)
@ -68,6 +72,8 @@ def service_enable(names):
names -- Services name to enable
"""
if isinstance(names, str):
names = [names]
for name in names:
if _run_service_command('enable', name):
win_msg(_("'%s' service enabled") % name)
@ -83,6 +89,8 @@ def service_disable(names):
names -- Services name to disable
"""
if isinstance(names, str):
names = [names]
for name in names:
if _run_service_command('disable', name):
win_msg(_("'%s' service disabled") % name)
@ -90,7 +98,7 @@ def service_disable(names):
raise YunoHostError(1, _("Service disabling failed for '%s'") % name)
def service_status(names=None):
def service_status(names=[]):
"""
Show status information about one or more services (all by default)
@ -102,7 +110,9 @@ def service_status(names=None):
check_names = True
result = {}
if names is None or len(names) == 0:
if isinstance(names, str):
names = [names]
elif len(names) == 0:
names = services.keys()
check_names = False
@ -141,6 +151,8 @@ def service_status(names=None):
else:
result[name]['loaded'] = _("not-found")
if len(names) == 1:
return result[names[0]]
return result