833385f846
When raising the PollsterPermanentError, the list of resources(tenants) are passed, which enables the Agent Manager to blacklist those resources. This stops those resources from being polled again and avoids any unwanted error messages from being logged. Change-Id: I4f7bf23d5d7f3c182e4089d80b03a1587fa31222 Closes-Bug: #1475441
184 lines
5.2 KiB
Python
184 lines
5.2 KiB
Python
# Copyright 2014 Intel
|
|
#
|
|
# 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.
|
|
|
|
import abc
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log
|
|
from oslo_utils import timeutils
|
|
import six
|
|
|
|
from ceilometer.agent import plugin_base
|
|
from ceilometer.i18n import _
|
|
from ceilometer.ipmi.platform import exception as nmexcept
|
|
from ceilometer.ipmi.platform import intel_node_manager as node_manager
|
|
from ceilometer import sample
|
|
|
|
CONF = cfg.CONF
|
|
CONF.import_opt('host', 'ceilometer.service')
|
|
CONF.import_opt('polling_retry', 'ceilometer.ipmi.pollsters',
|
|
group='ipmi')
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class _Base(plugin_base.PollsterBase):
|
|
|
|
def setup_environment(self):
|
|
super(_Base, self).setup_environment()
|
|
self.nodemanager = node_manager.NodeManager()
|
|
self.polling_failures = 0
|
|
|
|
# Do not load this extension if no NM support
|
|
if self.nodemanager.nm_version == 0:
|
|
raise plugin_base.ExtensionLoadError()
|
|
|
|
@property
|
|
def default_discovery(self):
|
|
return 'local_node'
|
|
|
|
def get_value(self, stats):
|
|
"""Get value from statistics."""
|
|
return node_manager._hex(stats["Current_value"])
|
|
|
|
@abc.abstractmethod
|
|
def read_data(self, cache):
|
|
"""Return data sample for IPMI."""
|
|
|
|
def get_samples(self, manager, cache, resources):
|
|
# Only one resource for Node Manager pollster
|
|
try:
|
|
stats = self.read_data(cache)
|
|
except nmexcept.IPMIException:
|
|
self.polling_failures += 1
|
|
LOG.warning(_('Polling %(name)s faild for %(cnt)s times!')
|
|
% ({'name': self.NAME,
|
|
'cnt': self.polling_failures}))
|
|
if (CONF.ipmi.polling_retry >= 0 and
|
|
self.polling_failures > CONF.ipmi.polling_retry):
|
|
LOG.warning(_('Pollster for %s is disabled!') % self.NAME)
|
|
raise plugin_base.PollsterPermanentError(resources)
|
|
else:
|
|
return
|
|
|
|
self.polling_failures = 0
|
|
|
|
metadata = {
|
|
'node': CONF.host
|
|
}
|
|
|
|
if stats:
|
|
data = self.get_value(stats)
|
|
|
|
yield sample.Sample(
|
|
name=self.NAME,
|
|
type=self.TYPE,
|
|
unit=self.UNIT,
|
|
volume=data,
|
|
user_id=None,
|
|
project_id=None,
|
|
resource_id=CONF.host,
|
|
timestamp=timeutils.utcnow().isoformat(),
|
|
resource_metadata=metadata)
|
|
|
|
|
|
class InletTemperaturePollster(_Base):
|
|
# Note(ildikov): The new meter name should be
|
|
# "hardware.ipmi.node.inlet_temperature". As currently there
|
|
# is no meter deprecation support in the code, we should use the
|
|
# old name in order to avoid confusion.
|
|
NAME = "hardware.ipmi.node.temperature"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "C"
|
|
|
|
def read_data(self, cache):
|
|
return self.nodemanager.read_inlet_temperature()
|
|
|
|
|
|
class OutletTemperaturePollster(_Base):
|
|
NAME = "hardware.ipmi.node.outlet_temperature"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "C"
|
|
|
|
def read_data(self, cache):
|
|
return self.nodemanager.read_outlet_temperature()
|
|
|
|
|
|
class PowerPollster(_Base):
|
|
NAME = "hardware.ipmi.node.power"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "W"
|
|
|
|
def read_data(self, cache):
|
|
return self.nodemanager.read_power_all()
|
|
|
|
|
|
class AirflowPollster(_Base):
|
|
NAME = "hardware.ipmi.node.airflow"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "CFM"
|
|
|
|
def read_data(self, cache):
|
|
return self.nodemanager.read_airflow()
|
|
|
|
|
|
class CUPSIndexPollster(_Base):
|
|
NAME = "hardware.ipmi.node.cups"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "CUPS"
|
|
|
|
def read_data(self, cache):
|
|
return self.nodemanager.read_cups_index()
|
|
|
|
def get_value(self, stats):
|
|
return node_manager._hex(stats["CUPS_Index"])
|
|
|
|
|
|
class _CUPSUtilPollsterBase(_Base):
|
|
CACHE_KEY_CUPS = 'CUPS'
|
|
|
|
def read_data(self, cache):
|
|
i_cache = cache.setdefault(self.CACHE_KEY_CUPS, {})
|
|
if not i_cache:
|
|
i_cache.update(self.nodemanager.read_cups_utilization())
|
|
return i_cache
|
|
|
|
|
|
class CPUUtilPollster(_CUPSUtilPollsterBase):
|
|
NAME = "hardware.ipmi.node.cpu_util"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "%"
|
|
|
|
def get_value(self, stats):
|
|
return node_manager._hex(stats["CPU_Utilization"])
|
|
|
|
|
|
class MemUtilPollster(_CUPSUtilPollsterBase):
|
|
NAME = "hardware.ipmi.node.mem_util"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "%"
|
|
|
|
def get_value(self, stats):
|
|
return node_manager._hex(stats["Mem_Utilization"])
|
|
|
|
|
|
class IOUtilPollster(_CUPSUtilPollsterBase):
|
|
NAME = "hardware.ipmi.node.io_util"
|
|
TYPE = sample.TYPE_GAUGE
|
|
UNIT = "%"
|
|
|
|
def get_value(self, stats):
|
|
return node_manager._hex(stats["IO_Utilization"])
|