Allow simpler scale exprs in transformer.conversions
For convenience of deployers, allow scale expression to be expressed as for example: 100.0 / (10**9 * (resource_metadata.cpu_number or 1)) instead of requiring that the full dict lookup syntax with default value is used: 100.0 / (10**9 * (resource_metadata.get('cpu_number', 1)) Unknown items evaluate to false in boolean expressions such as: resource_metadata.non.existent or 1.0 Change-Id: I2f1f84641222057b4d6213dcfd1c16f23ae9f273
This commit is contained in:
parent
65c4790303
commit
ac2b21b722
@ -16,7 +16,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import copy
|
from collections import defaultdict
|
||||||
|
|
||||||
from ceilometer import counter as ceilocounter
|
from ceilometer import counter as ceilocounter
|
||||||
from ceilometer.openstack.common import log
|
from ceilometer.openstack.common import log
|
||||||
@ -26,6 +26,29 @@ from ceilometer import transformer
|
|||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Namespace(object):
|
||||||
|
"""Encapsulates the namespace wrapping the evaluation of the
|
||||||
|
configured scale factor. This allows nested dicts to be
|
||||||
|
accessed in the attribute style, and missing attributes
|
||||||
|
to yield false when used in a boolean expression.
|
||||||
|
"""
|
||||||
|
def __init__(self, seed):
|
||||||
|
self.__dict__ = defaultdict(lambda: Namespace({}))
|
||||||
|
self.__dict__.update(seed)
|
||||||
|
for k, v in self.__dict__.iteritems():
|
||||||
|
if isinstance(v, dict):
|
||||||
|
self.__dict__[k] = Namespace(v)
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return self.__dict__[attr]
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.__dict__[key]
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
return len(self.__dict__) > 0
|
||||||
|
|
||||||
|
|
||||||
class ScalingTransformer(transformer.TransformerBase):
|
class ScalingTransformer(transformer.TransformerBase):
|
||||||
"""Transformer to apply a scaling conversion.
|
"""Transformer to apply a scaling conversion.
|
||||||
"""
|
"""
|
||||||
@ -54,7 +77,8 @@ class ScalingTransformer(transformer.TransformerBase):
|
|||||||
"""Apply the scaling factor (either a straight multiplicative
|
"""Apply the scaling factor (either a straight multiplicative
|
||||||
factor or else a string to be eval'd).
|
factor or else a string to be eval'd).
|
||||||
"""
|
"""
|
||||||
ns = copy.deepcopy(counter._asdict())
|
ns = Namespace(counter._asdict())
|
||||||
|
|
||||||
return ((eval(scale, {}, ns) if isinstance(scale, basestring)
|
return ((eval(scale, {}, ns) if isinstance(scale, basestring)
|
||||||
else counter.volume * scale) if scale else counter.volume)
|
else counter.volume * scale) if scale else counter.volume)
|
||||||
|
|
||||||
|
@ -747,9 +747,11 @@ class TestPipeline(base.TestCase):
|
|||||||
self.assertEquals(getattr(amb_temp, 'volume'), 88.8)
|
self.assertEquals(getattr(amb_temp, 'volume'), 88.8)
|
||||||
self.assertEquals(getattr(core_temp, 'volume'), 96.8)
|
self.assertEquals(getattr(core_temp, 'volume'), 96.8)
|
||||||
|
|
||||||
def _do_test_rate_of_change_conversion(self, prev, curr, offset,
|
def _do_test_rate_of_change_conversion(self, prev, curr, type, expected,
|
||||||
type, expected):
|
offset=1, weight=None):
|
||||||
s = "100.0 / (10**9 * resource_metadata.get('cpu_number', 1))"
|
s = "(resource_metadata.user_metadata.autoscaling_weight or 1.0)" \
|
||||||
|
"* (resource_metadata.non.existent or 1.0)" \
|
||||||
|
"* (100.0 / (10**9 * (resource_metadata.cpu_number or 1)))"
|
||||||
self.pipeline_cfg[0]['transformers'] = [
|
self.pipeline_cfg[0]['transformers'] = [
|
||||||
{
|
{
|
||||||
'name': 'rate_of_change',
|
'name': 'rate_of_change',
|
||||||
@ -766,6 +768,7 @@ class TestPipeline(base.TestCase):
|
|||||||
self.pipeline_cfg[0]['counters'] = ['cpu']
|
self.pipeline_cfg[0]['counters'] = ['cpu']
|
||||||
now = timeutils.utcnow()
|
now = timeutils.utcnow()
|
||||||
later = now + datetime.timedelta(minutes=offset)
|
later = now + datetime.timedelta(minutes=offset)
|
||||||
|
um = {'autoscaling_weight': weight} if weight else {}
|
||||||
counters = [
|
counters = [
|
||||||
counter.Counter(
|
counter.Counter(
|
||||||
name='cpu',
|
name='cpu',
|
||||||
@ -776,7 +779,8 @@ class TestPipeline(base.TestCase):
|
|||||||
project_id='test_proj',
|
project_id='test_proj',
|
||||||
resource_id='test_resource',
|
resource_id='test_resource',
|
||||||
timestamp=now.isoformat(),
|
timestamp=now.isoformat(),
|
||||||
resource_metadata={'cpu_number': 4}
|
resource_metadata={'cpu_number': 4,
|
||||||
|
'user_metadata': um},
|
||||||
),
|
),
|
||||||
counter.Counter(
|
counter.Counter(
|
||||||
name='cpu',
|
name='cpu',
|
||||||
@ -787,7 +791,8 @@ class TestPipeline(base.TestCase):
|
|||||||
project_id='test_proj',
|
project_id='test_proj',
|
||||||
resource_id='test_resource',
|
resource_id='test_resource',
|
||||||
timestamp=later.isoformat(),
|
timestamp=later.isoformat(),
|
||||||
resource_metadata={'cpu_number': 4}
|
resource_metadata={'cpu_number': 4,
|
||||||
|
'user_metadata': um},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -812,30 +817,34 @@ class TestPipeline(base.TestCase):
|
|||||||
def test_rate_of_change_conversion(self):
|
def test_rate_of_change_conversion(self):
|
||||||
self._do_test_rate_of_change_conversion(120000000000,
|
self._do_test_rate_of_change_conversion(120000000000,
|
||||||
180000000000,
|
180000000000,
|
||||||
1,
|
|
||||||
counter.TYPE_CUMULATIVE,
|
counter.TYPE_CUMULATIVE,
|
||||||
25.0)
|
25.0)
|
||||||
|
|
||||||
|
def test_rate_of_change_conversion_weight(self):
|
||||||
|
self._do_test_rate_of_change_conversion(120000000000,
|
||||||
|
180000000000,
|
||||||
|
counter.TYPE_CUMULATIVE,
|
||||||
|
27.5,
|
||||||
|
weight=1.1)
|
||||||
|
|
||||||
def test_rate_of_change_conversion_negative_cumulative_delta(self):
|
def test_rate_of_change_conversion_negative_cumulative_delta(self):
|
||||||
self._do_test_rate_of_change_conversion(180000000000,
|
self._do_test_rate_of_change_conversion(180000000000,
|
||||||
120000000000,
|
120000000000,
|
||||||
1,
|
|
||||||
counter.TYPE_CUMULATIVE,
|
counter.TYPE_CUMULATIVE,
|
||||||
50.0)
|
50.0)
|
||||||
|
|
||||||
def test_rate_of_change_conversion_negative_gauge_delta(self):
|
def test_rate_of_change_conversion_negative_gauge_delta(self):
|
||||||
self._do_test_rate_of_change_conversion(180000000000,
|
self._do_test_rate_of_change_conversion(180000000000,
|
||||||
120000000000,
|
120000000000,
|
||||||
1,
|
|
||||||
counter.TYPE_GAUGE,
|
counter.TYPE_GAUGE,
|
||||||
-25.0)
|
-25.0)
|
||||||
|
|
||||||
def test_rate_of_change_conversion_zero_delay(self):
|
def test_rate_of_change_conversion_zero_delay(self):
|
||||||
self._do_test_rate_of_change_conversion(120000000000,
|
self._do_test_rate_of_change_conversion(120000000000,
|
||||||
120000000000,
|
120000000000,
|
||||||
0,
|
|
||||||
counter.TYPE_CUMULATIVE,
|
counter.TYPE_CUMULATIVE,
|
||||||
0.0)
|
0.0,
|
||||||
|
offset=0)
|
||||||
|
|
||||||
def _do_test_rate_of_change_no_predecessor(self, replace):
|
def _do_test_rate_of_change_no_predecessor(self, replace):
|
||||||
s = "100.0 / (10**9 * resource_metadata.get('cpu_number', 1))"
|
s = "100.0 / (10**9 * resource_metadata.get('cpu_number', 1))"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user