Source code for aodh.api.controllers.v2.alarm_rules.threshold

#
# 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.

from ceilometerclient import client as ceiloclient
from ceilometerclient import exc as ceiloexc
from oslo_log import log
import pecan
import wsme
from wsme import types as wtypes

from aodh.api.controllers.v2 import base
from aodh.api.controllers.v2 import utils as v2_utils
from aodh.i18n import _
from aodh import keystone_client
from aodh import storage

LOG = log.getLogger(__name__)


[docs]class AlarmThresholdRule(base.AlarmRule): """Alarm Threshold Rule Describe when to trigger the alarm based on computed statistics """ meter_name = wsme.wsattr(wtypes.text, mandatory=True) "The name of the meter" # FIXME(sileht): default doesn't work # workaround: default is set in validate method query = wsme.wsattr([base.Query], default=[]) """The query to find the data for computing statistics. Ownership settings are automatically included based on the Alarm owner. """ period = wsme.wsattr(wtypes.IntegerType(minimum=1), default=60) "The time range in seconds over which query" comparison_operator = base.AdvEnum('comparison_operator', str, 'lt', 'le', 'eq', 'ne', 'ge', 'gt', default='eq') "The comparison against the alarm threshold" threshold = wsme.wsattr(float, mandatory=True) "The threshold of the alarm" statistic = base.AdvEnum('statistic', str, 'max', 'min', 'avg', 'sum', 'count', default='avg') "The statistic to compare to the threshold" evaluation_periods = wsme.wsattr(wtypes.IntegerType(minimum=1), default=1) "The number of historical periods to evaluate the threshold" exclude_outliers = wsme.wsattr(bool, default=False) "Whether datapoints with anomalously low sample counts are excluded" ceilometer_sample_api_is_supported = None def __init__(self, query=None, **kwargs): query = [base.Query(**q) for q in query] if query else [] super(AlarmThresholdRule, self).__init__(query=query, **kwargs) @classmethod def _check_ceilometer_sample_api(cls): # Check it only once if cls.ceilometer_sample_api_is_supported is None: auth_config = pecan.request.cfg.service_credentials client = ceiloclient.get_client( version=2, session=keystone_client.get_session(pecan.request.cfg), # ceiloclient adapter options region_name=auth_config.region_name, interface=auth_config.interface, ) try: client.statistics.list( meter_name="idontthinkthatexistsbutwhatever") except Exception as e: if isinstance(e, ceiloexc.HTTPException): if e.code == 410: cls.ceilometer_sample_api_is_supported = False elif e.code < 500: cls.ceilometer_sample_api_is_supported = True else: raise else: raise else: # I don't think this meter can exist but how known cls.ceilometer_sample_api_is_supported = True if cls.ceilometer_sample_api_is_supported is False: raise base.ClientSideError( "This telemetry installation is not configured to support" "alarm of type 'threshold") @staticmethod
[docs] def validate(threshold_rule): # note(sileht): wsme default doesn't work in some case # workaround for https://bugs.launchpad.net/wsme/+bug/1227039 if not threshold_rule.query: threshold_rule.query = [] # Timestamp is not allowed for AlarmThresholdRule query, as the alarm # evaluator will construct timestamp bounds for the sequence of # statistics queries as the sliding evaluation window advances # over time. v2_utils.validate_query(threshold_rule.query, storage.SampleFilter.__init__, allow_timestamps=False) return threshold_rule
@classmethod
[docs] def validate_alarm(cls, alarm): cls._check_ceilometer_sample_api() # ensure an implicit constraint on project_id is added to # the query if not already present alarm.threshold_rule.query = v2_utils.sanitize_query( alarm.threshold_rule.query, storage.SampleFilter.__init__, on_behalf_of=alarm.project_id )
@property def default_description(self): return (_('Alarm when %(meter_name)s is %(comparison_operator)s a ' '%(statistic)s of %(threshold)s over %(period)s seconds') % dict(comparison_operator=self.comparison_operator, statistic=self.statistic, threshold=self.threshold, meter_name=self.meter_name, period=self.period))
[docs] def as_dict(self): rule = self.as_dict_from_keys(['period', 'comparison_operator', 'threshold', 'statistic', 'evaluation_periods', 'meter_name', 'exclude_outliers']) rule['query'] = [q.as_dict() for q in self.query] return rule
@classmethod
[docs] def sample(cls): return cls(meter_name='cpu_util', period=60, evaluation_periods=1, threshold=300.0, statistic='avg', comparison_operator='gt', query=[{'field': 'resource_id', 'value': '2a4d689b-f0b8-49c1-9eef-87cae58d80db', 'op': 'eq', 'type': 'string'}])

Project Source