Don't create events when signals don't perform an action
If we get repeat signals that cause no concrete actions this can cause large quantities of senseless events that suppress useful events. Change-Id: I79374d27648319f241f36ab041784fab37823ddb Closes-bug: #1445361
This commit is contained in:
parent
e294154f17
commit
6a48c45bfd
|
@ -63,6 +63,10 @@ class UpdateReplace(Exception):
|
||||||
super(Exception, self).__init__(six.text_type(msg))
|
super(Exception, self).__init__(six.text_type(msg))
|
||||||
|
|
||||||
|
|
||||||
|
class NoActionRequired(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ResourceInError(exception.HeatException):
|
class ResourceInError(exception.HeatException):
|
||||||
msg_fmt = _('Went to status %(resource_status)s '
|
msg_fmt = _('Went to status %(resource_status)s '
|
||||||
'due to "%(status_reason)s"')
|
'due to "%(status_reason)s"')
|
||||||
|
@ -1180,6 +1184,9 @@ class Resource(object):
|
||||||
else:
|
else:
|
||||||
reason_string = get_string_details()
|
reason_string = get_string_details()
|
||||||
self._add_event('SIGNAL', self.status, reason_string)
|
self._add_event('SIGNAL', self.status, reason_string)
|
||||||
|
except NoActionRequired:
|
||||||
|
# Don't log an event as it just spams the user.
|
||||||
|
pass
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(_LE('signal %(name)s : %(msg)s')
|
LOG.exception(_LE('signal %(name)s : %(msg)s')
|
||||||
% {'name': six.text_type(self), 'msg': ex})
|
% {'name': six.text_type(self), 'msg': ex})
|
||||||
|
|
|
@ -153,13 +153,13 @@ class AutoScalingPolicy(signal_responder.SignalResponder,
|
||||||
{'name': self.name, 'state': alarm_state})
|
{'name': self.name, 'state': alarm_state})
|
||||||
|
|
||||||
if alarm_state != 'alarm':
|
if alarm_state != 'alarm':
|
||||||
return
|
raise resource.NoActionRequired()
|
||||||
if self._cooldown_inprogress():
|
if self._cooldown_inprogress():
|
||||||
LOG.info(_LI("%(name)s NOT performing scaling action, "
|
LOG.info(_LI("%(name)s NOT performing scaling action, "
|
||||||
"cooldown %(cooldown)s"),
|
"cooldown %(cooldown)s"),
|
||||||
{'name': self.name,
|
{'name': self.name,
|
||||||
'cooldown': self.properties[self.COOLDOWN]})
|
'cooldown': self.properties[self.COOLDOWN]})
|
||||||
return
|
raise resource.NoActionRequired()
|
||||||
|
|
||||||
asgn_id = self.properties[self.AUTO_SCALING_GROUP_NAME]
|
asgn_id = self.properties[self.AUTO_SCALING_GROUP_NAME]
|
||||||
group = self.stack.resource_by_refid(asgn_id)
|
group = self.stack.resource_by_refid(asgn_id)
|
||||||
|
|
|
@ -92,7 +92,8 @@ class TestAutoScalingPolicy(common.HeatTestCase):
|
||||||
test = {'current': 'not_an_alarm'}
|
test = {'current': 'not_an_alarm'}
|
||||||
with mock.patch.object(pol, '_cooldown_inprogress',
|
with mock.patch.object(pol, '_cooldown_inprogress',
|
||||||
side_effect=AssertionError()) as dont_call:
|
side_effect=AssertionError()) as dont_call:
|
||||||
pol.handle_signal(details=test)
|
self.assertRaises(resource.NoActionRequired,
|
||||||
|
pol.handle_signal, details=test)
|
||||||
self.assertEqual([], dont_call.call_args_list)
|
self.assertEqual([], dont_call.call_args_list)
|
||||||
|
|
||||||
def test_scaling_policy_cooldown_toosoon(self):
|
def test_scaling_policy_cooldown_toosoon(self):
|
||||||
|
@ -106,7 +107,8 @@ class TestAutoScalingPolicy(common.HeatTestCase):
|
||||||
side_effect=AssertionError) as dont_call:
|
side_effect=AssertionError) as dont_call:
|
||||||
with mock.patch.object(pol, '_cooldown_inprogress',
|
with mock.patch.object(pol, '_cooldown_inprogress',
|
||||||
return_value=True) as mock_cip:
|
return_value=True) as mock_cip:
|
||||||
pol.handle_signal(details=test)
|
self.assertRaises(resource.NoActionRequired,
|
||||||
|
pol.handle_signal, details=test)
|
||||||
mock_cip.assert_called_once_with()
|
mock_cip.assert_called_once_with()
|
||||||
self.assertEqual([], dont_call.call_args_list)
|
self.assertEqual([], dont_call.call_args_list)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import six
|
||||||
|
|
||||||
from heat.common import exception
|
from heat.common import exception
|
||||||
from heat.common import template_format
|
from heat.common import template_format
|
||||||
|
from heat.engine import resource
|
||||||
from heat.engine import scheduler
|
from heat.engine import scheduler
|
||||||
from heat.tests.autoscaling import inline_templates
|
from heat.tests.autoscaling import inline_templates
|
||||||
from heat.tests import common
|
from heat.tests import common
|
||||||
|
@ -91,7 +92,8 @@ class TestAutoScalingPolicy(common.HeatTestCase):
|
||||||
test = {'current': 'not_an_alarm'}
|
test = {'current': 'not_an_alarm'}
|
||||||
with mock.patch.object(pol, '_cooldown_inprogress',
|
with mock.patch.object(pol, '_cooldown_inprogress',
|
||||||
side_effect=AssertionError()) as dont_call:
|
side_effect=AssertionError()) as dont_call:
|
||||||
pol.handle_signal(details=test)
|
self.assertRaises(resource.NoActionRequired,
|
||||||
|
pol.handle_signal, details=test)
|
||||||
self.assertEqual([], dont_call.call_args_list)
|
self.assertEqual([], dont_call.call_args_list)
|
||||||
|
|
||||||
def test_scaling_policy_cooldown_toosoon(self):
|
def test_scaling_policy_cooldown_toosoon(self):
|
||||||
|
@ -105,7 +107,8 @@ class TestAutoScalingPolicy(common.HeatTestCase):
|
||||||
side_effect=AssertionError) as dont_call:
|
side_effect=AssertionError) as dont_call:
|
||||||
with mock.patch.object(pol, '_cooldown_inprogress',
|
with mock.patch.object(pol, '_cooldown_inprogress',
|
||||||
return_value=True) as mock_cip:
|
return_value=True) as mock_cip:
|
||||||
pol.handle_signal(details=test)
|
self.assertRaises(resource.NoActionRequired,
|
||||||
|
pol.handle_signal, details=test)
|
||||||
mock_cip.assert_called_once_with()
|
mock_cip.assert_called_once_with()
|
||||||
self.assertEqual([], dont_call.call_args_list)
|
self.assertEqual([], dont_call.call_args_list)
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,33 @@ class SignalTest(common.HeatTestCase):
|
||||||
|
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def test_signal_no_action(self):
|
||||||
|
test_d = {'Data': 'foo', 'Reason': 'bar',
|
||||||
|
'Status': 'SUCCESS', 'UniqueId': '123'}
|
||||||
|
|
||||||
|
self.stack = self.create_stack()
|
||||||
|
self.stack.create()
|
||||||
|
|
||||||
|
# mock a NoActionRequired from handle_signal()
|
||||||
|
self.m.StubOutWithMock(generic_resource.SignalResource,
|
||||||
|
'handle_signal')
|
||||||
|
generic_resource.SignalResource.handle_signal(test_d).AndRaise(
|
||||||
|
resource.NoActionRequired())
|
||||||
|
|
||||||
|
# _add_event should not be called.
|
||||||
|
self.m.StubOutWithMock(generic_resource.SignalResource,
|
||||||
|
'_add_event')
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
rsrc = self.stack['signal_handler']
|
||||||
|
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
|
||||||
|
self.assertTrue(rsrc.requires_deferred_auth)
|
||||||
|
|
||||||
|
rsrc.signal(details=test_d)
|
||||||
|
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
def test_signal_different_reason_types(self):
|
def test_signal_different_reason_types(self):
|
||||||
self.stack = self.create_stack()
|
self.stack = self.create_stack()
|
||||||
self.stack.create()
|
self.stack.create()
|
||||||
|
|
Loading…
Reference in New Issue