08ac1308b8
To allow monasca detecting network congestion, we add a new agent plugin for monasca-agent module based on Explicit Congestion Notification (ECN) tos bits. The agent will create a map between the number of Congestion Encountered(CE) packets/bytes and the source ip address responsible of the congestion. The source could be a compute or (if activated) a set of VMs deployed in a compute. First, we ensure that ECN marking is enabled for both edges. Second, we check ecn.packets and ecn.bytes and calculate ecn.cong.rate associated to each source of congestion. Last, the agent sends the three metrics and their timestamp to monasca API for any further processing and keeps the metric counters into a cache file. This piece of information could be used to trigger a new kind of performance alarm in monasca threshold. Change-Id: I98405524588582065c7825ca511c489d59826cda Task: 5750 Story: 2001234
101 lines
3.8 KiB
Python
101 lines
3.8 KiB
Python
# Copyright 2017 OrangeLabs
|
|
|
|
import ConfigParser
|
|
import logging
|
|
from monasca_agent.common.psutil_wrapper import psutil
|
|
import monasca_setup.agent_config
|
|
import monasca_setup.detection
|
|
import os
|
|
log = logging.getLogger(__name__)
|
|
|
|
# Directory to use for metric caches
|
|
cache_dir = "/dev/shm"
|
|
# Enable vm congestion check
|
|
enable_vm = True
|
|
# Ensure that ECN marking is enabled
|
|
enable_ecn = True
|
|
# Smoothing factor used to compute ecn congestion rate
|
|
s_factor = 0.1
|
|
# Period of time in second to collect metrics
|
|
collect_period = 30
|
|
# Acceptable arguments
|
|
acceptable_args = ['username', 'password', 'project_name',
|
|
'auth_url', 'cache_dir', 'enable_vm', 'enable_ecn',
|
|
'region_name', 's_factor', 'collect_period']
|
|
|
|
|
|
class Congestion(monasca_setup.detection.Plugin):
|
|
|
|
"""Configures congestion detection plugin."""
|
|
|
|
def _detect(self):
|
|
"""Run detection, set self.available True if the service is
|
|
detected.
|
|
"""
|
|
self.available = True
|
|
# Start with plugin-specific configuration parameters
|
|
# Try to detect the location of the Nova configuration file.
|
|
# Walk through the list of processes, searching for 'nova-compute'
|
|
# process with 'nova.conf' inside one of the parameters
|
|
nova_conf = None
|
|
for proc in psutil.process_iter():
|
|
try:
|
|
cmd = proc.as_dict(['cmdline'])['cmdline']
|
|
if (len(cmd) > 2 and 'python' in cmd[0] and
|
|
'nova-compute' in cmd[1]):
|
|
conf_indexes = [cmd.index(y)
|
|
for y in cmd if 'nova.conf' in y]
|
|
if not conf_indexes:
|
|
continue
|
|
param = conf_indexes[0]
|
|
if '=' in cmd[param]:
|
|
nova_conf = cmd[param].split('=')[1]
|
|
else:
|
|
nova_conf = cmd[param]
|
|
except (IOError, psutil.NoSuchProcess):
|
|
# Process has already terminated, ignore
|
|
continue
|
|
if (nova_conf is not None and os.path.isfile(nova_conf)):
|
|
self.available = True
|
|
self.nova_conf = nova_conf
|
|
|
|
def build_config(self):
|
|
"""Build the config as a Plugins object and return. """
|
|
config = monasca_setup.agent_config.Plugins()
|
|
log.info("Configuring congestion plugin")
|
|
nova_cfg = ConfigParser.SafeConfigParser()
|
|
log.info("\tUsing nova configuration file {0}".format(self.nova_conf))
|
|
nova_cfg.read(self.nova_conf)
|
|
# Which configuration options are needed for the plugin YAML?
|
|
# Use a dict so that they can be renamed later if necessary
|
|
cfg_needed = {
|
|
'username': 'username', 'password': 'password',
|
|
'project_name': 'project_name'}
|
|
cfg_section = 'keystone_authtoken'
|
|
region_name_sec = 'neutron'
|
|
init_config = {
|
|
'cache_dir': cache_dir,
|
|
'enable_vm': enable_vm,
|
|
'enable_ecn': enable_ecn,
|
|
's_factor': s_factor,
|
|
'collect_period': collect_period}
|
|
for option in cfg_needed:
|
|
init_config[option] = nova_cfg.get(
|
|
cfg_section, cfg_needed[option])
|
|
init_config['region_name'] = nova_cfg.get(
|
|
region_name_sec, 'region_name')
|
|
# Create an identity URI (again, slightly different for Devstack)
|
|
if nova_cfg.has_option(cfg_section, 'auth_url'):
|
|
init_config['auth_url'] = nova_cfg.get(cfg_section, 'auth_url')
|
|
else:
|
|
init_config['auth_url'] = nova_cfg.get(
|
|
cfg_section, 'identity_uri')
|
|
|
|
config = monasca_setup.agent_config.Plugins()
|
|
config['congestion'] = {
|
|
'init_config': init_config, 'instances': []}
|
|
return config
|
|
|
|
def dependencies_installed(self):
|
|
return True
|