Merge "Provide a way to disable some plugins"
This commit is contained in:
commit
39d854330e
@ -16,14 +16,21 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from stevedore import extension
|
|
||||||
|
|
||||||
from nova import manager
|
from nova import manager
|
||||||
|
|
||||||
|
from ceilometer import extension_manager
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
from ceilometer.openstack.common import log
|
from ceilometer.openstack.common import log
|
||||||
from ceilometer import publish
|
from ceilometer import publish
|
||||||
|
|
||||||
|
OPTS = [
|
||||||
|
cfg.ListOpt('disabled_central_pollsters',
|
||||||
|
default=[],
|
||||||
|
help='list of central pollsters to disable',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
cfg.CONF.register_opts(OPTS)
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -38,9 +45,9 @@ class AgentManager(manager.Manager):
|
|||||||
# importable. Need to add check against global
|
# importable. Need to add check against global
|
||||||
# configuration flag and check that asks the plugin if
|
# configuration flag and check that asks the plugin if
|
||||||
# it should be enabled.
|
# it should be enabled.
|
||||||
self.ext_manager = extension.ExtensionManager(
|
self.ext_manager = extension_manager.ActivatedExtensionManager(
|
||||||
namespace=PLUGIN_NAMESPACE,
|
namespace=PLUGIN_NAMESPACE,
|
||||||
invoke_on_load=True,
|
disabled_names=cfg.CONF.disabled_central_pollsters,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ from stevedore import extension
|
|||||||
|
|
||||||
from nova import manager
|
from nova import manager
|
||||||
|
|
||||||
|
from ceilometer import extension_manager
|
||||||
from ceilometer import meter
|
from ceilometer import meter
|
||||||
from ceilometer import publish
|
from ceilometer import publish
|
||||||
from ceilometer import storage
|
from ceilometer import storage
|
||||||
@ -36,6 +37,16 @@ except ImportError:
|
|||||||
import nova.rpc as rpc
|
import nova.rpc as rpc
|
||||||
|
|
||||||
|
|
||||||
|
OPTS = [
|
||||||
|
cfg.ListOpt('disabled_notification_listeners',
|
||||||
|
default=[],
|
||||||
|
help='list of listener plugins to disable',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
cfg.CONF.register_opts(OPTS)
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -52,9 +63,10 @@ class CollectorManager(manager.Manager):
|
|||||||
self.storage_engine = storage.get_engine(cfg.CONF)
|
self.storage_engine = storage.get_engine(cfg.CONF)
|
||||||
self.storage_conn = self.storage_engine.get_connection(cfg.CONF)
|
self.storage_conn = self.storage_engine.get_connection(cfg.CONF)
|
||||||
|
|
||||||
self.ext_manager = extension.ExtensionManager(self.COLLECTOR_NAMESPACE,
|
self.ext_manager = extension_manager.ActivatedExtensionManager(
|
||||||
invoke_on_load=True,
|
namespace=self.COLLECTOR_NAMESPACE,
|
||||||
)
|
disabled_names=cfg.CONF.disabled_notification_listeners,
|
||||||
|
)
|
||||||
|
|
||||||
if not list(self.ext_manager):
|
if not list(self.ext_manager):
|
||||||
LOG.warning('Failed to load any notification handlers for %s',
|
LOG.warning('Failed to load any notification handlers for %s',
|
||||||
@ -74,7 +86,8 @@ class CollectorManager(manager.Manager):
|
|||||||
|
|
||||||
def _setup_subscription(self, ext, *args, **kwds):
|
def _setup_subscription(self, ext, *args, **kwds):
|
||||||
handler = ext.obj
|
handler = ext.obj
|
||||||
LOG.debug('Event types: %r', handler.get_event_types())
|
LOG.debug('Event types from %s: %s',
|
||||||
|
ext.name, ', '.join(handler.get_event_types()))
|
||||||
for exchange_topic in handler.get_exchange_topics(cfg.CONF):
|
for exchange_topic in handler.get_exchange_topics(cfg.CONF):
|
||||||
for topic in exchange_topic.topics:
|
for topic in exchange_topic.topics:
|
||||||
# FIXME(dhellmann): Should be using create_worker(), except
|
# FIXME(dhellmann): Should be using create_worker(), except
|
||||||
|
@ -59,7 +59,14 @@ def make_counter_from_instance(instance, name, type, volume):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InstancePollster(plugin.ComputePollster):
|
class LibVirtPollster(plugin.ComputePollster):
|
||||||
|
|
||||||
|
def is_enabled(self):
|
||||||
|
# Use a fairly liberal substring check.
|
||||||
|
return 'libvirt' in FLAGS.compute_driver.lower()
|
||||||
|
|
||||||
|
|
||||||
|
class InstancePollster(LibVirtPollster):
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, instance):
|
||||||
yield make_counter_from_instance(instance,
|
yield make_counter_from_instance(instance,
|
||||||
@ -75,7 +82,7 @@ class InstancePollster(plugin.ComputePollster):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DiskIOPollster(plugin.ComputePollster):
|
class DiskIOPollster(LibVirtPollster):
|
||||||
|
|
||||||
LOG = log.getLogger(__name__ + '.diskio')
|
LOG = log.getLogger(__name__ + '.diskio')
|
||||||
|
|
||||||
@ -98,53 +105,52 @@ class DiskIOPollster(plugin.ComputePollster):
|
|||||||
])
|
])
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, instance):
|
||||||
if FLAGS.compute_driver == 'libvirt.LibvirtDriver':
|
conn = get_libvirt_connection()
|
||||||
conn = get_libvirt_connection()
|
# TODO(jd) This does not work see bug#998089
|
||||||
# TODO(jd) This does not work see bug#998089
|
# for disk in conn.get_disks(instance.name):
|
||||||
# for disk in conn.get_disks(instance.name):
|
try:
|
||||||
try:
|
disks = self._get_disks(conn, instance.name)
|
||||||
disks = self._get_disks(conn, instance.name)
|
except Exception as err:
|
||||||
except Exception as err:
|
self.LOG.warning('Ignoring instance %s: %s',
|
||||||
self.LOG.warning('Ignoring instance %s: %s',
|
instance.name, err)
|
||||||
instance.name, err)
|
self.LOG.exception(err)
|
||||||
self.LOG.exception(err)
|
else:
|
||||||
else:
|
r_bytes = 0
|
||||||
r_bytes = 0
|
r_requests = 0
|
||||||
r_requests = 0
|
w_bytes = 0
|
||||||
w_bytes = 0
|
w_requests = 0
|
||||||
w_requests = 0
|
for disk in disks:
|
||||||
for disk in disks:
|
stats = conn.block_stats(instance.name, disk)
|
||||||
stats = conn.block_stats(instance.name, disk)
|
self.LOG.info(self.DISKIO_USAGE_MESSAGE,
|
||||||
self.LOG.info(self.DISKIO_USAGE_MESSAGE,
|
instance, disk, stats[0], stats[1],
|
||||||
instance, disk, stats[0], stats[1],
|
stats[2], stats[3], stats[4])
|
||||||
stats[2], stats[3], stats[4])
|
r_bytes += stats[0]
|
||||||
r_bytes += stats[0]
|
r_requests += stats[1]
|
||||||
r_requests += stats[1]
|
w_bytes += stats[3]
|
||||||
w_bytes += stats[3]
|
w_requests += stats[2]
|
||||||
w_requests += stats[2]
|
yield make_counter_from_instance(instance,
|
||||||
yield make_counter_from_instance(instance,
|
name='disk.read.requests',
|
||||||
name='disk.read.requests',
|
type=counter.TYPE_CUMULATIVE,
|
||||||
type=counter.TYPE_CUMULATIVE,
|
volume=r_requests,
|
||||||
volume=r_requests,
|
)
|
||||||
)
|
yield make_counter_from_instance(instance,
|
||||||
yield make_counter_from_instance(instance,
|
name='disk.read.bytes',
|
||||||
name='disk.read.bytes',
|
type=counter.TYPE_CUMULATIVE,
|
||||||
type=counter.TYPE_CUMULATIVE,
|
volume=r_bytes,
|
||||||
volume=r_bytes,
|
)
|
||||||
)
|
yield make_counter_from_instance(instance,
|
||||||
yield make_counter_from_instance(instance,
|
name='disk.write.requests',
|
||||||
name='disk.write.requests',
|
type=counter.TYPE_CUMULATIVE,
|
||||||
type=counter.TYPE_CUMULATIVE,
|
volume=w_requests,
|
||||||
volume=w_requests,
|
)
|
||||||
)
|
yield make_counter_from_instance(instance,
|
||||||
yield make_counter_from_instance(instance,
|
name='disk.write.bytes',
|
||||||
name='disk.write.bytes',
|
type=counter.TYPE_CUMULATIVE,
|
||||||
type=counter.TYPE_CUMULATIVE,
|
volume=w_bytes,
|
||||||
volume=w_bytes,
|
)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CPUPollster(plugin.ComputePollster):
|
class CPUPollster(LibVirtPollster):
|
||||||
|
|
||||||
LOG = log.getLogger(__name__ + '.cpu')
|
LOG = log.getLogger(__name__ + '.cpu')
|
||||||
|
|
||||||
@ -166,7 +172,7 @@ class CPUPollster(plugin.ComputePollster):
|
|||||||
self.LOG.exception(err)
|
self.LOG.exception(err)
|
||||||
|
|
||||||
|
|
||||||
class NetPollster(plugin.ComputePollster):
|
class NetPollster(LibVirtPollster):
|
||||||
|
|
||||||
LOG = log.getLogger(__name__ + '.net')
|
LOG = log.getLogger(__name__ + '.net')
|
||||||
|
|
||||||
|
@ -16,14 +16,22 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from stevedore import extension
|
|
||||||
|
|
||||||
from nova import manager
|
from nova import manager
|
||||||
|
|
||||||
|
from ceilometer import extension_manager
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
from ceilometer.openstack.common import log
|
from ceilometer.openstack.common import log
|
||||||
from ceilometer import publish
|
from ceilometer import publish
|
||||||
|
|
||||||
|
OPTS = [
|
||||||
|
cfg.ListOpt('disabled_compute_pollsters',
|
||||||
|
default=[],
|
||||||
|
help='list of compute agent pollsters to disable',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
cfg.CONF.register_opts(OPTS)
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -38,9 +46,9 @@ class AgentManager(manager.Manager):
|
|||||||
# importable. Need to add check against global
|
# importable. Need to add check against global
|
||||||
# configuration flag and check that asks the plugin if
|
# configuration flag and check that asks the plugin if
|
||||||
# it should be enabled.
|
# it should be enabled.
|
||||||
self.ext_manager = extension.ExtensionManager(
|
self.ext_manager = extension_manager.ActivatedExtensionManager(
|
||||||
namespace=PLUGIN_NAMESPACE,
|
namespace=PLUGIN_NAMESPACE,
|
||||||
invoke_on_load=True,
|
disabled_names=cfg.CONF.disabled_compute_pollsters,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
71
ceilometer/extension_manager.py
Normal file
71
ceilometer/extension_manager.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright © 2012 New Dream Network, LLC (DreamHost)
|
||||||
|
#
|
||||||
|
# Author: Doug Hellmann <doug.hellmann@dreamhost.com>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
"""Base class for plugin loader.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from stevedore import enabled
|
||||||
|
|
||||||
|
from ceilometer.openstack.common import log
|
||||||
|
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def should_use_extension(namespace, ext, disabled_names):
|
||||||
|
"""Return boolean indicating whether the extension
|
||||||
|
should be used.
|
||||||
|
|
||||||
|
Tests the extension against a couple of criteria to see whether it
|
||||||
|
should be used, logs the reason it is not used if not, and then
|
||||||
|
returns the result.
|
||||||
|
"""
|
||||||
|
if ext.name in disabled_names:
|
||||||
|
LOG.debug(
|
||||||
|
'%s extension %r disabled through configuration setting',
|
||||||
|
namespace, ext.name,
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
if not ext.obj.is_enabled():
|
||||||
|
LOG.debug(
|
||||||
|
'%s extension %r reported that it is disabled',
|
||||||
|
namespace,
|
||||||
|
ext.name,
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
LOG.debug('using %s extension %r', namespace, ext.name)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ActivatedExtensionManager(enabled.EnabledExtensionManager):
|
||||||
|
"""Loads extensions based on a configurable set that should be
|
||||||
|
disabled and asking each one if it should be active or not.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, namespace, disabled_names, invoke_on_load=True,
|
||||||
|
invoke_args=(), invoke_kwds={}):
|
||||||
|
|
||||||
|
def local_check_func(ext):
|
||||||
|
return should_use_extension(namespace, ext, disabled_names)
|
||||||
|
|
||||||
|
super(ActivatedExtensionManager, self).__init__(
|
||||||
|
namespace=namespace,
|
||||||
|
check_func=local_check_func,
|
||||||
|
invoke_on_load=invoke_on_load,
|
||||||
|
invoke_args=invoke_args,
|
||||||
|
invoke_kwds=invoke_kwds,
|
||||||
|
)
|
@ -30,11 +30,25 @@ import ceilometer.openstack.common.notifier.rabbit_notifier
|
|||||||
ExchangeTopics = namedtuple('ExchangeTopics', ['exchange', 'topics'])
|
ExchangeTopics = namedtuple('ExchangeTopics', ['exchange', 'topics'])
|
||||||
|
|
||||||
|
|
||||||
class NotificationBase(object):
|
class PluginBase(object):
|
||||||
|
"""Base class for all plugins.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def is_enabled(self):
|
||||||
|
"""Return boolean indicating whether this plugin should
|
||||||
|
be enabled and used by the caller.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationBase(PluginBase):
|
||||||
"""Base class for plugins that support the notification API."""
|
"""Base class for plugins that support the notification API."""
|
||||||
|
|
||||||
__metaclass__ = abc.ABCMeta
|
__metaclass__ = abc.ABCMeta
|
||||||
|
|
||||||
|
def is_enabled(self):
|
||||||
|
return True
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_event_types(self):
|
def get_event_types(self):
|
||||||
"""Return a sequence of strings defining the event types to be
|
"""Return a sequence of strings defining the event types to be
|
||||||
@ -58,7 +72,7 @@ class NotificationBase(object):
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
class PollsterBase(object):
|
class PollsterBase(PluginBase):
|
||||||
"""Base class for plugins that support the polling API."""
|
"""Base class for plugins that support the polling API."""
|
||||||
|
|
||||||
__metaclass__ = abc.ABCMeta
|
__metaclass__ = abc.ABCMeta
|
||||||
|
@ -24,29 +24,33 @@ The following table lists the ceilometer specific options in the global configur
|
|||||||
Please note that ceilometer uses openstack-common extensively, which requires that
|
Please note that ceilometer uses openstack-common extensively, which requires that
|
||||||
the other parameters are set appropriately. For information we are listing the configuration
|
the other parameters are set appropriately. For information we are listing the configuration
|
||||||
elements that we use after the ceilometer specific elements.
|
elements that we use after the ceilometer specific elements.
|
||||||
|
|
||||||
If you use sql alchemy, its specific paramaters will need to be set.
|
If you use sql alchemy, its specific paramaters will need to be set.
|
||||||
|
|
||||||
|
|
||||||
========================== ==================================== ==============================================================
|
=============================== ==================================== ==============================================================
|
||||||
Parameter Default Note
|
Parameter Default Note
|
||||||
========================== ==================================== ==============================================================
|
=============================== ==================================== ==============================================================
|
||||||
nova_control_exchange nova Exchange name for Nova notifications
|
nova_control_exchange nova Exchange name for Nova notifications
|
||||||
glance_control_exchange glance_notifications Exchange name for Glance notifications
|
glance_control_exchange glance_notifications Exchange name for Glance notifications
|
||||||
cinder_control_exchange cinder Exchange name for Cinder notifications
|
cinder_control_exchange cinder Exchange name for Cinder notifications
|
||||||
quantum_control_exchange quantum Exchange name for Quantum notifications
|
quantum_control_exchange quantum Exchange name for Quantum notifications
|
||||||
metering_secret change this or be hacked Secret value for signing metering messages
|
metering_secret change this or be hacked Secret value for signing metering messages
|
||||||
metering_topic metering the topic ceilometer uses for metering messages
|
metering_topic metering the topic ceilometer uses for metering messages
|
||||||
counter_source openstack The source name of emited counters
|
counter_source openstack The source name of emited counters
|
||||||
control_exchange ceilometer AMQP exchange to connect to if using RabbitMQ or Qpid
|
control_exchange ceilometer AMQP exchange to connect to if using RabbitMQ or Qpid
|
||||||
periodic_interval 600 seconds between running periodic tasks
|
periodic_interval 600 seconds between running periodic tasks
|
||||||
os-username glance Username to use for openstack service access
|
os-username glance Username to use for openstack service access
|
||||||
os-password admin Password to use for openstack service access
|
os-password admin Password to use for openstack service access
|
||||||
os-tenant-id Tenant ID to use for openstack service access
|
os-tenant-id Tenant ID to use for openstack service access
|
||||||
os-tenant-name admin Tenant name to use for openstack service access
|
os-tenant-name admin Tenant name to use for openstack service access
|
||||||
os-auth-url http://localhost:5000/v2.0 Auth URL to use for openstack service access
|
os-auth-url http://localhost:5000/v2.0 Auth URL to use for openstack service access
|
||||||
database_connection mongodb://localhost:27017/ceilometer Database connection string
|
database_connection mongodb://localhost:27017/ceilometer Database connection string
|
||||||
metering_api_port 8777 The port for the ceilometer API server
|
metering_api_port 8777 The port for the ceilometer API server
|
||||||
========================== ==================================== ==============================================================
|
disabled_central_pollsters List of central pollsters to skip loading
|
||||||
|
disabled_compute_pollsters List of compute pollsters to skip loading
|
||||||
|
disabled_notification_listeners List of notification listeners to skip loading
|
||||||
|
=============================== ==================================== ==============================================================
|
||||||
|
|
||||||
SQL Alchemy
|
SQL Alchemy
|
||||||
===========
|
===========
|
||||||
|
@ -9,6 +9,6 @@ sqlalchemy-migrate>=0.7.2
|
|||||||
eventlet
|
eventlet
|
||||||
anyjson>=0.3.1
|
anyjson>=0.3.1
|
||||||
Flask==0.9
|
Flask==0.9
|
||||||
stevedore>=0.5
|
stevedore>=0.6
|
||||||
python-glanceclient
|
python-glanceclient
|
||||||
python-cinderclient
|
python-cinderclient
|
||||||
|
Loading…
Reference in New Issue
Block a user