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
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
from collections import defaultdict
|
||||
|
||||
from ceilometer import counter as ceilocounter
|
||||
from ceilometer.openstack.common import log
|
||||
@ -26,6 +26,29 @@ from ceilometer import transformer
|
||||
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):
|
||||
"""Transformer to apply a scaling conversion.
|
||||
"""
|
||||
@ -54,7 +77,8 @@ class ScalingTransformer(transformer.TransformerBase):
|
||||
"""Apply the scaling factor (either a straight multiplicative
|
||||
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)
|
||||
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(core_temp, 'volume'), 96.8)
|
||||
|
||||
def _do_test_rate_of_change_conversion(self, prev, curr, offset,
|
||||
type, expected):
|
||||
s = "100.0 / (10**9 * resource_metadata.get('cpu_number', 1))"
|
||||
def _do_test_rate_of_change_conversion(self, prev, curr, type, expected,
|
||||
offset=1, weight=None):
|
||||
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'] = [
|
||||
{
|
||||
'name': 'rate_of_change',
|
||||
@ -766,6 +768,7 @@ class TestPipeline(base.TestCase):
|
||||
self.pipeline_cfg[0]['counters'] = ['cpu']
|
||||
now = timeutils.utcnow()
|
||||
later = now + datetime.timedelta(minutes=offset)
|
||||
um = {'autoscaling_weight': weight} if weight else {}
|
||||
counters = [
|
||||
counter.Counter(
|
||||
name='cpu',
|
||||
@ -776,7 +779,8 @@ class TestPipeline(base.TestCase):
|
||||
project_id='test_proj',
|
||||
resource_id='test_resource',
|
||||
timestamp=now.isoformat(),
|
||||
resource_metadata={'cpu_number': 4}
|
||||
resource_metadata={'cpu_number': 4,
|
||||
'user_metadata': um},
|
||||
),
|
||||
counter.Counter(
|
||||
name='cpu',
|
||||
@ -787,7 +791,8 @@ class TestPipeline(base.TestCase):
|
||||
project_id='test_proj',
|
||||
resource_id='test_resource',
|
||||
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):
|
||||
self._do_test_rate_of_change_conversion(120000000000,
|
||||
180000000000,
|
||||
1,
|
||||
counter.TYPE_CUMULATIVE,
|
||||
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):
|
||||
self._do_test_rate_of_change_conversion(180000000000,
|
||||
120000000000,
|
||||
1,
|
||||
counter.TYPE_CUMULATIVE,
|
||||
50.0)
|
||||
|
||||
def test_rate_of_change_conversion_negative_gauge_delta(self):
|
||||
self._do_test_rate_of_change_conversion(180000000000,
|
||||
120000000000,
|
||||
1,
|
||||
counter.TYPE_GAUGE,
|
||||
-25.0)
|
||||
|
||||
def test_rate_of_change_conversion_zero_delay(self):
|
||||
self._do_test_rate_of_change_conversion(120000000000,
|
||||
120000000000,
|
||||
0,
|
||||
counter.TYPE_CUMULATIVE,
|
||||
0.0)
|
||||
0.0,
|
||||
offset=0)
|
||||
|
||||
def _do_test_rate_of_change_no_predecessor(self, replace):
|
||||
s = "100.0 / (10**9 * resource_metadata.get('cpu_number', 1))"
|
||||
|
Loading…
x
Reference in New Issue
Block a user